diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartMacStrategy.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartMacStrategy.java index 3c5205316..0bc469a77 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartMacStrategy.java +++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartMacStrategy.java @@ -4,10 +4,13 @@ import org.cryptomator.jni.MacFunctions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + class AutoStartMacStrategy implements AutoStartStrategy { private static final Logger LOG = LoggerFactory.getLogger(AutoStartMacStrategy.class); - + private final MacFunctions macFunctions; public AutoStartMacStrategy(MacFunctions macFunctions) { @@ -15,25 +18,26 @@ class AutoStartMacStrategy implements AutoStartStrategy { } @Override - public boolean isAutoStartEnabled() { - return macFunctions.launchServices().isLoginItemEnabled(); + public CompletionStage isAutoStartEnabled() { + boolean enabled = macFunctions.launchServices().isLoginItemEnabled(); + return CompletableFuture.completedFuture(enabled); } @Override - public void enableAutoStart() { + public void enableAutoStart() throws TogglingAutoStartFailedException { if (macFunctions.launchServices().enableLoginItem()) { LOG.debug("Added login item."); } else { - LOG.warn("Adding login item failed."); + throw new TogglingAutoStartFailedException("Failed to add login item."); } } @Override - public void disableAutoStart() { + public void disableAutoStart() throws TogglingAutoStartFailedException { if (macFunctions.launchServices().disableLoginItem()) { LOG.debug("Removed login item."); } else { - LOG.warn("Removing login item failed."); + throw new TogglingAutoStartFailedException("Failed to remove login item."); } } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartStrategy.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartStrategy.java index 543804795..99b21b4cd 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartStrategy.java +++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/AutoStartStrategy.java @@ -1,10 +1,24 @@ package org.cryptomator.ui.preferences; +import java.util.concurrent.CompletionStage; + public interface AutoStartStrategy { - boolean isAutoStartEnabled(); + CompletionStage isAutoStartEnabled(); - void enableAutoStart(); + void enableAutoStart() throws TogglingAutoStartFailedException; - void disableAutoStart(); + void disableAutoStart() throws TogglingAutoStartFailedException; + + class TogglingAutoStartFailedException extends Exception { + + public TogglingAutoStartFailedException(String message) { + super(message); + } + + public TogglingAutoStartFailedException(String message, Throwable cause) { + super(message, cause); + } + + } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java index 9a7985901..61c37e4ab 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java @@ -1,6 +1,8 @@ package org.cryptomator.ui.preferences; +import javafx.application.Platform; import javafx.beans.value.ObservableValue; +import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.geometry.NodeOrientation; import javafx.scene.control.CheckBox; @@ -18,6 +20,7 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; import java.util.Optional; +import java.util.concurrent.ExecutorService; @PreferencesScoped public class GeneralPreferencesController implements FxController { @@ -27,6 +30,7 @@ public class GeneralPreferencesController implements FxController { private final Settings settings; private final boolean trayMenuSupported; private final Optional autoStartStrategy; + private final ExecutorService executor; public ChoiceBox themeChoiceBox; public CheckBox startHiddenCheckbox; public CheckBox debugModeCheckbox; @@ -36,10 +40,11 @@ public class GeneralPreferencesController implements FxController { public RadioButton nodeOrientationRtl; @Inject - GeneralPreferencesController(Settings settings, @Named("trayMenuSupported") boolean trayMenuSupported, Optional autoStartStrategy) { + GeneralPreferencesController(Settings settings, @Named("trayMenuSupported") boolean trayMenuSupported, Optional autoStartStrategy, ExecutorService executor) { this.settings = settings; this.trayMenuSupported = trayMenuSupported; this.autoStartStrategy = autoStartStrategy; + this.executor = executor; } @FXML @@ -52,8 +57,11 @@ public class GeneralPreferencesController implements FxController { debugModeCheckbox.selectedProperty().bindBidirectional(settings.debugMode()); - autoStartCheckbox.setSelected(this.isAutoStartEnabled()); - autoStartCheckbox.selectedProperty().addListener(this::toggleAutoStart); + autoStartStrategy.ifPresent(autoStart -> { + autoStart.isAutoStartEnabled().thenAccept(enabled -> { + Platform.runLater(() -> autoStartCheckbox.setSelected(enabled)); + }); + }); nodeOrientationLtr.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.LEFT_TO_RIGHT); nodeOrientationRtl.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.RIGHT_TO_LEFT); @@ -68,20 +76,6 @@ public class GeneralPreferencesController implements FxController { return autoStartStrategy.isPresent(); } - private boolean isAutoStartEnabled() { - return autoStartStrategy.map(AutoStartStrategy::isAutoStartEnabled).orElse(false); - } - - private void toggleAutoStart(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") boolean oldValue, boolean newValue) { - autoStartStrategy.ifPresent(autoStart -> { - if (newValue) { - autoStart.enableAutoStart(); - } else { - autoStart.disableAutoStart(); - } - }); - } - private void toggleNodeOrientation(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) { if (nodeOrientationLtr.equals(newValue)) { settings.userInterfaceOrientation().set(NodeOrientation.LEFT_TO_RIGHT); @@ -92,6 +86,16 @@ public class GeneralPreferencesController implements FxController { } } + @FXML + public void toggleAutoStart() { + autoStartStrategy.ifPresent(autoStart -> { + boolean enableAutoStart = autoStartCheckbox.isSelected(); + Task toggleTask = new ToggleAutoStartTask(autoStart, enableAutoStart); + toggleTask.setOnFailed(evt -> autoStartCheckbox.setSelected(!enableAutoStart)); // restore previous state + executor.execute(toggleTask); + }); + } + /* Helper classes */ private static class UiThemeConverter extends StringConverter { @@ -107,4 +111,25 @@ public class GeneralPreferencesController implements FxController { } } + private static class ToggleAutoStartTask extends Task { + + private final AutoStartStrategy autoStart; + private final boolean enable; + + public ToggleAutoStartTask(AutoStartStrategy autoStart, boolean enable) { + this.autoStart = autoStart; + this.enable = enable; + } + + @Override + protected Void call() throws Exception { + if (enable) { + autoStart.enableAutoStart(); + } else { + autoStart.disableAutoStart(); + } + return null; + } + } + } diff --git a/main/ui/src/main/resources/fxml/preferences_general.fxml b/main/ui/src/main/resources/fxml/preferences_general.fxml index f89db9638..4688d7f6e 100644 --- a/main/ui/src/main/resources/fxml/preferences_general.fxml +++ b/main/ui/src/main/resources/fxml/preferences_general.fxml @@ -34,6 +34,6 @@ - +