Browse Source

add profile selector for saves

Signed-off-by: crueter <crueter@eden-emu.dev>
pull/2700/head
crueter 5 months ago
parent
commit
b5e3be1f79
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 8
      src/frontend_common/data_manager.cpp
  2. 4
      src/frontend_common/data_manager.h
  3. 3
      src/qt_common/qt_compress.cpp
  4. 3
      src/qt_common/qt_compress.h
  5. 18
      src/qt_common/qt_content_util.cpp
  6. 6
      src/qt_common/qt_content_util.h
  7. 63
      src/yuzu/data_dialog.cpp
  8. 2
      src/yuzu/data_dialog.h
  9. 2
      src/yuzu/main.cpp

8
src/frontend_common/data_manager.cpp

@ -11,13 +11,13 @@ namespace FrontendCommon::DataManager {
namespace fs = std::filesystem;
const std::string GetDataDir(DataDir dir)
const std::string GetDataDir(DataDir dir, const std::string &user_id)
{
const fs::path nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir);
switch (dir) {
case DataDir::Saves:
return (nand_dir / "user" / "save" / "0000000000000000").string();
return (nand_dir / "user" / "save" / "0000000000000000" / user_id).string();
case DataDir::UserNand:
return (nand_dir / "user" / "Contents" / "registered").string();
case DataDir::SysNand:
@ -35,9 +35,9 @@ const std::string GetDataDir(DataDir dir)
return "";
}
u64 ClearDir(DataDir dir)
u64 ClearDir(DataDir dir, const std::string &user_id)
{
fs::path data_dir = GetDataDir(dir);
fs::path data_dir = GetDataDir(dir, user_id);
u64 result = fs::remove_all(data_dir);
// mkpath at the end just so it actually exists

4
src/frontend_common/data_manager.h

@ -11,9 +11,9 @@ namespace FrontendCommon::DataManager {
enum class DataDir { Saves, UserNand, SysNand, Mods, Shaders };
const std::string GetDataDir(DataDir dir);
const std::string GetDataDir(DataDir dir, const std::string &user_id = "");
u64 ClearDir(DataDir dir);
u64 ClearDir(DataDir dir, const std::string &user_id = "");
const std::string ReadableBytesSize(u64 size);

3
src/qt_common/qt_compress.cpp

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "qt_compress.h"
#include "quazipfileinfo.h"

3
src/qt_common/qt_compress.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QDir>

18
src/qt_common/qt_content_util.cpp

@ -358,7 +358,7 @@ void FixProfiles()
QtCommon::Game::OpenSaveFolder();
}
void ClearDataDir(FrontendCommon::DataManager::DataDir dir)
void ClearDataDir(FrontendCommon::DataManager::DataDir dir, const std::string& user_id)
{
auto result = QtCommon::Frontend::Warning(tr("Really clear data?"),
tr("Important data may be lost!"),
@ -379,15 +379,17 @@ void ClearDataDir(FrontendCommon::DataManager::DataDir dir)
QtCommon::Frontend::QtProgressDialog dialog(tr("Clearing..."), QString(), 0, 0);
dialog.show();
FrontendCommon::DataManager::ClearDir(dir);
FrontendCommon::DataManager::ClearDir(dir, user_id);
dialog.close();
}
void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir, std::function<void()> callback)
void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir,
const std::string& user_id,
std::function<void()> callback)
{
using namespace QtCommon::Frontend;
const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir);
const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir, user_id);
const QString zip_dump_location = GetSaveFileName(tr("Select Export Location"),
QStringLiteral("export.zip"),
@ -447,9 +449,11 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir, std::function<
watcher->setFuture(future);
}
void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir, std::function<void()> callback)
void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir,
const std::string& user_id,
std::function<void()> callback)
{
const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir);
const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir, user_id);
using namespace QtCommon::Frontend;
@ -484,7 +488,7 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir, std::function<
// to prevent GUI mangling we have to run this in a thread as well
QFuture<bool> delete_future = QtConcurrent::run([=]() {
FrontendCommon::DataManager::ClearDir(data_dir);
FrontendCommon::DataManager::ClearDir(data_dir, user_id);
return !progress->wasCanceled();
});

6
src/qt_common/qt_content_util.h

