This commit is contained in:
ptyfyre 2026-04-06 13:49:26 +03:00 committed by GitHub
commit 2dc12f4de0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 115 additions and 17 deletions

View File

@ -6,12 +6,17 @@
#include <QFileDialog>
#include <QUrl>
#include "citra_qt/configuration/configure_storage.h"
#include <QMessageBox>
#include <QProgressDialog>
#include "common/file_util.h"
#include "common/settings.h"
#include "ui_configure_storage.h"
ConfigureStorage::ConfigureStorage(bool is_powered_on_, QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()), is_powered_on{is_powered_on_} {
: QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()), is_powered_on{is_powered_on_},
parent{parent} {
ui->setupUi(this);
SetConfiguration();
@ -22,12 +27,15 @@ ConfigureStorage::ConfigureStorage(bool is_powered_on_, QWidget* parent)
connect(ui->change_nand_dir, &QPushButton::clicked, this, [this]() {
ui->change_nand_dir->setEnabled(false);
const QString og_path =
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
const QString dir_path = QFileDialog::getExistingDirectory(
this, tr("Select NAND Directory"),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)),
QFileDialog::ShowDirsOnly);
if (!dir_path.isEmpty()) {
FileUtil::UpdateUserPath(FileUtil::UserPath::NANDDir, dir_path.toStdString());
MigrateFolder(og_path, dir_path);
SetConfiguration();
}
ui->change_nand_dir->setEnabled(true);
@ -40,12 +48,15 @@ ConfigureStorage::ConfigureStorage(bool is_powered_on_, QWidget* parent)
connect(ui->change_sdmc_dir, &QPushButton::clicked, this, [this]() {
ui->change_sdmc_dir->setEnabled(false);
const QString og_path =
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
const QString dir_path = QFileDialog::getExistingDirectory(
this, tr("Select SDMC Directory"),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)),
QFileDialog::ShowDirsOnly);
if (!dir_path.isEmpty()) {
FileUtil::UpdateUserPath(FileUtil::UserPath::SDMCDir, dir_path.toStdString());
MigrateFolder(og_path, dir_path);
SetConfiguration();
}
ui->change_sdmc_dir->setEnabled(true);
@ -95,6 +106,81 @@ void ConfigureStorage::ApplyConfiguration() {
}
}
void ConfigureStorage::MigrateFolder(const QString& from, const QString& dest) {
bool source_exists = FileUtil::Exists(from.toStdString());
bool dest_exists = FileUtil::Exists(dest.toStdString());
bool dest_has_content = false;
bool source_has_content = false;
if (source_exists) {
source_has_content = !FileUtil::IsEmptyDir(from.toStdString());
}
if (dest_exists) {
dest_has_content = !FileUtil::IsEmptyDir(dest.toStdString());
}
if (!source_has_content) {
return;
}
QString message;
if (dest_has_content) {
message = tr("Data exists in both the old and new locations.\n\n"
"Old: %1\n"
"New: %2\n\n"
"Would you like to migrate the data from the old location?\n"
"WARNING: This will overwrite any data in the new location!")
.arg(from)
.arg(dest);
} else {
message = tr("Would you like to migrate your data to the new location?\n\n"
"From: %1\n"
"To: %2")
.arg(from)
.arg(dest);
}
QMessageBox::StandardButton reply =
QMessageBox::question(parent, tr("Migrate Save Data"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (reply != QMessageBox::Yes) {
return;
}
QProgressDialog progress(tr("Migrating save data..."), tr("Cancel"), 0, 0, this);
progress.setWindowModality(Qt::WindowModal);
progress.setMinimumDuration(0);
progress.show();
if (!dest_exists) {
if (!FileUtil::CreateFullPath(dest.toStdString())) {
progress.close();
QMessageBox::warning(this, tr("Migration Failed"),
tr("Failed to create destination directory."));
return;
}
}
FileUtil::CopyDir(from.toStdString() + "/", dest.toStdString() + "/");
progress.close();
QMessageBox::StandardButton deleteReply =
QMessageBox::question(this, tr("Migration Complete"),
tr("Data has been migrated successfully.\n\n"
"Would you like to delete the old data?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (deleteReply == QMessageBox::Yes) {
if (!FileUtil::DeleteDirRecursively(from.toStdString())) {
QMessageBox::warning(this, tr("Deletion Failed"), tr("Failed to delete old data."));
}
}
}
void ConfigureStorage::RetranslateUI() {
ui->retranslateUi(this);
}

View File

@ -1,10 +1,11 @@
// Copyright 2021 Citra Emulator Project
// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <QMainWindow>
#include <QWidget>
namespace Ui {
@ -19,9 +20,13 @@ public:
~ConfigureStorage() override;
void ApplyConfiguration();
void MigrateFolder(const QString& from, const QString& dest);
void RetranslateUI();
void SetConfiguration();
std::unique_ptr<Ui::ConfigureStorage> ui;
bool is_powered_on;
QWidget* parent;
};

View File

@ -79,13 +79,6 @@
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>NOTE: This does not move the contents of the previous directory to the new one.</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
@ -143,14 +136,7 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>NOTE: This does not move the contents of the previous directory to the new one.</string>
</property>
</widget>
</item>
<layout class="QHBoxLayout" name="horizontalLayout_4">>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">

View File

@ -155,6 +155,24 @@ static void StripTailDirSlashes(std::string& fname) {
fname.resize(i);
}
bool IsEmptyDir(const std::string& folder_path) {
if (!IsDirectory(folder_path)) {
return false;
}
bool has_entries = false;
ForeachDirectoryEntry(nullptr, folder_path,
[&has_entries]([[maybe_unused]] u64* num_entries_out,
[[maybe_unused]] const std::string& directory,
[[maybe_unused]] const std::string& virtual_name) -> bool {
has_entries = true;
return false;
});
return !has_entries;
}
bool Exists(const std::string& filename) {
std::string copy(filename);
StripTailDirSlashes(copy);

View File

@ -121,6 +121,9 @@ private:
friend class boost::serialization::access;
};
// Check if a folder is empty
[[nodiscard]] bool IsEmptyDir(const std::string& folder_path);
// Returns true if file filename exists
[[nodiscard]] bool Exists(const std::string& filename);