From 6911cfa387f6b7737a5b4a5aeb3a5d36b90c5245 Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Sun, 19 Aug 2018 11:34:07 +0800 Subject: [PATCH] try to move deleting version to trash --- .../org/jackhuang/hmcl/ui/VersionPage.java | 10 +++++-- .../resources/assets/lang/I18N.properties | 3 +- .../resources/assets/lang/I18N_zh.properties | 3 +- .../assets/lang/I18N_zh_CN.properties | 3 +- .../hmcl/game/DefaultGameRepository.java | 8 ++++-- .../org/jackhuang/hmcl/util/FileUtils.java | 28 ++++++++++++++++++- 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java index 32575afcf..ee14e1281 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java @@ -26,17 +26,17 @@ import javafx.beans.property.StringProperty; import javafx.fxml.FXML; import javafx.scene.control.Tab; import javafx.scene.layout.StackPane; - import org.jackhuang.hmcl.download.game.GameAssetIndexDownloadTask; import org.jackhuang.hmcl.setting.EnumGameDirectory; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.ui.export.ExportWizardProvider; import org.jackhuang.hmcl.ui.wizard.DecoratorPage; import org.jackhuang.hmcl.util.FileUtils; -import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import java.io.File; +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; + public final class VersionPage extends StackPane implements DecoratorPage { private final StringProperty title = new SimpleStringProperty(this, "title", null); @@ -188,7 +188,11 @@ public final class VersionPage extends StackPane implements DecoratorPage { public static void deleteVersion(Profile profile, String version) { boolean isIndependent = profile.getVersionSetting(version).getGameDirType() == EnumGameDirectory.VERSION_FOLDER; - Controllers.confirmDialog(i18n(isIndependent ? "version.manage.remove.confirm.independent" : "version.manage.remove.confirm", version), i18n("message.confirm"), () -> { + boolean isMovingToTrashSupported = FileUtils.isMovingToTrashSupported(); + String message = isIndependent ? i18n("version.manage.remove.confirm.independent", version) : + isMovingToTrashSupported ? i18n("version.manage.remove.confirm.trash", version, version + "_removed") : + i18n("version.manage.remove.confirm", version); + Controllers.confirmDialog(message, i18n("message.confirm"), () -> { if (profile.getRepository().removeVersionFromDisk(version)) { profile.getRepository().refreshVersionsAsync().start(); Controllers.navigate(null); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index b2c53ea70..3149bff9f 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -334,7 +334,8 @@ version.launch_script.save=Save the launch script version.launch_script.success=Finished script creation, %s. version.manage.redownload_assets_index=Redownload Assets Index version.manage.remove=Delete this game -version.manage.remove.confirm=Sure to remove game %s? +version.manage.remove.confirm=Sure to remove game %s? You cannot restore this game again! +version.manage.remove.confirm.trash=Sure to remove game %s? You can restore the game with the name of %s in your system trash. version.manage.remove.confirm.independent=Since this game is in independent mode, deleting this game will result in all saved worlds belonging to this game removed simultaneously. Sure to remove game %s? version.manage.remove_libraries=Delete library files version.manage.rename=Rename this game diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 48718bce0..a99de3a1a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -334,7 +334,8 @@ version.launch_script.save=保存啓動腳本 version.launch_script.success=啓動腳本已生成完畢:%s version.manage.redownload_assets_index=重新下載資源配置(assets_index.json) version.manage.remove=刪除該版本 -version.manage.remove.confirm=真的要刪除版本 %s 嗎? +version.manage.remove.confirm=真的要刪除版本 %s 嗎?你將無法找回被刪除的文件! +version.manage.remove.confirm.trash=真的要刪除版本 %s 嗎?你可以在系統的回收站中恢復文件夾 %s 來找回該版本。 version.manage.remove.confirm.independent=由於該遊戲使用了版本隔離,所以刪除該版本將導致該遊戲的存檔等數據一同被刪除,真的要刪除版本 %s 嗎? version.manage.remove_libraries=刪除所有庫文件 version.manage.rename=重命名該版本 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 441aeb07b..291ae689a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -334,7 +334,8 @@ version.launch_script.save=保存启动脚本 version.launch_script.success=启动脚本已生成完毕:%s version.manage.redownload_assets_index=重新下载资源配置(assets_index.json) version.manage.remove=删除该版本 -version.manage.remove.confirm=真的要删除版本 %s 吗? +version.manage.remove.confirm=真的要删除版本 %s 吗?你将无法找回被删除的文件! +version.manage.remove.confirm.trash=真的要删除版本 %s 吗?你可以在系统的回收站中恢复文件夹 %s 来找回该版本。 version.manage.remove.confirm.independent=由于该游戏使用了版本隔离,所以删除该版本将导致该游戏的存档等数据一同被删除,真的要删除版本 %s 吗? version.manage.remove_libraries=删除所有库文件 version.manage.rename=重命名该版本 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java index c6678f7c2..eaa0d428d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java @@ -160,14 +160,18 @@ public class DefaultGameRepository implements GameRepository { if (!file.renameTo(removedFile)) return false; + versions.remove(id); + + if (FileUtils.isMovingToTrashSupported()) { + return FileUtils.moveToTrash(removedFile); + } + // remove json files first to ensure HMCL will not recognize this folder as a valid version. List jsons = FileUtils.listFilesByExtension(removedFile, "json"); jsons.forEach(f -> { if (!f.delete()) Logging.LOG.warning("Unable to delete file " + f); }); - - versions.remove(id); // remove the version from version list regardless of whether the directory was removed successfully or not. try { FileUtils.deleteDirectory(removedFile); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java index 14e85afa0..27dcba1fb 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/FileUtils.java @@ -20,8 +20,10 @@ package org.jackhuang.hmcl.util; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.lang.reflect.Method; import java.nio.charset.Charset; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.LinkedList; import java.util.List; import java.util.Objects; @@ -95,6 +97,30 @@ public final class FileUtils { return Lang.test(() -> deleteDirectory(directory)); } + public static boolean moveToTrash(File file) { + try { + java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); + Method moveToTrash = desktop.getClass().getMethod("moveToTrash", File.class); + moveToTrash.invoke(desktop, file); + return true; + } catch (Exception e) { + return false; + } + } + + /** + * Check if {@code java.awt.Desktop.moveToTrash} exists. + * @return true if the method exists. + */ + public static boolean isMovingToTrashSupported() { + try { + java.awt.Desktop.class.getMethod("moveToTrash", File.class); + return true; + } catch (ReflectiveOperationException e) { + return false; + } + } + public static void cleanDirectory(File directory) throws IOException { if (!directory.exists()) {