Win32: Add a function to move files to trash instead of deleting them

This commit is contained in:
Henrik Rydgård
2025-04-10 08:27:07 +02:00
parent 7e760b262a
commit 69b2f7d9b6
6 changed files with 74 additions and 17 deletions
+52
View File
@@ -1371,4 +1371,56 @@ bool IsProbablyInDownloadsFolder(const Path &filename) {
return filename.FilePathContainsNoCase("download");
}
// The Win32 implementation kinda belongs in ShellUtil.cpp but that's in the wrong project.
// Some reorganization is in order...
bool MoveFileToTrash(const Path &path) {
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
IFileOperation *pFileOp = nullptr;
HRESULT hr = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pFileOp));
if (FAILED(hr)) {
return false;
}
// Set operation flags
hr = pFileOp->SetOperationFlags(FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT);
if (FAILED(hr)) {
pFileOp->Release();
CoUninitialize();
return false;
}
// Create a shell item from the file path
IShellItem* pItem = nullptr;
hr = SHCreateItemFromParsingName(path.ToWString().c_str(), nullptr, IID_PPV_ARGS(&pItem));
if (SUCCEEDED(hr)) {
// Schedule the delete (move to recycle bin)
hr = pFileOp->DeleteItem(pItem, nullptr);
if (SUCCEEDED(hr)) {
hr = pFileOp->PerformOperations(); // Execute
}
pItem->Release();
}
pFileOp->Release();
return true;
#else
return false;
#endif
}
bool MoveFileToTrashOrDelete(const Path &path) {
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
return MoveFileToTrash(path);
#else
return Delete(path);
#endif
}
bool MoveDirectoryTreeToTrashOrDelete(const Path &path) {
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
return MoveFileToTrash(path); // works with directories
#else
return DeleteDirRecursively(path);
#endif
}
} // namespace File
+8
View File
@@ -233,4 +233,12 @@ inline bool ReadTextFileToString(const Path &path, std::string *str) {
// Return value must be delete[]-d.
uint8_t *ReadLocalFile(const Path &path, size_t *size);
// Moves to trash/recycle bin.
// This is only functional if SYSPROP_HAS_TRASH_BIN is true, otherwise will return false.
bool MoveFileToTrash(const Path &path);
// These move to trash if possible, otherwise permanently delete.
bool MoveFileToTrashOrDelete(const Path &path);
bool MoveDirectoryTreeToTrashOrDelete(const Path &path);
} // namespace
+1
View File
@@ -221,6 +221,7 @@ enum SystemProperty {
SYSPROP_BATTERY_PERCENTAGE,
SYSPROP_ENOUGH_RAM_FOR_FULL_ISO,
SYSPROP_HAS_TRASH_BIN,
};
enum class SystemNotification {
+12 -16
View File
@@ -321,25 +321,21 @@ UI::EventReturn GameScreen::OnCreateConfig(UI::EventParams &e) {
return UI::EVENT_DONE;
}
void GameScreen::CallbackDeleteConfig(bool yes) {
if (yes) {
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(nullptr, gamePath_, GameInfoFlags::PARAM_SFO);
if (!info->Ready(GameInfoFlags::PARAM_SFO)) {
return;
}
g_Config.deleteGameConfig(info->id);
info->hasConfig = false;
screenManager()->RecreateAllViews();
}
}
UI::EventReturn GameScreen::OnDeleteConfig(UI::EventParams &e)
{
UI::EventReturn GameScreen::OnDeleteConfig(UI::EventParams &e) {
auto di = GetI18NCategory(I18NCat::DIALOG);
screenManager()->push(
new PromptScreen(gamePath_, di->T("DeleteConfirmGameConfig", "Do you really want to delete the settings for this game?"), di->T("Delete"), di->T("Cancel"),
std::bind(&GameScreen::CallbackDeleteConfig, this, std::placeholders::_1)));
[this](bool result) {
if (result) {
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(nullptr, gamePath_, GameInfoFlags::PARAM_SFO);
if (!info->Ready(GameInfoFlags::PARAM_SFO)) {
return;
}
g_Config.deleteGameConfig(info->id);
info->hasConfig = false;
screenManager()->RecreateAllViews();
}
}));
return UI::EVENT_DONE;
}
-1
View File
@@ -44,7 +44,6 @@ public:
protected:
void CreateViews() override;
void CallbackDeleteConfig(bool yes);
void CallbackDeleteSaveData(bool yes);
void CallbackDeleteGame(bool yes);
+1
View File
@@ -379,6 +379,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
case SYSPROP_HAS_TEXT_INPUT_DIALOG:
case SYSPROP_CAN_CREATE_SHORTCUT:
case SYSPROP_CAN_SHOW_FILE:
case SYSPROP_HAS_TRASH_BIN:
return true;
case SYSPROP_HAS_IMAGE_BROWSER:
return true;