Browse Source

Merge pull request #1136 from tech4me/master

qt/main: Port part of citra(#3411), open savedata works
bunnei 8 years ago
parent
commit
b38d67d940

+ 1 - 1
src/core/file_sys/savedata_factory.cpp

@@ -73,7 +73,7 @@ ResultVal<VirtualDir> 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)

+ 3 - 3
src/core/file_sys/savedata_factory.h

@@ -49,11 +49,11 @@ public:
 
     ResultVal<VirtualDir> 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

+ 1 - 1
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));
 }
 

+ 5 - 1
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);

+ 33 - 4
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"
@@ -337,8 +338,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);
@@ -624,8 +624,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() {

+ 2 - 1
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();