From cc71832b19ed9d3579160ddb8fe6e4f9a8269553 Mon Sep 17 00:00:00 2001 From: tech4me Date: Mon, 20 Aug 2018 21:46:40 -0700 Subject: qt/main: Port part of citra(#3411), open savedata works --- src/core/file_sys/savedata_factory.cpp | 2 +- src/core/file_sys/savedata_factory.h | 6 +++--- src/yuzu/game_list.cpp | 2 +- src/yuzu/game_list.h | 6 +++++- src/yuzu/main.cpp | 37 ++++++++++++++++++++++++++++++---- src/yuzu/main.h | 3 ++- 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index dfdca83d6..034d3a78f 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -73,7 +73,7 @@ ResultVal SaveDataFactory::Open(SaveDataSpaceId space, SaveDataDescr } std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, - u128 user_id, u64 save_id) const { + u128 user_id, u64 save_id) { // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should // be interpreted as the title id of the current process. if (type == SaveDataType::SaveData && title_id == 0) diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index f3cf50d5a..368b36017 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h @@ -49,11 +49,11 @@ public: ResultVal Open(SaveDataSpaceId space, SaveDataDescriptor meta); + static std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, + u128 user_id, u64 save_id); + private: VirtualDir dir; - - std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, - u64 save_id) const; }; } // namespace FileSys diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index a974fb933..d5726b8b3 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -327,7 +327,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); open_save_location->setEnabled(program_id != 0); connect(open_save_location, &QAction::triggered, - [&]() { emit OpenSaveFolderRequested(program_id); }); + [&]() { emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData); }); context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location)); } diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index afe624b32..20252e778 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -21,6 +21,8 @@ class GameListWorker; +enum class GameListOpenTarget { SaveData }; + class GameList : public QWidget { Q_OBJECT @@ -76,7 +78,7 @@ public: signals: void GameChosen(QString game_path); void ShouldCancelWorker(); - void OpenSaveFolderRequested(u64 program_id); + void OpenFolderRequested(u64 program_id, GameListOpenTarget target); private slots: void onTextChanged(const QString& newText); @@ -99,3 +101,5 @@ private: GameListWorker* current_worker = nullptr; QFileSystemWatcher* watcher = nullptr; }; + +Q_DECLARE_METATYPE(GameListOpenTarget); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 3db3f9d98..e4cac5984 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -30,6 +30,7 @@ #include "core/file_sys/bis_factory.h" #include "core/file_sys/card_image.h" #include "core/file_sys/registered_cache.h" +#include "core/file_sys/savedata_factory.h" #include "core/file_sys/vfs_real.h" #include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" @@ -303,8 +304,7 @@ void GMainWindow::RestoreUIState() { void GMainWindow::ConnectWidgetEvents() { connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile); - connect(game_list, &GameList::OpenSaveFolderRequested, this, - &GMainWindow::OnGameListOpenSaveFolder); + connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder); connect(this, &GMainWindow::EmulationStarting, render_window, &GRenderWindow::OnEmulationStarting); @@ -584,8 +584,37 @@ void GMainWindow::OnGameListLoadFile(QString game_path) { BootGame(game_path); } -void GMainWindow::OnGameListOpenSaveFolder(u64 program_id) { - UNIMPLEMENTED(); +void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target) { + std::string path; + std::string open_target; + switch (target) { + case GameListOpenTarget::SaveData: { + open_target = "Save Data"; + const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir); + ASSERT(program_id != 0); + // TODO(tech4me): Update this to work with arbitrary user profile + // Refer to core/hle/service/acc/profile_manager.cpp ProfileManager constructor + constexpr u128 user_id = {1, 0}; + path = nand_dir + FileSys::SaveDataFactory::GetFullPath(FileSys::SaveDataSpaceId::NandUser, + FileSys::SaveDataType::SaveData, + program_id, user_id, 0); + break; + } + default: + UNIMPLEMENTED(); + } + + const QString qpath = QString::fromStdString(path); + + const QDir dir(qpath); + if (!dir.exists()) { + QMessageBox::warning(this, + tr("Error Opening %1 Folder").arg(QString::fromStdString(open_target)), + tr("Folder does not exist!")); + return; + } + LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target, program_id); + QDesktopServices::openUrl(QUrl::fromLocalFile(qpath)); } void GMainWindow::OnMenuLoadFile() { diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 5f4d2ab9a..02df30878 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -21,6 +21,7 @@ class GRenderWindow; class MicroProfileDialog; class ProfilerWidget; class WaitTreeWidget; +enum class GameListOpenTarget; namespace Tegra { class DebugContext; @@ -122,7 +123,7 @@ private slots: void OnStopGame(); /// Called whenever a user selects a game in the game list widget. void OnGameListLoadFile(QString game_path); - void OnGameListOpenSaveFolder(u64 program_id); + void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); void OnMenuLoadFile(); void OnMenuLoadFolder(); void OnMenuInstallToNAND(); -- cgit v1.2.3