From a8119a47a15fd78127adf645698c944ed33097a7 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 15 Oct 2019 14:39:47 -0400 Subject: [PATCH] qt: Add Tools commands for system archive management --- src/yuzu/main.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++ src/yuzu/main.h | 4 +++ src/yuzu/main.ui | 33 +++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 89df1a612d..828102cdda 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -27,6 +27,7 @@ #include "core/hle/service/am/applets/applets.h" #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/hid.h" +#include "yuzu/status/system_archive.h" // These are wrappers to avoid the calls to CreateDirectory and CreateFile because of the Windows // defines. @@ -40,6 +41,10 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual return dir->CreateFile(path); } +static bool VfsDirectoryDeleteFileWrapper(const FileSys::VirtualDir& dir, const std::string& path) { + return dir->DeleteFile(path); +} + #include #include @@ -83,6 +88,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "core/file_sys/romfs.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/submission_package.h" +#include "core/file_sys/system_archive/importer.h" #include "core/frontend/applets/software_keyboard.h" #include "core/hle/kernel/process.h" #include "core/hle/service/am/am.h" @@ -760,6 +766,16 @@ void GMainWindow::ConnectMenuEvents() { connect(ui.action_Capture_Screenshot, &QAction::triggered, this, &GMainWindow::OnCaptureScreenshot); + // Tools + connect(ui.actionImport_Directory, &QAction::triggered, this, + &GMainWindow::OnImportDirectorySystemUpdate); + connect(ui.actionImport_Cartridge, &QAction::triggered, this, + &GMainWindow::OnImportCartridgeSystemUpdate); + connect(ui.actionClear_Imported, &QAction::triggered, this, + &GMainWindow::OnClearImportedSysdata); + connect(ui.actionView_Status, &QAction::triggered, this, + &GMainWindow::OnViewSystemArchiveStatus); + // Help connect(ui.action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder); connect(ui.action_Rederive, &QAction::triggered, this, @@ -1358,6 +1374,71 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id, QDesktopServices::openUrl(QUrl(QStringLiteral("https://yuzu-emu.org/game/") + directory)); } +void GMainWindow::OnClearImportedSysdata() { + Core::System& system{Core::System::GetInstance()}; + + const auto path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + "imported" DIR_SEP; + QDir dir(QString::fromStdString(path)); + const auto list = dir.entryList(QDir::Files); + for (const auto& file : list) { + if (!dir.remove(file)) { + QMessageBox::warning(this, tr("Clear Failed"), + tr("The imported sysdata directory was not able to be cleared.")); + return; + } + } + + QMessageBox::information(this, tr("Clear Successful"), + tr("The imported sysdata directory was cleared successfully.")); +} + +void GMainWindow::OnImportDirectorySystemUpdate() { + Core::System& system{Core::System::GetInstance()}; + + const auto dir = QFileDialog::getExistingDirectory(this, tr("Select System Update Directory")); + + if (dir.isEmpty()) { + return; + } + + const auto vdir = vfs->OpenDirectory(dir.toStdString(), FileSys::Mode::Read); + if (FileSys::SystemArchive::ImportDirectorySystemUpdate( + system.GetFileSystemController().GetSysdataImportedDirectory(), vdir)) { + QMessageBox::information(this, tr("Import Successful"), + tr("The system update import was successful.")); + } else { + QMessageBox::warning(this, tr("Import Failed"), tr("The system update import failed.")); + } +} + +void GMainWindow::OnImportCartridgeSystemUpdate() { + Core::System& system{Core::System::GetInstance()}; + + const auto file = QFileDialog::getOpenFileName(this, tr("Select Cartridge File"), QString{}, + QStringLiteral("Cartridge Images (*.xci)")); + + if (file.isEmpty()) { + return; + } + + FileSys::XCI xci{vfs->OpenFile(file.toStdString(), FileSys::Mode::Read)}; + if (FileSys::SystemArchive::ImportXCISystemUpdate( + system.GetFileSystemController().GetSysdataImportedDirectory(), xci)) { + QMessageBox::information(this, tr("Import Successful"), + tr("The system update import was successful.")); + } else { + QMessageBox::warning(this, tr("Import Failed"), tr("The system update import failed.")); + } +} + +void GMainWindow::OnViewSystemArchiveStatus() { + Core::System& system{Core::System::GetInstance()}; + + system.GetFileSystemController().CreateFactories(*vfs); + SystemArchiveDialog dialog(this, system.GetFileSystemController()); + dialog.exec(); +} + void GMainWindow::OnGameListOpenDirectory(const QString& directory) { QString path; if (directory == QStringLiteral("SDMC")) { diff --git a/src/yuzu/main.h b/src/yuzu/main.h index fd4b9ccf54..cce177f7f0 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -190,6 +190,10 @@ private slots: void OnGameListCopyTID(u64 program_id); void OnGameListNavigateToGamedbEntry(u64 program_id, const CompatibilityList& compatibility_list); + void OnClearImportedSysdata(); + void OnImportDirectorySystemUpdate(); + void OnImportCartridgeSystemUpdate(); + void OnViewSystemArchiveStatus(); void OnGameListOpenDirectory(const QString& directory); void OnGameListAddDirectory(); void OnGameListShowList(bool show); diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index a1ce3c0c35..37cc24e17b 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -104,9 +104,22 @@ Tools + + + System Archives + + + + + + + + + + @@ -293,6 +306,26 @@ Capture Screenshot + + + Import Directory + + + + + Import Cartridge + + + + + Clear Imported + + + + + View Status + +