Implement multiple saves import

https://bugs.dolphin-emu.org/issues/12887
This commit is contained in:
Joshua Vandaële 2025-01-16 10:29:35 +01:00
parent c344514ba2
commit 42fb43dacf
No known key found for this signature in database
GPG key ID: 5E8F4E7EDBD390EA
4 changed files with 115 additions and 14 deletions

View file

@ -9,6 +9,7 @@
#include <QAction>
#include <QActionGroup>
#include <QDesktopServices>
#include <QDirIterator>
#include <QFileDialog>
#include <QFontDialog>
#include <QInputDialog>
@ -334,6 +335,8 @@ void MenuBar::AddToolsMenu()
m_import_wii_save =
tools_menu->addAction(tr("Import Wii Save..."), this, &MenuBar::ImportWiiSave);
m_import_wii_saves =
tools_menu->addAction(tr("Import Wii Saves..."), this, &MenuBar::ImportWiiSaves);
m_export_wii_saves =
tools_menu->addAction(tr("Export All Wii Saves"), this, &MenuBar::ExportWiiSaves);
@ -1085,6 +1088,7 @@ void MenuBar::UpdateToolsMenu(const Core::State state)
m_import_backup->setEnabled(is_uninitialized);
m_check_nand->setEnabled(is_uninitialized);
m_import_wii_save->setEnabled(is_uninitialized);
m_import_wii_saves->setEnabled(is_uninitialized);
m_export_wii_saves->setEnabled(is_uninitialized);
if (is_uninitialized)
@ -1156,7 +1160,8 @@ void MenuBar::ImportWiiSave()
return ModalMessageBox::question(
this, tr("Save Import"),
tr("Save data for this title already exists in the NAND. Consider backing up "
"the current data before overwriting.\nOverwrite now?")) == QMessageBox::Yes;
"the current data before overwriting.\n\nOverwrite existing save data?")) ==
QMessageBox::Yes;
};
const auto result = WiiSave::Import(file.toStdString(), can_overwrite);
@ -1187,6 +1192,95 @@ void MenuBar::ImportWiiSave()
}
}
void MenuBar::ImportWiiSaves()
{
QString folder =
DolphinFileDialog::getExistingDirectory(this, tr("Select Save Folder"), QDir::currentPath());
if (folder.isEmpty())
return;
QDirIterator it(folder, QStringList(QStringLiteral("*.bin")), QDir::Files,
QDirIterator::Subdirectories);
QStringList failure_details;
size_t success_count = 0;
size_t fail_count = 0;
bool yes_all = false;
bool no_all = false;
while (it.hasNext())
{
const QString file = it.next();
auto can_overwrite = [&] {
if (yes_all)
return true;
if (no_all)
return false;
auto response = ModalMessageBox::question(
this, tr("Save Import"),
tr("%1: Save data for this title already exists in the NAND. Consider backing up "
"the current data before overwriting.\n\nOverwrite existing save data?")
.arg(file),
QMessageBox::StandardButton::YesAll | QMessageBox::StandardButton::Yes |
QMessageBox::StandardButton::No | QMessageBox::StandardButton::NoAll);
if (response == QMessageBox::YesAll)
{
yes_all = true;
return true;
}
else if (response == QMessageBox::NoAll)
{
no_all = true;
return false;
}
return response == QMessageBox::Yes;
};
const auto result = WiiSave::Import(file.toStdString(), can_overwrite);
switch (result)
{
case WiiSave::CopyResult::Success:
success_count++;
break;
case WiiSave::CopyResult::CorruptedSource:
fail_count++;
failure_details.append(tr("%1: Failed to import save file. The given file appears to be "
"corrupted or is not a valid Wii save.")
.arg(file));
break;
case WiiSave::CopyResult::TitleMissing:
fail_count++;
failure_details.append(
tr("%1: Failed to import save file. Please launch the game once, then try again.")
.arg(file));
break;
case WiiSave::CopyResult::Cancelled:
break;
default:
fail_count++;
failure_details.append(
tr("%1: Failed to import save file. Your NAND may be corrupt, or something is preventing "
"access to files within it. Try repairing your NAND (Tools -> Manage NAND -> Check "
"NAND...), then import the save again.")
.arg(file));
break;
}
}
if (success_count == 0 && fail_count == 0)
return;
ModalMessageBox::information(this, tr("Save Import"),
tr("Successfully imported %1 save file(s) with %2 failure(s)")
.arg(success_count)
.arg(fail_count),
QMessageBox::Ok, QMessageBox::NoButton, Qt::WindowModal,
failure_details.join(QStringLiteral("\n\n")));
}
void MenuBar::ExportWiiSaves()
{
const QString export_dir = DolphinFileDialog::getExistingDirectory(

View file

@ -153,6 +153,7 @@ private:
void InstallWAD();
void ImportWiiSave();
void ImportWiiSaves();
void ExportWiiSaves();
void CheckNAND();
void NANDExtractCertificates();
@ -214,6 +215,7 @@ private:
QAction* m_extract_certificates;
std::array<QAction*, 5> m_wii_remotes;
QAction* m_import_wii_save;
QAction* m_import_wii_saves;
QAction* m_export_wii_saves;
// Emulation

View file

@ -21,7 +21,7 @@ ModalMessageBox::ModalMessageBox(QWidget* parent, Qt::WindowModality modality)
static inline int ExecMessageBox(ModalMessageBox::Icon icon, QWidget* parent, const QString& title,
const QString& text, ModalMessageBox::StandardButtons buttons,
ModalMessageBox::StandardButton default_button,
Qt::WindowModality modality)
Qt::WindowModality modality, QString detailed_text)
{
ModalMessageBox msg(parent, modality);
msg.setIcon(icon);
@ -29,6 +29,7 @@ static inline int ExecMessageBox(ModalMessageBox::Icon icon, QWidget* parent, co
msg.setText(text);
msg.setStandardButtons(buttons);
msg.setDefaultButton(default_button);
msg.setDetailedText(detailed_text);
SetQWidgetWindowDecorations(&msg);
return msg.exec();
@ -36,32 +37,32 @@ static inline int ExecMessageBox(ModalMessageBox::Icon icon, QWidget* parent, co
int ModalMessageBox::critical(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons, StandardButton default_button,
Qt::WindowModality modality)
Qt::WindowModality modality, const QString& detailedText)
{
return ExecMessageBox(QMessageBox::Critical, parent, title, text, buttons, default_button,
modality);
modality, detailedText);
}
int ModalMessageBox::information(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons, StandardButton default_button,
Qt::WindowModality modality)
Qt::WindowModality modality, const QString& detailedText)
{
return ExecMessageBox(QMessageBox::Information, parent, title, text, buttons, default_button,
modality);
modality, detailedText);
}
int ModalMessageBox::question(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons, StandardButton default_button,
Qt::WindowModality modality)
Qt::WindowModality modality, const QString& detailedText)
{
return ExecMessageBox(QMessageBox::Warning, parent, title, text, buttons, default_button,
modality);
modality, detailedText);
}
int ModalMessageBox::warning(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons, StandardButton default_button,
Qt::WindowModality modality)
Qt::WindowModality modality, const QString& detailedText)
{
return ExecMessageBox(QMessageBox::Warning, parent, title, text, buttons, default_button,
modality);
modality, detailedText);
}

View file

@ -13,14 +13,18 @@ public:
static int critical(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons = Ok, StandardButton default_button = NoButton,
Qt::WindowModality modality = Qt::WindowModal);
Qt::WindowModality modality = Qt::WindowModal,
const QString& detailed_text = QString());
static int information(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons = Ok, StandardButton default_button = NoButton,
Qt::WindowModality modality = Qt::WindowModal);
Qt::WindowModality modality = Qt::WindowModal,
const QString& detailedText = QString());
static int question(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons = Yes | No, StandardButton default_button = NoButton,
Qt::WindowModality modality = Qt::WindowModal);
Qt::WindowModality modality = Qt::WindowModal,
const QString& detailedText = QString());
static int warning(QWidget* parent, const QString& title, const QString& text,
StandardButtons buttons = Ok, StandardButton default_button = NoButton,
Qt::WindowModality modality = Qt::WindowModal);
Qt::WindowModality modality = Qt::WindowModal,
const QString& detailedText = QString());
};