|
@@ -1,8 +1,9 @@
|
|
|
package org.cryptomator.ui.addvaultwizard;
|
|
|
|
|
|
import dagger.Lazy;
|
|
|
-import org.cryptomator.common.locationpresets.LocationPresetsProvider;
|
|
|
+import org.cryptomator.common.ObservableUtil;
|
|
|
import org.cryptomator.common.locationpresets.LocationPreset;
|
|
|
+import org.cryptomator.common.locationpresets.LocationPresetsProvider;
|
|
|
import org.cryptomator.ui.common.FxController;
|
|
|
import org.cryptomator.ui.common.FxmlFile;
|
|
|
import org.cryptomator.ui.common.FxmlScene;
|
|
@@ -12,17 +13,13 @@ import org.slf4j.LoggerFactory;
|
|
|
|
|
|
import javax.inject.Inject;
|
|
|
import javax.inject.Named;
|
|
|
-import javafx.beans.binding.Bindings;
|
|
|
import javafx.beans.binding.BooleanBinding;
|
|
|
import javafx.beans.property.BooleanProperty;
|
|
|
import javafx.beans.property.ObjectProperty;
|
|
|
import javafx.beans.property.SimpleBooleanProperty;
|
|
|
-import javafx.beans.property.SimpleObjectProperty;
|
|
|
-import javafx.beans.property.SimpleStringProperty;
|
|
|
import javafx.beans.property.StringProperty;
|
|
|
import javafx.beans.value.ObservableValue;
|
|
|
import javafx.fxml.FXML;
|
|
|
-import javafx.scene.Node;
|
|
|
import javafx.scene.Scene;
|
|
|
import javafx.scene.control.Label;
|
|
|
import javafx.scene.control.RadioButton;
|
|
@@ -56,10 +53,9 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
private final ObjectProperty<Path> vaultPath;
|
|
|
private final StringProperty vaultName;
|
|
|
private final ResourceBundle resourceBundle;
|
|
|
- private final BooleanBinding validVaultPath;
|
|
|
+ private final ObservableValue<VaultPathStatus> vaultPathStatus;
|
|
|
+ private final ObservableValue<Boolean> validVaultPath;
|
|
|
private final BooleanProperty usePresetPath;
|
|
|
- private final StringProperty statusText;
|
|
|
- private final ObjectProperty<Node> statusGraphic;
|
|
|
|
|
|
private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH;
|
|
|
|
|
@@ -67,7 +63,7 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
public ToggleGroup locationPresetsToggler;
|
|
|
public VBox radioButtonVBox;
|
|
|
public RadioButton customRadioButton;
|
|
|
- public Label vaultPathStatus;
|
|
|
+ public Label locationStatusLabel;
|
|
|
public FontAwesome5IconView goodLocation;
|
|
|
public FontAwesome5IconView badLocation;
|
|
|
|
|
@@ -79,10 +75,10 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
this.vaultPath = vaultPath;
|
|
|
this.vaultName = vaultName;
|
|
|
this.resourceBundle = resourceBundle;
|
|
|
- this.validVaultPath = Bindings.createBooleanBinding(this::validateVaultPathAndSetStatus, this.vaultPath);
|
|
|
+ this.vaultPathStatus = ObservableUtil.mapWithDefault(vaultPath, this::validatePath, new VaultPathStatus(false, "error.message"));
|
|
|
+ this.validVaultPath = ObservableUtil.mapWithDefault(vaultPathStatus, VaultPathStatus::valid, false);
|
|
|
+ this.vaultPathStatus.addListener(this::updateStatusLabel);
|
|
|
this.usePresetPath = new SimpleBooleanProperty();
|
|
|
- this.statusText = new SimpleStringProperty();
|
|
|
- this.statusGraphic = new SimpleObjectProperty<>();
|
|
|
this.locationPresetBtns = LocationPresetsProvider.loadAll(LocationPresetsProvider.class) //
|
|
|
.flatMap(LocationPresetsProvider::getLocations) //
|
|
|
.sorted(Comparator.comparing(LocationPreset::name)) //
|
|
@@ -93,31 +89,32 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
}).toList();
|
|
|
}
|
|
|
|
|
|
- private boolean validateVaultPathAndSetStatus() {
|
|
|
- final Path p = vaultPath.get();
|
|
|
- if (p == null) {
|
|
|
- statusText.set("Error: Path is NULL.");
|
|
|
- statusGraphic.set(badLocation);
|
|
|
- return false;
|
|
|
- } else if (!Files.exists(p.getParent())) {
|
|
|
- statusText.set(resourceBundle.getString("addvaultwizard.new.locationDoesNotExist"));
|
|
|
- statusGraphic.set(badLocation);
|
|
|
- return false;
|
|
|
+ private VaultPathStatus validatePath(Path p) throws NullPointerException {
|
|
|
+ if (!Files.exists(p.getParent())) {
|
|
|
+ return new VaultPathStatus(false, "addvaultwizard.new.locationDoesNotExist");
|
|
|
} else if (!isActuallyWritable(p.getParent())) {
|
|
|
- statusText.set(resourceBundle.getString("addvaultwizard.new.locationIsNotWritable"));
|
|
|
- statusGraphic.set(badLocation);
|
|
|
- return false;
|
|
|
+ return new VaultPathStatus(false, "addvaultwizard.new.locationIsNotWritable");
|
|
|
} else if (!Files.notExists(p)) {
|
|
|
- statusText.set(resourceBundle.getString("addvaultwizard.new.fileAlreadyExists"));
|
|
|
- statusGraphic.set(badLocation);
|
|
|
- return false;
|
|
|
+ return new VaultPathStatus(false, "addvaultwizard.new.fileAlreadyExists");
|
|
|
} else {
|
|
|
- statusText.set(resourceBundle.getString("addvaultwizard.new.locationIsOk"));
|
|
|
- statusGraphic.set(goodLocation);
|
|
|
- return true;
|
|
|
+ return new VaultPathStatus(true, "addvaultwizard.new.locationIsOk");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void updateStatusLabel(ObservableValue<? extends VaultPathStatus> observable, VaultPathStatus oldValue, VaultPathStatus newValue) {
|
|
|
+ if (newValue.valid()) {
|
|
|
+ locationStatusLabel.setGraphic(goodLocation);
|
|
|
+ locationStatusLabel.getStyleClass().remove("label-red");
|
|
|
+ locationStatusLabel.getStyleClass().add("label-muted");
|
|
|
+ } else {
|
|
|
+ locationStatusLabel.setGraphic(badLocation);
|
|
|
+ locationStatusLabel.getStyleClass().remove("label-muted");
|
|
|
+ locationStatusLabel.getStyleClass().add("label-red");
|
|
|
+ }
|
|
|
+ this.locationStatusLabel.setText(resourceBundle.getString(newValue.localizationKey()));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private boolean isActuallyWritable(Path p) {
|
|
|
Path tmpFile = p.resolve(TEMP_FILE_FORMAT);
|
|
|
try (var chan = Files.newByteChannel(tmpFile, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) {
|
|
@@ -153,10 +150,8 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
|
|
|
@FXML
|
|
|
public void next() {
|
|
|
- if (validateVaultPathAndSetStatus()) {
|
|
|
+ if (validVaultPath.getValue()) {
|
|
|
window.setScene(choosePasswordScene.get());
|
|
|
- } else {
|
|
|
- validVaultPath.invalidate();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -176,6 +171,12 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /* Internal classes */
|
|
|
+
|
|
|
+ private record VaultPathStatus(boolean valid, String localizationKey) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
/* Getter/Setter */
|
|
|
|
|
|
public Path getVaultPath() {
|
|
@@ -186,19 +187,19 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
return vaultPath;
|
|
|
}
|
|
|
|
|
|
- public BooleanBinding validVaultPathProperty() {
|
|
|
+ public ObservableValue<Boolean> validVaultPathProperty() {
|
|
|
return validVaultPath;
|
|
|
}
|
|
|
|
|
|
- public Boolean getValidVaultPath() {
|
|
|
- return validVaultPath.get();
|
|
|
+ public boolean isValidVaultPath() {
|
|
|
+ return validVaultPath.getValue();
|
|
|
}
|
|
|
|
|
|
public BooleanProperty usePresetPathProperty() {
|
|
|
return usePresetPath;
|
|
|
}
|
|
|
|
|
|
- public boolean getUsePresetPath() {
|
|
|
+ public boolean isUsePresetPath() {
|
|
|
return usePresetPath.get();
|
|
|
}
|
|
|
|
|
@@ -210,20 +211,4 @@ public class CreateNewVaultLocationController implements FxController {
|
|
|
return anyRadioButtonSelectedProperty().get();
|
|
|
}
|
|
|
|
|
|
- public StringProperty statusTextProperty() {
|
|
|
- return statusText;
|
|
|
- }
|
|
|
-
|
|
|
- public String getStatusText() {
|
|
|
- return statusText.get();
|
|
|
- }
|
|
|
-
|
|
|
- public ObjectProperty<Node> statusGraphicProperty() {
|
|
|
- return statusGraphic;
|
|
|
- }
|
|
|
-
|
|
|
- public Node getStatusGraphic() {
|
|
|
- return statusGraphic.get();
|
|
|
- }
|
|
|
-
|
|
|
}
|