diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index 5975e09198..5e75f755ee 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -293,12 +293,25 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, } } - // Display Save Data List - selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, listSet); + // Display Save Data List but do so asynchronously in the GUI thread. For, qTimers only work using main UI thread. + atomic_t dlg_result(false); + bool hasNewData = (bool) listSet->newData; // Are we saving? + + + Emu.CallAfter([&]() + { + selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, hasNewData, listSet); + dlg_result = true; + }); + + while (!dlg_result) + { + thread_ctrl::wait_for(1000); + } if (selected == -1) { - if (listSet->newData) + if (hasNewData) { save_entry.dirName = listSet->newData->dirName.get_ptr(); } @@ -307,6 +320,12 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, return CELL_OK; // ??? } } + // Cancel selected in UI + else if (selected == -2) + { + return CELL_CANCEL; + } + if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)) { return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.h b/rpcs3/Emu/Cell/Modules/cellSaveData.h index 97162da674..289c1e9dc5 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.h +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.h @@ -292,5 +292,5 @@ class SaveDialogBase public: virtual ~SaveDialogBase(); - virtual s32 ShowSaveDataList(std::vector& save_entries, s32 focused, vm::ptr listSet) = 0; + virtual s32 ShowSaveDataList(std::vector& save_entries, s32 focused, bool isSaving, vm::ptr listSet) = 0; }; diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index a61bc0ecb4..43c88ec764 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -996,7 +996,7 @@ void main_window::CreateActions() confAutopauseManagerAct->setEnabled(false); confVFSDialogAct = new QAction(tr("Virtual File System"), this); - + confSavedataManagerAct = new QAction(tr("Save &Data Utility"), this); confSavedataManagerAct->setEnabled(false); @@ -1164,7 +1164,7 @@ void main_window::CreateConnects() gameListFrame->Refresh(true); // dev-hdd0 may have changed. Refresh just in case. }); connect(confSavedataManagerAct, &QAction::triggered, [=](){ - save_data_list_dialog* sdid = new save_data_list_dialog(this, true); + save_data_list_dialog* sdid = new save_data_list_dialog({}, 0, false, this); sdid->show(); }); connect(toolsCgDisasmAct, &QAction::triggered, [=](){ diff --git a/rpcs3/rpcs3qt/save_data_dialog.cpp b/rpcs3/rpcs3qt/save_data_dialog.cpp index 4571feba45..670488af9d 100644 --- a/rpcs3/rpcs3qt/save_data_dialog.cpp +++ b/rpcs3/rpcs3qt/save_data_dialog.cpp @@ -2,8 +2,11 @@ #include "Emu/Memory/Memory.h" #include "save_data_dialog.h" +#include "save_data_utility.h" -s32 save_data_dialog::ShowSaveDataList(std::vector& save_entries, s32 focused, vm::ptr listSet) +s32 save_data_dialog::ShowSaveDataList(std::vector& save_entries, s32 focused, bool isSaving, vm::ptr listSet) { - return focused; + save_data_list_dialog sdid(save_entries, focused, isSaving); + sdid.exec(); + return sdid.GetSelection(); } diff --git a/rpcs3/rpcs3qt/save_data_dialog.h b/rpcs3/rpcs3qt/save_data_dialog.h index 2822a190b6..9aaad0d937 100644 --- a/rpcs3/rpcs3qt/save_data_dialog.h +++ b/rpcs3/rpcs3qt/save_data_dialog.h @@ -5,5 +5,5 @@ class save_data_dialog : public SaveDialogBase { public: - virtual s32 ShowSaveDataList(std::vector& save_entries, s32 focused, vm::ptr listSet) override; + virtual s32 ShowSaveDataList(std::vector& save_entries, s32 focused, bool isSaving, vm::ptr listSet) override; }; diff --git a/rpcs3/rpcs3qt/save_data_utility.cpp b/rpcs3/rpcs3qt/save_data_utility.cpp index 42351bec9a..d26ce09775 100644 --- a/rpcs3/rpcs3qt/save_data_utility.cpp +++ b/rpcs3/rpcs3qt/save_data_utility.cpp @@ -1,10 +1,12 @@ #include "stdafx.h" #include "save_data_utility.h" +inline QString qstr(const std::string& _in) { return QString::fromUtf8(_in.data(), _in.size()); } + //Cause i can not decide what struct to be used to fill those. Just use no real data now. //Currently variable info isn't used. it supposed to be a container for the information passed by other. -save_data_info_dialog::save_data_info_dialog(QWidget* parent, const save_data_information& info) - : QDialog(parent) +save_data_info_dialog::save_data_info_dialog(const SaveDataEntry& save, QWidget* parent) + : QDialog(parent), m_entry(save) { setWindowTitle(tr("Save Data Information")); setMinimumSize(QSize(400, 300)); @@ -12,7 +14,7 @@ save_data_info_dialog::save_data_info_dialog(QWidget* parent, const save_data_in // Table m_list = new QTableWidget(this); //m_list->setItemDelegate(new table_item_delegate(this)); // to get rid of item selection rectangles include "table_item_delegate.h" - //m_list->setSelectionBehavior(QAbstractItemView::SelectRows); // enable to only select whole rows instead of items + m_list->setSelectionBehavior(QAbstractItemView::SelectRows); // enable to only select whole rows instead of items m_list->setEditTriggers(QAbstractItemView::NoEditTriggers); m_list->setColumnCount(2); m_list->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Detail")); @@ -38,208 +40,140 @@ save_data_info_dialog::save_data_info_dialog(QWidget* parent, const save_data_in UpdateData(); } + //This is intended to write the information of save data to QTableView. -//However been not able to decide which data struct i should use, i use static content for this to make it stub. void save_data_info_dialog::UpdateData() { m_list->clearContents(); - m_list->setRowCount(6); // set this to nr of members in struct + m_list->setRowCount(4); // set this to nr of members in struct + //Maybe there should be more details of save data. m_list->setItem(0, 0, new QTableWidgetItem(tr("User ID"))); - m_list->setItem(0, 1, new QTableWidgetItem("00000000 (None)")); + m_list->setItem(0, 1, new QTableWidgetItem("00000001 (Default)")); - m_list->setItem(1, 0, new QTableWidgetItem(tr("Game Title"))); - m_list->setItem(1, 1, new QTableWidgetItem("Happy with rpcs3 (free)")); + m_list->setItem(1, 0, new QTableWidgetItem(tr("Title"))); + m_list->setItem(1, 1, new QTableWidgetItem(qstr(m_entry.title))); m_list->setItem(2, 0, new QTableWidgetItem(tr("Subtitle"))); - m_list->setItem(2, 1, new QTableWidgetItem("You devs are great")); + m_list->setItem(2, 1, new QTableWidgetItem(qstr(m_entry.subtitle))); m_list->setItem(3, 0, new QTableWidgetItem(tr("Detail"))); - m_list->setItem(3, 1, new QTableWidgetItem("Stub it first")); - - m_list->setItem(4, 0, new QTableWidgetItem(tr("Copyable"))); - m_list->setItem(4, 1, new QTableWidgetItem("1 (Not allowed)")); - - m_list->setItem(5, 0, new QTableWidgetItem(tr("Play Time"))); - m_list->setItem(5, 1, new QTableWidgetItem("00:00:00")); - //Maybe there should be more details of save data. - //But i'm getting bored for assign it one by one. + m_list->setItem(3, 1, new QTableWidgetItem(qstr(m_entry.details))); m_list->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); -} - -//This dialog represents the Menu of Save Data Utility - which pop up after when you roll to a save and press triangle. -//I've ever thought of make it a right-click menu or a show-hide panel of the main dialog. -//Well only when those function calls related get implemented we can tell what this GUI should be, seriously. -save_data_manage_dialog::save_data_manage_dialog(QWidget* parent, unsigned int* sort_type, save_data_entry& save) - : QDialog(parent) -{ - setWindowTitle(tr("Save Data Pop-up Menu")); - setMinimumSize(QSize(400, 110)); - - // "Sort By" ComboBox - m_sort_options = new QComboBox(this); - m_sort_options->setEditable(false); - //You might change this - of corse we should know what to been set - maybe after functions related been implemented. - m_sort_options->addItem(tr("User Id")); - m_sort_options->addItem(tr("Game Title")); - m_sort_options->addItem(tr("Game Subtitle")); - m_sort_options->addItem(tr("Play Time")); - m_sort_options->addItem(tr("Data Size")); - m_sort_options->addItem(tr("Last Modified")); - m_sort_options->addItem(tr("Created Time")); - m_sort_options->addItem(tr("Accessed Time")); - m_sort_options->addItem(tr("Modified Time")); - m_sort_options->addItem(tr("Modify Time")); - - m_sort_type = sort_type; - if (m_sort_type != nullptr) - { - //Check sort type and set it to combo box - if (*m_sort_type >= m_sort_options->count()) - { - *m_sort_type = 0; - } - } - m_sort_options->setCurrentIndex(*m_sort_type); - - // Buttons - QPushButton* pb_sort_action = new QPushButton(tr("&Apply"), this); - QPushButton* pb_copy = new QPushButton(tr("&Copy"), this); - QPushButton* pb_delete = new QPushButton(tr("&Delete"), this); - QPushButton* pb_info = new QPushButton(tr("&Info"), this); - QPushButton* pb_close = new QPushButton(tr("&Close"), this); - - // Sort Layout - QHBoxLayout* hbox_sort = new QHBoxLayout(); - hbox_sort->setAlignment(Qt::AlignCenter); - hbox_sort->addWidget(new QLabel(tr("Sort By"), this)); - hbox_sort->addWidget(m_sort_options); - hbox_sort->addWidget(pb_sort_action); - - // Button Layout - QHBoxLayout* hbox_actions = new QHBoxLayout(); - hbox_actions->setAlignment(Qt::AlignCenter); - hbox_actions->addWidget(pb_copy); - hbox_actions->addWidget(pb_delete); - hbox_actions->addWidget(pb_info); - hbox_actions->addWidget(pb_close); - - // Main Layout - QVBoxLayout* vbox_manage = new QVBoxLayout(); - vbox_manage->setAlignment(Qt::AlignCenter); - vbox_manage->addLayout(hbox_sort); - vbox_manage->addLayout(hbox_actions); - setLayout(vbox_manage); - - // Events - connect(pb_sort_action, &QAbstractButton::clicked, this, &save_data_manage_dialog::OnApplySort); - connect(pb_copy, &QAbstractButton::clicked, this, &save_data_manage_dialog::OnCopy); - connect(pb_delete, &QAbstractButton::clicked, this, &save_data_manage_dialog::OnDelete); - connect(pb_info, &QAbstractButton::clicked, this, &save_data_manage_dialog::OnInfo); - connect(pb_close, &QAbstractButton::clicked, this, &save_data_manage_dialog::close); -} -//Display information about the current selected save data. -//If selected is "New Save Data" or other invalid, this dialog would be initialized with "Info" disabled or not visible. -void save_data_manage_dialog::OnInfo() -{ - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_manage_dialog: OnInfo called."); - save_data_information info; //It should get a real one for information.. finally - save_data_info_dialog* infoDialog = new save_data_info_dialog(this, info); - infoDialog->setModal(true); - infoDialog->show(); -} -//Copy selected save data to another. Might need a dialog but i just leave it as this. Or Modal Dialog. -void save_data_manage_dialog::OnCopy() -{ - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_manage_dialog: OnCopy called."); -} -//Delete selected save data, need confirm. just a stub now. -void save_data_manage_dialog::OnDelete() -{ - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_manage_dialog: OnDelete called."); -} -//This should return the sort setting of the save data list. Also not implemented really. -void save_data_manage_dialog::OnApplySort() -{ - *m_sort_type = m_sort_options->currentIndex(); - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_manage_dialog: OnApplySort called. NAME=%s", - m_sort_options->itemText(m_sort_options->currentIndex()).toStdString().c_str()); + m_list->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); } //Show up the savedata list, either to choose one to save/load or to manage saves. //I suggest to use function callbacks to give save data list or get save data entry. (Not implemented or stubbed) -save_data_list_dialog::save_data_list_dialog(QWidget* parent, bool enable_manage) - : QDialog(parent) +save_data_list_dialog::save_data_list_dialog(const std::vector& entries, s32 focusedEntry, bool is_saving, QWidget* parent) + : QDialog(parent), m_save_entries(entries), m_selectedEntry(-1), selectedEntryLabel(nullptr) { setWindowTitle(tr("Save Data Utility")); setMinimumSize(QSize(400, 400)); - QLabel* l_description = new QLabel(tr("This is only a stub for now. This doesn't work yet due to related functions not being implemented."), this); - l_description->setWordWrap(400); - // Table m_list = new QTableWidget(this); //m_list->setItemDelegate(new table_item_delegate(this)); // to get rid of cell selection rectangles include "table_item_delegate.h" - //m_list->setSelectionBehavior(QAbstractItemView::SelectRows); // enable to only select whole rows instead of items + m_list->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + m_list->setSelectionBehavior(QAbstractItemView::SelectRows); m_list->setEditTriggers(QAbstractItemView::NoEditTriggers); m_list->setContextMenuPolicy(Qt::CustomContextMenu); m_list->setColumnCount(3); - m_list->setHorizontalHeaderLabels(QStringList() << tr("Game ID") << tr("Save ID") << tr("Detail")); + m_list->setHorizontalHeaderLabels(QStringList() << tr("Title") << tr("Subtitle") << tr("Save ID")); // Button Layout QHBoxLayout* hbox_action = new QHBoxLayout(); - QPushButton *m_close = new QPushButton(tr("&Close"), this); + QPushButton *push_cancel = new QPushButton(tr("&Cancel"), this); + QPushButton *push_select = new QPushButton(tr("&Select Entry"), this); + connect(push_select, &QAbstractButton::clicked, this, &save_data_list_dialog::accept); + hbox_action->addWidget(push_select); + setWindowTitle(tr("Save Data Chooser")); - //If do not need manage, hide it, like just a save data picker. - if (!enable_manage) + selectedEntryLabel = new QLabel(this); + UpdateSelectionLabel(); + + if (is_saving) { - QPushButton *m_select = new QPushButton(tr("&Select"), this); - connect(m_select, &QAbstractButton::clicked, this, &save_data_list_dialog::OnSelect); - hbox_action->addWidget(m_select); - setWindowTitle(tr("Save Data Chooser")); - } - else { - QPushButton *m_manage = new QPushButton(tr("&Manage"), this); - connect(m_manage, &QAbstractButton::clicked, this, &save_data_list_dialog::OnManage); - hbox_action->addWidget(m_manage); + QPushButton *saveNewEntry = new QPushButton(tr("Save New Entry"), this); + connect(saveNewEntry, &QAbstractButton::clicked, this, [&]() { + m_selectedEntry = -1; // Set the return properly. + accept(); + }); + hbox_action->addWidget(saveNewEntry); } hbox_action->addStretch(); - hbox_action->addWidget(m_close); + hbox_action->addWidget(push_cancel); // events - connect(m_close, &QAbstractButton::clicked, this, &save_data_list_dialog::close); - connect(m_list, &QTableWidget::itemClicked, this, &save_data_list_dialog::OnEntryInfo); - connect(m_list, &QTableWidget::customContextMenuRequested, this, &save_data_list_dialog::ShowContextMenu); + connect(push_cancel, &QAbstractButton::clicked, this, &save_data_list_dialog::close); + connect(m_list, &QTableWidget::itemDoubleClicked, this, &save_data_list_dialog::OnEntryInfo); + connect(m_list, &QTableWidget::currentCellChanged, this, [&](int cr, int cc, int pr, int pc) { + m_selectedEntry = cr; + UpdateSelectionLabel(); + }); + + // TODO: Unstub functions inside of this context menu so it makes sense to show this menu + //connect(m_list, &QTableWidget::customContextMenuRequested, this, &save_data_list_dialog::ShowContextMenu); connect(m_list->horizontalHeader(), &QHeaderView::sectionClicked, [=](int col){ - // Sort entries, update columns and refresh the panel. Taken from game_list_frame - m_sortColumn = col; - OnSort(m_sortColumn); - UpdateList(); + OnSort(col); }); // main layout QVBoxLayout* vbox_main = new QVBoxLayout(); vbox_main->setAlignment(Qt::AlignCenter); - vbox_main->addWidget(l_description); vbox_main->addWidget(m_list); + if (selectedEntryLabel != nullptr) + { + vbox_main->addWidget(selectedEntryLabel); + } vbox_main->addLayout(hbox_action); setLayout(vbox_main); LoadEntries(); UpdateList(); + + m_list->setCurrentCell(focusedEntry, 0); } -//After you pick a menu item from the sort sub-menu -void save_data_list_dialog::OnSort(int id) + +void save_data_list_dialog::UpdateSelectionLabel() +{ + if (selectedEntryLabel != nullptr) + { + if (m_list->currentRow() == -1) + { + selectedEntryLabel->setText(tr("Currently Selected: None")); + } + else + { + int entry = m_list->item(m_list->currentRow(), 0)->data(Qt::UserRole).toInt(); + selectedEntryLabel->setText(tr("Currently Selected: ") + qstr(m_save_entries[entry].dirName)); + } + } +} + +s32 save_data_list_dialog::GetSelection() +{ + int res = result(); + if (res == QDialog::Accepted) + { + if (m_selectedEntry == -1) + { // Save new entry + return -1; + } + return m_list->item(m_selectedEntry, 0)->data(Qt::UserRole).toInt(); + } + + // Cancel is pressed. May promote to enum or figure out proper cellsavedata code to use later. + return -2; +} + +void save_data_list_dialog::OnSort(int idx) { - int idx = id; - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnSort called. Type Value:%d", idx); if ((idx < m_sort_type_count) && (idx >= 0)) { - m_sort_type = idx; - - if (m_sort_type == m_sortColumn) + if (idx == m_sortColumn) { m_sortAscending ^= true; } @@ -247,10 +181,12 @@ void save_data_list_dialog::OnSort(int id) { m_sortAscending = true; } - // someSort(m_sort_type, m_sortAscending) - // look at game_list_frame sortGameData for reference + Qt::SortOrder colSortOrder = m_sortAscending ? Qt::AscendingOrder : Qt::DescendingOrder; + m_list->sortByColumn(m_sortColumn, colSortOrder); + m_sortColumn = idx; } } + //Copy a existing save, need to get more arguments. maybe a new dialog. void save_data_list_dialog::OnEntryCopy() { @@ -262,6 +198,7 @@ void save_data_list_dialog::OnEntryCopy() UpdateList(); } } + //Remove a save file, need to be confirmed. void save_data_list_dialog::OnEntryRemove() { @@ -273,42 +210,19 @@ void save_data_list_dialog::OnEntryRemove() UpdateList(); } } + //Display info dialog directly. void save_data_list_dialog::OnEntryInfo() { int idx = m_list->currentRow(); if (idx != -1) { - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnEntryInfo called."); - save_data_information info; //Only a stub now. - save_data_info_dialog* infoDialog = new save_data_info_dialog(this, info); + save_data_info_dialog* infoDialog = new save_data_info_dialog(m_save_entries[idx], this); infoDialog->setModal(true); infoDialog->show(); } } -//Display info dialog directly. -void save_data_list_dialog::OnManage() -{ - int idx = m_list->currentRow(); - if (idx != -1) - { - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnManage called."); - save_data_entry save; //Only a stub now. - save_data_manage_dialog* manageDialog = new save_data_manage_dialog(this, &m_sort_type, save); - manageDialog->setModal(true); - manageDialog->show(); - } -} -//When you press that select button in the Chooser mode. -void save_data_list_dialog::OnSelect() -{ - int idx = m_list->currentRow(); - if (idx != -1) - { - LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnSelect called."); - setModal(false); - } -} + //Pop-up a small context-menu, being a replacement for save_data_manage_dialog void save_data_list_dialog::ShowContextMenu(const QPoint &pos) { @@ -316,7 +230,7 @@ void save_data_list_dialog::ShowContextMenu(const QPoint &pos) QMenu* menu = new QMenu(); int idx = m_list->currentRow(); - userIDAct = new QAction(tr("UserID"), this); + saveIDAct = new QAction(tr("SaveID"), this); titleAct = new QAction(tr("Title"), this); subtitleAct = new QAction(tr("Subtitle"), this); copyAct = new QAction(tr("&Copy"), this); @@ -325,10 +239,9 @@ void save_data_list_dialog::ShowContextMenu(const QPoint &pos) //This is also a stub for the sort setting. Ids is set according to their sort-type integer. m_sort_options = new QMenu(tr("&Sort")); - m_sort_options->addAction(userIDAct); m_sort_options->addAction(titleAct); m_sort_options->addAction(subtitleAct); - m_sort_type_count = 3; // set this !!! + m_sort_options->addAction(saveIDAct); menu->addMenu(m_sort_options); menu->addSeparator(); @@ -345,30 +258,35 @@ void save_data_list_dialog::ShowContextMenu(const QPoint &pos) connect(removeAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryRemove); connect(infoAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryInfo); - connect(userIDAct, &QAction::triggered, this, [=] {OnSort(0); }); - connect(titleAct, &QAction::triggered, this, [=] {OnSort(1); }); - connect(subtitleAct, &QAction::triggered, this, [=] {OnSort(2); }); + connect(titleAct, &QAction::triggered, this, [=] {OnSort(0); }); + connect(subtitleAct, &QAction::triggered, this, [=] {OnSort(1); }); + connect(saveIDAct, &QAction::triggered, this, [=] {OnSort(2); }); menu->exec(globalPos); } + //This is intended to load the save data list from a way. However that is not certain for a stub. Does nothing now. void save_data_list_dialog::LoadEntries(void) { } -//Setup some static items just for display. + void save_data_list_dialog::UpdateList(void) { m_list->clearContents(); - m_list->setRowCount(2); // set this to number of entries - - m_list->setItem(0, 0, new QTableWidgetItem("TEST00000")); - m_list->setItem(0, 1, new QTableWidgetItem("00")); - m_list->setItem(0, 2, new QTableWidgetItem("Final battle")); - - m_list->setItem(1, 0, new QTableWidgetItem("XXXX99876")); - m_list->setItem(1, 1, new QTableWidgetItem("30")); - m_list->setItem(1, 2, new QTableWidgetItem("This is a fake game")); - + m_list->setRowCount(m_save_entries.size()); m_list->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + m_list->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + int row = 0; + for (SaveDataEntry entry: m_save_entries) + { + QTableWidgetItem* item = new QTableWidgetItem(qstr(entry.title)); + item->setData(Qt::UserRole, row); // For sorting to work properly + m_list->setItem(row, 0, item); + m_list->setItem(row, 1, new QTableWidgetItem(qstr(entry.subtitle))); + m_list->setItem(row, 2, new QTableWidgetItem(qstr(entry.dirName))); + + ++row; + } } diff --git a/rpcs3/rpcs3qt/save_data_utility.h b/rpcs3/rpcs3qt/save_data_utility.h index b05c31bb18..23f2e5b991 100644 --- a/rpcs3/rpcs3qt/save_data_utility.h +++ b/rpcs3/rpcs3qt/save_data_utility.h @@ -1,5 +1,10 @@ #pragma once +// I just want the struct for the save data. +#include "stdafx.h" +#include "Emu/Memory/Memory.h" +#include "Emu/Cell/Modules/cellSaveData.h" + #include #include #include @@ -9,55 +14,19 @@ #include #include -//TODO: Implement function calls related to Save Data List. -//Those function calls may be needed to use this GUI. -//Currently this is only a stub. - -//A stub for the struct sent to save_data_info_dialog. -struct save_data_information -{ - -}; -//A stub for the sorting. -enum -{ - SAVE_DATA_LIST_SORT_BY_USERID -}; -//A stub for a single entry of save data. used to make a save data list or do management. -struct save_data_entry -{ - -}; - //Used to display the information of a savedata. //Not sure about what information should be displayed. class save_data_info_dialog :public QDialog { Q_OBJECT - QTableWidget* m_list; - +public: + explicit save_data_info_dialog(const SaveDataEntry& save, QWidget* parent = nullptr); +private: void UpdateData(); -public: - save_data_info_dialog(QWidget* parent, const save_data_information& info); -}; -//Simple way to show up the sort menu and other operations -//Like what you get when press Triangle on SaveData. -class save_data_manage_dialog :public QDialog -{ - Q_OBJECT - - QComboBox* m_sort_options; - unsigned int* m_sort_type; - -private Q_SLOTS: - void OnInfo(); - void OnCopy(); - void OnDelete(); - void OnApplySort(); -public: - save_data_manage_dialog(QWidget* parent, unsigned int* sort_type, save_data_entry& save); + SaveDataEntry m_entry; + QTableWidget* m_list; }; //Display a list of SaveData. Would need to be initialized. @@ -66,32 +35,37 @@ class save_data_list_dialog : public QDialog { Q_OBJECT - QTableWidget* m_list; - QMenu* m_sort_options; - unsigned int m_sort_type; - unsigned int m_sort_type_count; +public: + explicit save_data_list_dialog(const std::vector& entries, s32 focusedEntry, bool is_saving, QWidget* parent = nullptr); + s32 GetSelection(); +private Q_SLOTS: + void OnEntryCopy(); + void OnEntryRemove(); + void OnEntryInfo(); + void ShowContextMenu(const QPoint &pos); +private: + void UpdateSelectionLabel(void); + void LoadEntries(void); + void UpdateList(void); + void OnSort(int id); + + s32 m_selectedEntry; + QLabel* selectedEntryLabel; + + QTableWidget* m_list; + std::vector m_save_entries; + + QMenu* m_sort_options; + + const int m_sort_type_count = 3; int m_sortColumn; bool m_sortAscending; - void LoadEntries(void); - void UpdateList(void); -public: - save_data_list_dialog(QWidget* parent, bool enable_manage); -private: - QAction* userIDAct; + QAction* saveIDAct; QAction* titleAct; QAction* subtitleAct; QAction* copyAct; QAction* removeAct; QAction* infoAct; - - void OnSort(int id); -private Q_SLOTS: - void OnSelect(); - void OnManage(); - void OnEntryCopy(); - void OnEntryRemove(); - void OnEntryInfo(); - void ShowContextMenu(const QPoint &pos); };