This commit is contained in:
Sebastian Stenzel
2020-05-07 16:45:24 +02:00
parent 93011dc754
commit 86906d0049
9 changed files with 111 additions and 6 deletions

View File

@@ -35,6 +35,7 @@ public class VaultSettings {
public static final boolean DEFAULT_USES_READONLY_MODE = false;
public static final String DEFAULT_MOUNT_FLAGS = "";
public static final int DEFAULT_FILENAME_LENGTH_LIMIT = -1;
public static final WhenUnlocked DEFAULT_ACTION_AFTER_UNLOCK = WhenUnlocked.ASK;
private static final Random RNG = new Random();
@@ -49,6 +50,7 @@ public class VaultSettings {
private final BooleanProperty usesReadOnlyMode = new SimpleBooleanProperty(DEFAULT_USES_READONLY_MODE);
private final StringProperty mountFlags = new SimpleStringProperty(DEFAULT_MOUNT_FLAGS);
private final IntegerProperty filenameLengthLimit = new SimpleIntegerProperty(DEFAULT_FILENAME_LENGTH_LIMIT);
private final ObjectProperty<WhenUnlocked> actionAfterUnlock = new SimpleObjectProperty<>(DEFAULT_ACTION_AFTER_UNLOCK);
public VaultSettings(String id) {
this.id = Objects.requireNonNull(id);
@@ -57,7 +59,7 @@ public class VaultSettings {
}
Observable[] observables() {
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, usesIndividualMountPath, individualMountPath, usesReadOnlyMode, mountFlags, filenameLengthLimit};
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, useCustomMountPath, customMountPath, usesReadOnlyMode, mountFlags, filenameLengthLimit, actionAfterUnlock};
}
private void deriveMountNameFromPath(Path path) {
@@ -149,6 +151,14 @@ public class VaultSettings {
return filenameLengthLimit;
}
public ObjectProperty<WhenUnlocked> actionAfterUnlock() {
return actionAfterUnlock;
}
public WhenUnlocked getActionAfterUnlock() {
return actionAfterUnlock.get();
}
/* Hashcode/Equals */
@Override

View File

@@ -30,6 +30,7 @@ class VaultSettingsJsonAdapter {
out.name("usesReadOnlyMode").value(value.usesReadOnlyMode().get());
out.name("mountFlags").value(value.mountFlags().get());
out.name("filenameLengthLimit").value(value.filenameLengthLimit().get());
out.name("actionAfterUnlock").value(value.actionAfterUnlock().get().name());
out.endObject();
}
@@ -45,6 +46,7 @@ class VaultSettingsJsonAdapter {
boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE;
String mountFlags = VaultSettings.DEFAULT_MOUNT_FLAGS;
int filenameLengthLimit = VaultSettings.DEFAULT_FILENAME_LENGTH_LIMIT;
WhenUnlocked actionAfterUnlock = VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
in.beginObject();
while (in.hasNext()) {
@@ -85,6 +87,9 @@ class VaultSettingsJsonAdapter {
case "filenameLengthLimit":
filenameLengthLimit = in.nextInt();
break;
case "actionAfterUnlock":
actionAfterUnlock = parseActionAfterUnlock(in.nextString());
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
@@ -104,7 +109,17 @@ class VaultSettingsJsonAdapter {
vaultSettings.usesReadOnlyMode().set(usesReadOnlyMode);
vaultSettings.mountFlags().set(mountFlags);
vaultSettings.filenameLengthLimit().set(filenameLengthLimit);
vaultSettings.actionAfterUnlock().set(actionAfterUnlock);
return vaultSettings;
}
private WhenUnlocked parseActionAfterUnlock(String actionAfterUnlockName) {
try {
return WhenUnlocked.valueOf(actionAfterUnlockName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid action after unlock {}. Defaulting to {}.", actionAfterUnlockName, VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK);
return VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
}
}
}

View File

@@ -0,0 +1,17 @@
package org.cryptomator.common.settings;
public enum WhenUnlocked {
IGNORE("vaultOptions.general.actionAfterUnlock.ignore"),
REVEAL("vaultOptions.general.actionAfterUnlock.reveal"),
ASK("vaultOptions.general.actionAfterUnlock.ask");
private String displayName;
WhenUnlocked(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}

View File

@@ -7,8 +7,10 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
import javafx.stage.Stage;
import org.cryptomator.common.settings.WhenUnlocked;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.VaultService;
@@ -29,6 +31,8 @@ public class UnlockSuccessController implements FxController {
private final VaultService vaultService;
private final ObjectProperty<ContentDisplay> revealButtonState;
private final BooleanProperty revealButtonDisabled;
public CheckBox rememberChoiceCheckbox;
@Inject
public UnlockSuccessController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, VaultService vaultService) {
@@ -44,6 +48,9 @@ public class UnlockSuccessController implements FxController {
public void close() {
LOG.trace("UnlockSuccessController.close()");
window.close();
if (rememberChoiceCheckbox.isSelected()) {
vault.getVaultSettings().actionAfterUnlock().setValue(WhenUnlocked.IGNORE);
}
}
@FXML
@@ -64,6 +71,9 @@ public class UnlockSuccessController implements FxController {
revealButtonDisabled.set(false);
});
executor.execute(revealTask);
if (rememberChoiceCheckbox.isSelected()) {
vault.getVaultSettings().actionAfterUnlock().setValue(WhenUnlocked.REVEAL);
}
}
/* Getter/Setter */

View File

@@ -5,6 +5,7 @@ import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.cryptomator.common.settings.WhenUnlocked;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.common.vaults.Volume;
@@ -121,9 +122,12 @@ public class UnlockWorkflow extends Task<Boolean> {
if (savePassword.get()) {
savePasswordToSystemkeychain();
}
Platform.runLater(() -> {
window.setScene(successScene.get()); // TODO only if enabled (see issue #1083)
});
if (vault.getVaultSettings().actionAfterUnlock().get() == WhenUnlocked.ASK) {
Platform.runLater(() -> {
window.setScene(successScene.get());
window.show();
});
}
}
private void savePasswordToSystemkeychain() {

View File

@@ -2,24 +2,56 @@ package org.cryptomator.ui.vaultoptions;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.util.StringConverter;
import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.common.settings.WhenUnlocked;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
import java.util.ResourceBundle;
@VaultOptionsScoped
public class GeneralVaultOptionsController implements FxController {
private final Vault vault;
private final ResourceBundle resourceBundle;
public CheckBox unlockOnStartupCheckbox;
public ChoiceBox<WhenUnlocked> actionAfterUnlockChoiceBox;
@Inject
GeneralVaultOptionsController(@VaultOptionsWindow Vault vault) {
GeneralVaultOptionsController(@VaultOptionsWindow Vault vault, ResourceBundle resourceBundle) {
this.vault = vault;
this.resourceBundle = resourceBundle;
}
@FXML
public void initialize() {
unlockOnStartupCheckbox.selectedProperty().bindBidirectional(vault.getVaultSettings().unlockAfterStartup());
actionAfterUnlockChoiceBox.getItems().addAll(WhenUnlocked.values());
actionAfterUnlockChoiceBox.valueProperty().bindBidirectional(vault.getVaultSettings().actionAfterUnlock());
actionAfterUnlockChoiceBox.setConverter(new WhenUnlockedConverter(resourceBundle));
}
private static class WhenUnlockedConverter extends StringConverter<WhenUnlocked> {
private final ResourceBundle resourceBundle;
public WhenUnlockedConverter(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
@Override
public String toString(WhenUnlocked obj) {
return resourceBundle.getString(obj.getDisplayName());
}
@Override
public WhenUnlocked fromString(String string) {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -10,6 +10,7 @@
<?import javafx.scene.shape.Circle?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.FormattedLabel?>
<?import javafx.scene.control.CheckBox?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.unlock.UnlockSuccessController"
@@ -26,7 +27,10 @@
<Circle styleClass="glyph-icon-primary" radius="24"/>
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="CHECK" glyphSize="24"/>
</StackPane>
<FormattedLabel format="%unlock.success.message" arg1="${controller.vault.displayableName}" wrapText="true" HBox.hgrow="ALWAYS"/>
<VBox spacing="6">
<FormattedLabel format="%unlock.success.message" arg1="${controller.vault.displayableName}" wrapText="true" HBox.hgrow="ALWAYS"/>
<CheckBox text="%unlock.success.rememberChoice" fx:id="rememberChoiceCheckbox"/>
</VBox>
</HBox>
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">

View File

@@ -3,6 +3,9 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.vaultoptions.GeneralVaultOptionsController"
@@ -12,5 +15,10 @@
</padding>
<children>
<CheckBox text="%vaultOptions.general.unlockAfterStartup" fx:id="unlockOnStartupCheckbox"/>
<HBox spacing="6" alignment="CENTER_LEFT">
<Label text="%vaultOptions.general.actionAfterUnlock"/>
<ChoiceBox fx:id="actionAfterUnlockChoiceBox"/>
</HBox>
</children>
</VBox>

View File

@@ -96,6 +96,7 @@ unlock.savePassword=Save Password
unlock.unlockBtn=Unlock
## Success
unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible.
unlock.success.rememberChoice=Remember choice, don't show this again
unlock.success.revealBtn=Reveal Vault
## Invalid Mount Point
unlock.error.invalidMountPoint=Mount point is not an empty directory: %s
@@ -206,6 +207,10 @@ wrongFileAlert.link=For further assistance, visit
## General
vaultOptions.general=General
vaultOptions.general.unlockAfterStartup=Unlock vault when starting Cryptomator
vaultOptions.general.actionAfterUnlock=After successful unlock
vaultOptions.general.actionAfterUnlock.ignore=Do nothing
vaultOptions.general.actionAfterUnlock.reveal=Reveal Drive
vaultOptions.general.actionAfterUnlock.ask=Ask
## Mount
vaultOptions.mount=Mounting
vaultOptions.mount.readonly=Read-Only