rpcsx/rpcs3/rpcs3qt/save_data_utility.cpp

297 lines
9.7 KiB
C++

#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(const SaveDataEntry& save, QWidget* parent)
: QDialog(parent), m_entry(save)
{
setWindowTitle(tr("Save Data Information"));
setMinimumSize(QSize(400, 300));
// 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->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_list->setColumnCount(2);
m_list->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Detail"));
// Buttons
QPushButton* close_button = new QPushButton(tr("&Close"), this);
connect(close_button, &QAbstractButton::clicked, this, &save_data_info_dialog::close);
// Button Layout
QHBoxLayout* hbox_actions = new QHBoxLayout();
hbox_actions->addStretch(); //Add a stretch to make Close on the Right-Down corner of this dialog.
hbox_actions->addWidget(close_button);
// Main Layout
QVBoxLayout* vbox_main = new QVBoxLayout();
vbox_main->addWidget(m_list, 1);
vbox_main->addLayout(hbox_actions, 0);
vbox_main->setAlignment(Qt::AlignCenter);
setLayout(vbox_main);
// resize to minimum view size
resize(minimumSize().expandedTo(sizeHint()));
UpdateData();
}
//This is intended to write the information of save data to QTableView.
void save_data_info_dialog::UpdateData()
{
m_list->clearContents();
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("00000001 (Default)"));
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(qstr(m_entry.subtitle)));
m_list->setItem(3, 0, new QTableWidgetItem(tr("Detail")));
m_list->setItem(3, 1, new QTableWidgetItem(qstr(m_entry.details)));
m_list->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
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(const std::vector<SaveDataEntry>& 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));
// 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->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("Title") << tr("Subtitle") << tr("Save ID"));
// Button Layout
QHBoxLayout* hbox_action = new QHBoxLayout();
QPushButton *push_cancel = new QPushButton(tr("&Cancel"), this);
push_cancel->setAutoDefault(false);
QPushButton *push_select = new QPushButton(tr("&Select Entry"), this);
push_select->setAutoDefault(true);
push_select->setDefault(true);
connect(push_select, &QAbstractButton::clicked, this, &save_data_list_dialog::accept);
hbox_action->addWidget(push_select);
setWindowTitle(tr("Save Data Chooser"));
selectedEntryLabel = new QLabel(this);
UpdateSelectionLabel();
if (is_saving)
{
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(push_cancel);
// events
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){
OnSort(col);
});
// main layout
QVBoxLayout* vbox_main = new QVBoxLayout();
vbox_main->setAlignment(Qt::AlignCenter);
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);
}
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)
{
if ((idx < m_sort_type_count) && (idx >= 0))
{
if (idx == m_sortColumn)
{
m_sortAscending ^= true;
}
else
{
m_sortAscending = true;
}
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()
{
int idx = m_list->currentRow();
if (idx != -1)
{
LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnEntryCopy called.");
//Some Operations?
UpdateList();
}
}
//Remove a save file, need to be confirmed.
void save_data_list_dialog::OnEntryRemove()
{
int idx = m_list->currentRow();
if (idx != -1)
{
LOG_WARNING(HLE, "Stub - save_data_utility: save_data_list_dialog: OnEntryRemove called.");
//Some Operations?
UpdateList();
}
}
//Display info dialog directly.
void save_data_list_dialog::OnEntryInfo()
{
int idx = m_list->currentRow();
if (idx != -1)
{
save_data_info_dialog* infoDialog = new save_data_info_dialog(m_save_entries[idx], this);
infoDialog->setModal(true);
infoDialog->show();
}
}
//Pop-up a small context-menu, being a replacement for save_data_manage_dialog
void save_data_list_dialog::ShowContextMenu(const QPoint &pos)
{
QPoint globalPos = m_list->mapToGlobal(pos);
QMenu* menu = new QMenu();
int idx = m_list->currentRow();
saveIDAct = new QAction(tr("SaveID"), this);
titleAct = new QAction(tr("Title"), this);
subtitleAct = new QAction(tr("Subtitle"), this);
copyAct = new QAction(tr("&Copy"), this);
removeAct = new QAction(tr("&Remove"), this);
infoAct = new QAction(tr("&Info"), this);
//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(titleAct);
m_sort_options->addAction(subtitleAct);
m_sort_options->addAction(saveIDAct);
menu->addMenu(m_sort_options);
menu->addSeparator();
menu->addAction(copyAct);
menu->addAction(removeAct);
menu->addSeparator();
menu->addAction(infoAct);
copyAct->setEnabled(idx != -1);
removeAct->setEnabled(idx != -1);
//Events
connect(copyAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryCopy);
connect(removeAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryRemove);
connect(infoAct, &QAction::triggered, this, &save_data_list_dialog::OnEntryInfo);
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)
{
}
void save_data_list_dialog::UpdateList(void)
{
m_list->clearContents();
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;
}
}