mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 09:39:33 +01:00
Savedata manager: Export a game's saves from the popup of one of them
The page-wide button depended on the game the screen was opened for, which the screen doesn't show. The popup knows the game from the save itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9be62bb7d5
commit
95e7f2d686
2 files changed
+29
-27
No files matched your search
+28
-23
@@ -67,6 +67,19 @@ static void AddFolderToZip(const Path &folder, const std::string &nameInZip, std
|
||||
}
|
||||
}
|
||||
|
||||
// The save folders of a game next to a save of it, without installed data.
|
||||
static std::vector<Path> FindGameSaves(const Path &saveDir, std::string_view gameID) {
|
||||
std::vector<Path> saves;
|
||||
std::vector<File::FileInfo> dirs;
|
||||
File::GetFilesInDir(saveDir, &dirs);
|
||||
for (const File::FileInfo &dir : dirs) {
|
||||
if (dir.isDirectory && startsWith(dir.name, gameID) && File::Exists(dir.fullName / "PARAM.SFO") && !IsInstalledGameData(dir.fullName)) {
|
||||
saves.push_back(dir.fullName);
|
||||
}
|
||||
}
|
||||
return saves;
|
||||
}
|
||||
|
||||
static void ExportAsZip(std::string_view zipName, const std::vector<ShareZipEntry> &entries) {
|
||||
if (!ShareFilesAsZip(zipName, entries)) {
|
||||
auto sa = GetI18NCategory(I18NCat::SAVEDATA);
|
||||
@@ -207,6 +220,21 @@ void SavedataPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
}
|
||||
}
|
||||
|
||||
if (canExport && !isState && ginfo->Ready(GameInfoFlags::PARAM_SFO) && ginfo->id.size() >= 5) {
|
||||
// The game ID starts the folder names (the same rule as GetSaveDataDirectories()).
|
||||
std::vector<Path> gameSaves = FindGameSaves(savePath_.NavigateUp(), ginfo->id);
|
||||
if (gameSaves.size() > 1) {
|
||||
std::string zipName = ginfo->GetTitle() + " (" + ginfo->id + ")";
|
||||
content->Add(new Choice(sa->T("Export all saves for this game"), ImageID("I_SHARE"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)))->OnClick.Add([gameSaves, zipName](UI::EventParams &e) {
|
||||
std::vector<ShareZipEntry> entries;
|
||||
for (const Path &dir : gameSaves) {
|
||||
AddFolderToZip(dir, dir.GetFilename(), &entries);
|
||||
}
|
||||
ExportAsZip(zipName, entries);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
buttonRow->SetSpacing(12);
|
||||
|
||||
@@ -762,8 +790,6 @@ void SavedataScreen::CreateSavestateTab(UI::ViewGroup *savestate) {
|
||||
|
||||
bool SavedataScreen::LookUpGame() {
|
||||
gameID_.clear();
|
||||
gameTitle_.clear();
|
||||
gameSaveDirs_.clear();
|
||||
if (gamePath_.empty()) {
|
||||
return true;
|
||||
}
|
||||
@@ -778,13 +804,6 @@ bool SavedataScreen::LookUpGame() {
|
||||
return true;
|
||||
}
|
||||
gameID_ = ginfo->id;
|
||||
gameTitle_ = ginfo->GetTitle();
|
||||
for (const Path &dir : ginfo->GetSaveDataDirectories()) {
|
||||
// The folders the browser lists, without installed data.
|
||||
if (File::Exists(dir / "PARAM.SFO") && !IsInstalledGameData(dir)) {
|
||||
gameSaveDirs_.push_back(dir);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -814,12 +833,6 @@ void SavedataScreen::CreateTabs() {
|
||||
|
||||
void SavedataScreen::CreateExtraButtons(UI::ViewGroup *verticalLayout, int margins) {
|
||||
using namespace UI;
|
||||
if (!gameSaveDirs_.empty() && CanShareFiles()) {
|
||||
auto sa = GetI18NCategory(I18NCat::SAVEDATA);
|
||||
Choice *exportButton = verticalLayout->Add(new Choice(sa->T("Export all saves for this game"), ImageID("I_SHARE"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0, 0, margins, margins))));
|
||||
exportButton->OnClick.Handle(this, &SavedataScreen::OnExportGameSaves);
|
||||
exportButton->SetRoundCorners();
|
||||
}
|
||||
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
Choice *searchButton = verticalLayout->Add(new Choice(di->T("Search"), ImageID("I_SEARCH"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0, 0, margins, margins))));
|
||||
@@ -837,14 +850,6 @@ void SavedataScreen::OnSearch(UI::EventParams &e) {
|
||||
}
|
||||
}
|
||||
|
||||
void SavedataScreen::OnExportGameSaves(UI::EventParams &e) {
|
||||
std::vector<ShareZipEntry> entries;
|
||||
for (const Path &dir : gameSaveDirs_) {
|
||||
AddFolderToZip(dir, dir.GetFilename(), &entries);
|
||||
}
|
||||
ExportAsZip(gameTitle_ + " (" + gameID_ + ")", entries);
|
||||
}
|
||||
|
||||
void SavedataScreen::OnSavedataButtonClick(UI::EventParams &e) {
|
||||
// the game path: e.s;
|
||||
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(screenManager()->getDrawContext(), Path(e.s), GameInfoFlags::PARAM_SFO);
|
||||
|
||||
+1
-4
@@ -118,16 +118,13 @@ protected:
|
||||
private:
|
||||
void OnSavedataButtonClick(UI::EventParams &e);
|
||||
void OnSearch(UI::EventParams &e);
|
||||
void OnExportGameSaves(UI::EventParams &e);
|
||||
|
||||
void CreateSavedataTab(UI::ViewGroup *savedata);
|
||||
void CreateSavestateTab(UI::ViewGroup *savestate);
|
||||
// The ID and title of the game the screen was opened for, once its PARAM.SFO is loaded.
|
||||
// The ID of the game the screen was opened for (its saves are highlighted), once its PARAM.SFO is loaded.
|
||||
bool LookUpGame();
|
||||
|
||||
std::string gameID_;
|
||||
std::string gameTitle_;
|
||||
std::vector<Path> gameSaveDirs_; // The game's saves, without installed data.
|
||||
bool gameLookupPending_ = false;
|
||||
SavedataSortOption sortOption_ = SavedataSortOption::FILENAME;
|
||||
SavedataBrowser *dataBrowser_ = nullptr;
|
||||
|
||||
Reference in new issue
Block a user