diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java index e0e4d70e5..fc5019162 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java @@ -217,7 +217,22 @@ public class MainController implements ViewController { private void gracefulShutdown() { vaults.filtered(Vault.NOT_LOCKED).forEach(Vault::prepareForShutdown); - Platform.runLater(Platform::exit); + if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) { + ButtonType tryAgainButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.tryAgain")); + ButtonType forceShutdownButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.forceShutdown")); + Alert gracefulShutdownDialog = DialogBuilderUtil.buildGracefulShutdownDialog( + localization.getString("main.gracefulShutdown.dialog.title"), localization.getString("main.gracefulShutdown.dialog.header"), localization.getString("main.gracefulShutdown.dialog.content"), + forceShutdownButtonType, forceShutdownButtonType, tryAgainButtonType); + + Optional choice = gracefulShutdownDialog.showAndWait(); + choice.ifPresent(btnType -> { + if (tryAgainButtonType.equals(btnType)) { + gracefulShutdown(); + } else if (forceShutdownButtonType.equals(btnType)) { + Platform.runLater(Platform::exit); + } + }); + } } private void loadFont(String resourcePath) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/util/DialogBuilderUtil.java b/main/ui/src/main/java/org/cryptomator/ui/util/DialogBuilderUtil.java index 59741e2f2..744c37cff 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/util/DialogBuilderUtil.java +++ b/main/ui/src/main/java/org/cryptomator/ui/util/DialogBuilderUtil.java @@ -38,6 +38,10 @@ public class DialogBuilderUtil { return buildDialog(title, header, content, Alert.AlertType.CONFIRMATION, defaultButton, ButtonType.YES, ButtonType.NO); } + public static Alert buildGracefulShutdownDialog(String title, String header, String content, ButtonType defaultButton, ButtonType... buttons) { + return buildDialog(title, header, content, Alert.AlertType.WARNING, defaultButton, buttons); + } + private static Alert buildDialog(String title, String header, String content, Alert.AlertType type, ButtonType defaultButton, ButtonType... buttons) { Text contentText = new Text(content); contentText.setWrappingWidth(360.0); diff --git a/main/ui/src/main/resources/localization/en.txt b/main/ui/src/main/resources/localization/en.txt index 3018503fe..03f6e8847 100644 --- a/main/ui/src/main/resources/localization/en.txt +++ b/main/ui/src/main/resources/localization/en.txt @@ -19,6 +19,11 @@ main.directoryList.remove.confirmation.content=The vault will only be removed fr main.createVault.nonEmptyDir.title=Creating vault failed main.createVault.nonEmptyDir.header=Chosen directory is not empty main.createVault.nonEmptyDir.content=The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory. +main.gracefulShutdown.dialog.title=Locking vault(s) failed +main.gracefulShutdown.dialog.header=Vault(s) in use +main.gracefulShutdown.dialog.content=One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended. +main.gracefulShutdown.button.tryAgain=Try again +main.gracefulShutdown.button.forceShutdown=Force shutdown # welcome.fxml welcome.checkForUpdates.label.currentlyChecking=Checking for Updates...