@ -47,9 +47,9 @@ void InstallKeys();
void VerifyGameContents(const std::string &game_path);
void VerifyInstalledContents();
void ClearDataDir(FrontendCommon::DataManager::DataDir dir);
void ExportDataDir(FrontendCommon::DataManager::DataDir dir, std::function<void()> callback = {});
void ImportDataDir(FrontendCommon::DataManager::DataDir dir, std::function<void()> callback = {});
void ClearDataDir(FrontendCommon::DataManager::DataDir dir, const std::string &user_id = "");
void ExportDataDir(FrontendCommon::DataManager::DataDir dir, const std::string &user_id = "", std::function<void()> callback = {});
void ImportDataDir(FrontendCommon::DataManager::DataDir dir, const std::string &user_id = "", std::function<void()> callback = {});
// Profiles //
void FixProfiles();

63
src/yuzu/data_dialog.cpp

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "data_dialog.h"
#include "core/hle/service/acc/profile_manager.h"
#include "frontend_common/data_manager.h"
#include "qt_common/qt_content_util.h"
#include "qt_common/qt_frontend_util.h"
@ -15,6 +16,10 @@
#include <QProgressDialog>
#include <QtConcurrentRun>
#include <core/frontend/applets/profile_select.h>
#include <applets/qt_profile_select.h>
DataDialog::DataDialog(QWidget *parent)
: QDialog(parent)
, ui(std::make_unique<Ui::DataDialog>())
@ -73,24 +78,40 @@ DataWidget::DataWidget(FrontendCommon::DataManager::DataDir data_dir,
void DataWidget::clear()
{
QtCommon::Content::ClearDataDir(m_dir);
std::string user_id{};
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
user_id = selectProfile();
}
QtCommon::Content::ClearDataDir(m_dir, user_id);
scan();
}
void DataWidget::open()
{
std::string user_id{};
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
user_id = selectProfile();
}
QDesktopServices::openUrl(QUrl::fromLocalFile(
QString::fromStdString(FrontendCommon::DataManager::GetDataDir(m_dir))));
QString::fromStdString(FrontendCommon::DataManager::GetDataDir(m_dir, user_id))));
}
void DataWidget::upload()
{
QtCommon::Content::ExportDataDir(m_dir);
std::string user_id{};
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
user_id = selectProfile();
}
QtCommon::Content::ExportDataDir(m_dir, user_id);
}
void DataWidget::download()
{
QtCommon::Content::ImportDataDir(m_dir, std::bind(&DataWidget::scan, this));
std::string user_id{};
if (m_dir == FrontendCommon::DataManager::DataDir::Saves) {
user_id = selectProfile();
}
QtCommon::Content::ImportDataDir(m_dir, user_id, std::bind(&DataWidget::scan, this));
}
void DataWidget::scan() {
@ -108,3 +129,37 @@ void DataWidget::scan() {
watcher->setFuture(
QtConcurrent::run([this]() { return FrontendCommon::DataManager::DataDirSize(m_dir); }));
}
std::string DataWidget::selectProfile()
{
const auto select_profile = [this] {
const Core::Frontend::ProfileSelectParameters parameters{
.mode = Service::AM::Frontend::UiMode::UserSelector,
.invalid_uid_list = {},
.display_options = {},
.purpose = Service::AM::Frontend::UserSelectionPurpose::General,
};
QtProfileSelectionDialog dialog(*QtCommon::system, this, parameters);
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint
| Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
dialog.setWindowModality(Qt::WindowModal);
if (dialog.exec() == QDialog::Rejected) {
return -1;
}
return dialog.GetIndex();
};
const auto index = select_profile();
if (index == -1) {
return "";
}
const auto uuid = QtCommon::system->GetProfileManager().GetUser(static_cast<std::size_t>(index));
ASSERT(uuid);
const auto user_id = uuid->AsU128();
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
}

2
src/yuzu/data_dialog.h

@ -45,6 +45,8 @@ public slots:
private:
std::unique_ptr<Ui::DataWidget> ui;
FrontendCommon::DataManager::DataDir m_dir;
std::string selectProfile();
};
#endif // DATA_DIALOG_H

2
src/yuzu/main.cpp

@ -2408,7 +2408,6 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
ASSERT_MSG(has_user_save != has_device_save, "Game uses both user and device savedata?");
// TODO(alekpop): It returns the wrong user
switch (target) {
case GameListOpenTarget::SaveData: {
open_target = tr("Save Data");
@ -2794,6 +2793,7 @@ void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& ga
}
void GMainWindow::OnGameListOpenDirectory(const QString& directory) {
// TODO(crueter): QtCommon
std::filesystem::path fs_path;
if (directory == QStringLiteral("SDMC")) {
fs_path =

Loading…
Cancel
Save