mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Win32: Add a function to move files to trash instead of deleting them
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -221,6 +221,7 @@ enum SystemProperty {
|
||||
SYSPROP_BATTERY_PERCENTAGE,
|
||||
|
||||
SYSPROP_ENOUGH_RAM_FOR_FULL_ISO,
|
||||
SYSPROP_HAS_TRASH_BIN,
|
||||
};
|
||||
|
||||
enum class SystemNotification {
|
||||
|
||||
+12
-16
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
|
||||
protected:
|
||||
void CreateViews() override;
|
||||
void CallbackDeleteConfig(bool yes);
|
||||
void CallbackDeleteSaveData(bool yes);
|
||||
void CallbackDeleteGame(bool yes);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user