Merge pull request #1136 from tech4me/master
qt/main: Port part of citra(#3411), open savedata works
This commit is contained in:
commit
b38d67d940
|
@ -73,7 +73,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, SaveDataDescr
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id,
|
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
|
// 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.
|
// be interpreted as the title id of the current process.
|
||||||
if (type == SaveDataType::SaveData && title_id == 0)
|
if (type == SaveDataType::SaveData && title_id == 0)
|
||||||
|
|
|
@ -49,11 +49,11 @@ public:
|
||||||
|
|
||||||
ResultVal<VirtualDir> Open(SaveDataSpaceId space, SaveDataDescriptor meta);
|
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:
|
private:
|
||||||
VirtualDir dir;
|
VirtualDir dir;
|
||||||
|
|
||||||
std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id,
|
|
||||||
u64 save_id) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -327,7 +327,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
||||||
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
||||||
open_save_location->setEnabled(program_id != 0);
|
open_save_location->setEnabled(program_id != 0);
|
||||||
connect(open_save_location, &QAction::triggered,
|
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));
|
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
class GameListWorker;
|
class GameListWorker;
|
||||||
|
|
||||||
|
enum class GameListOpenTarget { SaveData };
|
||||||
|
|
||||||
class GameList : public QWidget {
|
class GameList : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -76,7 +78,7 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void GameChosen(QString game_path);
|
void GameChosen(QString game_path);
|
||||||
void ShouldCancelWorker();
|
void ShouldCancelWorker();
|
||||||
void OpenSaveFolderRequested(u64 program_id);
|
void OpenFolderRequested(u64 program_id, GameListOpenTarget target);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onTextChanged(const QString& newText);
|
void onTextChanged(const QString& newText);
|
||||||
|
@ -99,3 +101,5 @@ private:
|
||||||
GameListWorker* current_worker = nullptr;
|
GameListWorker* current_worker = nullptr;
|
||||||
QFileSystemWatcher* watcher = nullptr;
|
QFileSystemWatcher* watcher = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(GameListOpenTarget);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "core/file_sys/bis_factory.h"
|
#include "core/file_sys/bis_factory.h"
|
||||||
#include "core/file_sys/card_image.h"
|
#include "core/file_sys/card_image.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
#include "core/file_sys/savedata_factory.h"
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs_real.h"
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
@ -337,8 +338,7 @@ void GMainWindow::RestoreUIState() {
|
||||||
|
|
||||||
void GMainWindow::ConnectWidgetEvents() {
|
void GMainWindow::ConnectWidgetEvents() {
|
||||||
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
|
connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile);
|
||||||
connect(game_list, &GameList::OpenSaveFolderRequested, this,
|
connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder);
|
||||||
&GMainWindow::OnGameListOpenSaveFolder);
|
|
||||||
|
|
||||||
connect(this, &GMainWindow::EmulationStarting, render_window,
|
connect(this, &GMainWindow::EmulationStarting, render_window,
|
||||||
&GRenderWindow::OnEmulationStarting);
|
&GRenderWindow::OnEmulationStarting);
|
||||||
|
@ -624,10 +624,39 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
|
||||||
BootGame(game_path);
|
BootGame(game_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnGameListOpenSaveFolder(u64 program_id) {
|
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();
|
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() {
|
void GMainWindow::OnMenuLoadFile() {
|
||||||
QString extensions;
|
QString extensions;
|
||||||
for (const auto& piece : game_list->supported_file_extensions)
|
for (const auto& piece : game_list->supported_file_extensions)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class GRenderWindow;
|
||||||
class MicroProfileDialog;
|
class MicroProfileDialog;
|
||||||
class ProfilerWidget;
|
class ProfilerWidget;
|
||||||
class WaitTreeWidget;
|
class WaitTreeWidget;
|
||||||
|
enum class GameListOpenTarget;
|
||||||
|
|
||||||
namespace Tegra {
|
namespace Tegra {
|
||||||
class DebugContext;
|
class DebugContext;
|
||||||
|
@ -122,7 +123,7 @@ private slots:
|
||||||
void OnStopGame();
|
void OnStopGame();
|
||||||
/// Called whenever a user selects a game in the game list widget.
|
/// Called whenever a user selects a game in the game list widget.
|
||||||
void OnGameListLoadFile(QString game_path);
|
void OnGameListLoadFile(QString game_path);
|
||||||
void OnGameListOpenSaveFolder(u64 program_id);
|
void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target);
|
||||||
void OnMenuLoadFile();
|
void OnMenuLoadFile();
|
||||||
void OnMenuLoadFolder();
|
void OnMenuLoadFolder();
|
||||||
void OnMenuInstallToNAND();
|
void OnMenuInstallToNAND();
|
||||||
|
|
Loading…
Reference in New Issue