mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 17:28:36 +12:00
Basic Save Manager (#2924)
* The basic unstubbing. Save entries will be listed and you can select a save. If you select none, then it'll work as well. WIP * Filled out the trivial parts of the info dialog. * Finish implementation and clean up. No "maintain" dialog or context menu for now until the copy/delete functions are implemented. * Fix crash * Update cellSaveData.cpp
This commit is contained in:
parent
253e7a90b8
commit
190a59ce03
7 changed files with 180 additions and 266 deletions
|
@ -293,12 +293,25 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display Save Data List
|
// Display Save Data List but do so asynchronously in the GUI thread. For, qTimers only work using main UI thread.
|
||||||
selected = Emu.GetCallbacks().get_save_dialog()->ShowSaveDataList(save_entries, focused, listSet);
|
atomic_t<bool> 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 (selected == -1)
|
||||||
{
|
{
|
||||||
if (listSet->newData)
|
if (hasNewData)
|
||||||
{
|
{
|
||||||
save_entry.dirName = listSet->newData->dirName.get_ptr();
|
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; // ???
|
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))
|
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||||
{
|
{
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
|
|
@ -292,5 +292,5 @@ class SaveDialogBase
|
||||||
public:
|
public:
|
||||||
virtual ~SaveDialogBase();
|
virtual ~SaveDialogBase();
|
||||||
|
|
||||||
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, vm::ptr<CellSaveDataListSet> listSet) = 0;
|
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1164,7 +1164,7 @@ void main_window::CreateConnects()
|
||||||
gameListFrame->Refresh(true); // dev-hdd0 may have changed. Refresh just in case.
|
gameListFrame->Refresh(true); // dev-hdd0 may have changed. Refresh just in case.
|
||||||
});
|
});
|
||||||
connect(confSavedataManagerAct, &QAction::triggered, [=](){
|
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();
|
sdid->show();
|
||||||
});
|
});
|
||||||
connect(toolsCgDisasmAct, &QAction::triggered, [=](){
|
connect(toolsCgDisasmAct, &QAction::triggered, [=](){
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
|
|
||||||
#include "save_data_dialog.h"
|
#include "save_data_dialog.h"
|
||||||
|
#include "save_data_utility.h"
|
||||||
|
|
||||||
s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, vm::ptr<CellSaveDataListSet> listSet)
|
s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet)
|
||||||
{
|
{
|
||||||
return focused;
|
save_data_list_dialog sdid(save_entries, focused, isSaving);
|
||||||
|
sdid.exec();
|
||||||
|
return sdid.GetSelection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
class save_data_dialog : public SaveDialogBase
|
class save_data_dialog : public SaveDialogBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, vm::ptr<CellSaveDataListSet> listSet) override;
|
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, bool isSaving, vm::ptr<CellSaveDataListSet> listSet) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "save_data_utility.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.
|
//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.
|
//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)
|
save_data_info_dialog::save_data_info_dialog(const SaveDataEntry& save, QWidget* parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent), m_entry(save)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Save Data Information"));
|
setWindowTitle(tr("Save Data Information"));
|
||||||
setMinimumSize(QSize(400, 300));
|
setMinimumSize(QSize(400, 300));
|
||||||
|
@ -12,7 +14,7 @@ save_data_info_dialog::save_data_info_dialog(QWidget* parent, const save_data_in
|
||||||
// Table
|
// Table
|
||||||
m_list = new QTableWidget(this);
|
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->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->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
m_list->setColumnCount(2);
|
m_list->setColumnCount(2);
|
||||||
m_list->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Detail"));
|
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();
|
UpdateData();
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is intended to write the information of save data to QTableView.
|
//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()
|
void save_data_info_dialog::UpdateData()
|
||||||
{
|
{
|
||||||
m_list->clearContents();
|
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, 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, 0, new QTableWidgetItem(tr("Title")));
|
||||||
m_list->setItem(1, 1, new QTableWidgetItem("Happy with rpcs3 (free)"));
|
m_list->setItem(1, 1, new QTableWidgetItem(qstr(m_entry.title)));
|
||||||
|
|
||||||
m_list->setItem(2, 0, new QTableWidgetItem(tr("Subtitle")));
|
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, 0, new QTableWidgetItem(tr("Detail")));
|
||||||
m_list->setItem(3, 1, new QTableWidgetItem("Stub it first"));
|
m_list->setItem(3, 1, new QTableWidgetItem(qstr(m_entry.details)));
|
||||||
|
|
||||||
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->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
m_list->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
}
|
m_list->verticalHeader()->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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Show up the savedata list, either to choose one to save/load or to manage saves.
|
//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)
|
//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)
|
save_data_list_dialog::save_data_list_dialog(const std::vector<SaveDataEntry>& entries, s32 focusedEntry, bool is_saving, QWidget* parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent), m_save_entries(entries), m_selectedEntry(-1), selectedEntryLabel(nullptr)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Save Data Utility"));
|
setWindowTitle(tr("Save Data Utility"));
|
||||||
setMinimumSize(QSize(400, 400));
|
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
|
// Table
|
||||||
m_list = new QTableWidget(this);
|
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->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->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
m_list->setContextMenuPolicy(Qt::CustomContextMenu);
|
m_list->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
m_list->setColumnCount(3);
|
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
|
// Button Layout
|
||||||
QHBoxLayout* hbox_action = new QHBoxLayout();
|
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.
|
selectedEntryLabel = new QLabel(this);
|
||||||
if (!enable_manage)
|
UpdateSelectionLabel();
|
||||||
|
|
||||||
|
if (is_saving)
|
||||||
{
|
{
|
||||||
QPushButton *m_select = new QPushButton(tr("&Select"), this);
|
QPushButton *saveNewEntry = new QPushButton(tr("Save New Entry"), this);
|
||||||
connect(m_select, &QAbstractButton::clicked, this, &save_data_list_dialog::OnSelect);
|
connect(saveNewEntry, &QAbstractButton::clicked, this, [&]() {
|
||||||
hbox_action->addWidget(m_select);
|
m_selectedEntry = -1; // Set the return properly.
|
||||||
setWindowTitle(tr("Save Data Chooser"));
|
accept();
|
||||||
}
|
});
|
||||||
else {
|
hbox_action->addWidget(saveNewEntry);
|
||||||
QPushButton *m_manage = new QPushButton(tr("&Manage"), this);
|
|
||||||
connect(m_manage, &QAbstractButton::clicked, this, &save_data_list_dialog::OnManage);
|
|
||||||
hbox_action->addWidget(m_manage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hbox_action->addStretch();
|
hbox_action->addStretch();
|
||||||
hbox_action->addWidget(m_close);
|
hbox_action->addWidget(push_cancel);
|
||||||
|
|
||||||
// events
|
// events
|
||||||
connect(m_close, &QAbstractButton::clicked, this, &save_data_list_dialog::close);
|
connect(push_cancel, &QAbstractButton::clicked, this, &save_data_list_dialog::close);
|
||||||
connect(m_list, &QTableWidget::itemClicked, this, &save_data_list_dialog::OnEntryInfo);
|
connect(m_list, &QTableWidget::itemDoubleClicked, this, &save_data_list_dialog::OnEntryInfo);
|
||||||
connect(m_list, &QTableWidget::customContextMenuRequested, this, &save_data_list_dialog::ShowContextMenu);
|
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){
|
connect(m_list->horizontalHeader(), &QHeaderView::sectionClicked, [=](int col){
|
||||||
// Sort entries, update columns and refresh the panel. Taken from game_list_frame
|
OnSort(col);
|
||||||
m_sortColumn = col;
|
|
||||||
OnSort(m_sortColumn);
|
|
||||||
UpdateList();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// main layout
|
// main layout
|
||||||
QVBoxLayout* vbox_main = new QVBoxLayout();
|
QVBoxLayout* vbox_main = new QVBoxLayout();
|
||||||
vbox_main->setAlignment(Qt::AlignCenter);
|
vbox_main->setAlignment(Qt::AlignCenter);
|
||||||
vbox_main->addWidget(l_description);
|
|
||||||
vbox_main->addWidget(m_list);
|
vbox_main->addWidget(m_list);
|
||||||
|
if (selectedEntryLabel != nullptr)
|
||||||
|
{
|
||||||
|
vbox_main->addWidget(selectedEntryLabel);
|
||||||
|
}
|
||||||
vbox_main->addLayout(hbox_action);
|
vbox_main->addLayout(hbox_action);
|
||||||
setLayout(vbox_main);
|
setLayout(vbox_main);
|
||||||
|
|
||||||
LoadEntries();
|
LoadEntries();
|
||||||
UpdateList();
|
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))
|
if ((idx < m_sort_type_count) && (idx >= 0))
|
||||||
{
|
{
|
||||||
m_sort_type = idx;
|
if (idx == m_sortColumn)
|
||||||
|
|
||||||
if (m_sort_type == m_sortColumn)
|
|
||||||
{
|
{
|
||||||
m_sortAscending ^= true;
|
m_sortAscending ^= true;
|
||||||
}
|
}
|
||||||
|
@ -247,10 +181,12 @@ void save_data_list_dialog::OnSort(int id)
|
||||||
{
|
{
|
||||||
m_sortAscending = true;
|
m_sortAscending = true;
|
||||||
}
|
}
|
||||||
// someSort(m_sort_type, m_sortAscending)
|
Qt::SortOrder colSortOrder = m_sortAscending ? Qt::AscendingOrder : Qt::DescendingOrder;
|
||||||
// look at game_list_frame sortGameData for reference
|
m_list->sortByColumn(m_sortColumn, colSortOrder);
|
||||||
|
m_sortColumn = idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Copy a existing save, need to get more arguments. maybe a new dialog.
|
//Copy a existing save, need to get more arguments. maybe a new dialog.
|
||||||
void save_data_list_dialog::OnEntryCopy()
|
void save_data_list_dialog::OnEntryCopy()
|
||||||
{
|
{
|
||||||
|
@ -262,6 +198,7 @@ void save_data_list_dialog::OnEntryCopy()
|
||||||
UpdateList();
|
UpdateList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove a save file, need to be confirmed.
|
//Remove a save file, need to be confirmed.
|
||||||
void save_data_list_dialog::OnEntryRemove()
|
void save_data_list_dialog::OnEntryRemove()
|
||||||
{
|
{
|
||||||
|
@ -273,42 +210,19 @@ void save_data_list_dialog::OnEntryRemove()
|
||||||
UpdateList();
|
UpdateList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Display info dialog directly.
|
//Display info dialog directly.
|
||||||
void save_data_list_dialog::OnEntryInfo()
|
void save_data_list_dialog::OnEntryInfo()
|
||||||
{
|
{
|
||||||
int idx = m_list->currentRow();
|
int idx = m_list->currentRow();
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
{
|
{
|
||||||
LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnEntryInfo called.");
|
save_data_info_dialog* infoDialog = new save_data_info_dialog(m_save_entries[idx], this);
|
||||||
save_data_information info; //Only a stub now.
|
|
||||||
save_data_info_dialog* infoDialog = new save_data_info_dialog(this, info);
|
|
||||||
infoDialog->setModal(true);
|
infoDialog->setModal(true);
|
||||||
infoDialog->show();
|
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
|
//Pop-up a small context-menu, being a replacement for save_data_manage_dialog
|
||||||
void save_data_list_dialog::ShowContextMenu(const QPoint &pos)
|
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();
|
QMenu* menu = new QMenu();
|
||||||
int idx = m_list->currentRow();
|
int idx = m_list->currentRow();
|
||||||
|
|
||||||
userIDAct = new QAction(tr("UserID"), this);
|
saveIDAct = new QAction(tr("SaveID"), this);
|
||||||
titleAct = new QAction(tr("Title"), this);
|
titleAct = new QAction(tr("Title"), this);
|
||||||
subtitleAct = new QAction(tr("Subtitle"), this);
|
subtitleAct = new QAction(tr("Subtitle"), this);
|
||||||
copyAct = new QAction(tr("&Copy"), 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.
|
//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 = new QMenu(tr("&Sort"));
|
||||||
m_sort_options->addAction(userIDAct);
|
|
||||||
m_sort_options->addAction(titleAct);
|
m_sort_options->addAction(titleAct);
|
||||||
m_sort_options->addAction(subtitleAct);
|
m_sort_options->addAction(subtitleAct);
|
||||||
m_sort_type_count = 3; // set this !!!
|
m_sort_options->addAction(saveIDAct);
|
||||||
|
|
||||||
menu->addMenu(m_sort_options);
|
menu->addMenu(m_sort_options);
|
||||||
menu->addSeparator();
|
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(removeAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryRemove);
|
||||||
connect(infoAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryInfo);
|
connect(infoAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryInfo);
|
||||||
|
|
||||||
connect(userIDAct, &QAction::triggered, this, [=] {OnSort(0); });
|
connect(titleAct, &QAction::triggered, this, [=] {OnSort(0); });
|
||||||
connect(titleAct, &QAction::triggered, this, [=] {OnSort(1); });
|
connect(subtitleAct, &QAction::triggered, this, [=] {OnSort(1); });
|
||||||
connect(subtitleAct, &QAction::triggered, this, [=] {OnSort(2); });
|
connect(saveIDAct, &QAction::triggered, this, [=] {OnSort(2); });
|
||||||
|
|
||||||
menu->exec(globalPos);
|
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.
|
//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)
|
void save_data_list_dialog::LoadEntries(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
//Setup some static items just for display.
|
|
||||||
void save_data_list_dialog::UpdateList(void)
|
void save_data_list_dialog::UpdateList(void)
|
||||||
{
|
{
|
||||||
m_list->clearContents();
|
m_list->clearContents();
|
||||||
m_list->setRowCount(2); // set this to number of entries
|
m_list->setRowCount(m_save_entries.size());
|
||||||
|
|
||||||
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->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
#pragma once
|
#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 <QDialog>
|
#include <QDialog>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
@ -9,55 +14,19 @@
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
//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.
|
//Used to display the information of a savedata.
|
||||||
//Not sure about what information should be displayed.
|
//Not sure about what information should be displayed.
|
||||||
class save_data_info_dialog :public QDialog
|
class save_data_info_dialog :public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
QTableWidget* m_list;
|
public:
|
||||||
|
explicit save_data_info_dialog(const SaveDataEntry& save, QWidget* parent = nullptr);
|
||||||
|
private:
|
||||||
void UpdateData();
|
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
|
SaveDataEntry m_entry;
|
||||||
//Like what you get when press Triangle on SaveData.
|
QTableWidget* m_list;
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Display a list of SaveData. Would need to be initialized.
|
//Display a list of SaveData. Would need to be initialized.
|
||||||
|
@ -66,32 +35,37 @@ class save_data_list_dialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
QTableWidget* m_list;
|
public:
|
||||||
QMenu* m_sort_options;
|
explicit save_data_list_dialog(const std::vector<SaveDataEntry>& entries, s32 focusedEntry, bool is_saving, QWidget* parent = nullptr);
|
||||||
unsigned int m_sort_type;
|
|
||||||
unsigned int m_sort_type_count;
|
|
||||||
|
|
||||||
|
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<SaveDataEntry> m_save_entries;
|
||||||
|
|
||||||
|
QMenu* m_sort_options;
|
||||||
|
|
||||||
|
const int m_sort_type_count = 3;
|
||||||
int m_sortColumn;
|
int m_sortColumn;
|
||||||
bool m_sortAscending;
|
bool m_sortAscending;
|
||||||
|
|
||||||
void LoadEntries(void);
|
QAction* saveIDAct;
|
||||||
void UpdateList(void);
|
|
||||||
public:
|
|
||||||
save_data_list_dialog(QWidget* parent, bool enable_manage);
|
|
||||||
private:
|
|
||||||
QAction* userIDAct;
|
|
||||||
QAction* titleAct;
|
QAction* titleAct;
|
||||||
QAction* subtitleAct;
|
QAction* subtitleAct;
|
||||||
QAction* copyAct;
|
QAction* copyAct;
|
||||||
QAction* removeAct;
|
QAction* removeAct;
|
||||||
QAction* infoAct;
|
QAction* infoAct;
|
||||||
|
|
||||||
void OnSort(int id);
|
|
||||||
private Q_SLOTS:
|
|
||||||
void OnSelect();
|
|
||||||
void OnManage();
|
|
||||||
void OnEntryCopy();
|
|
||||||
void OnEntryRemove();
|
|
||||||
void OnEntryInfo();
|
|
||||||
void ShowContextMenu(const QPoint &pos);
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue