瀏覽代碼

also adjust styleClass of location label

Armin Schrenk 1 年之前
父節點
當前提交
6acda9b13c

+ 39 - 54
src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java

@@ -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();
-	}
-
 }

+ 1 - 1
src/main/resources/fxml/addvault_new_location.fxml

@@ -47,7 +47,7 @@
 		<VBox spacing="6">
 			<Label text="%addvaultwizard.new.locationLabel" labelFor="$locationTextField"/>
 			<TextField fx:id="locationTextField" promptText="%addvaultwizard.new.locationPrompt" text="${controller.vaultPath}" editable="false" disable="${!controller.anyRadioButtonSelected}" HBox.hgrow="ALWAYS"/>
-			<Label fx:id="vaultPathStatus" styleClass="label-muted" alignment="CENTER_RIGHT" wrapText="true" visible="${controller.anyRadioButtonSelected}" maxWidth="Infinity" graphicTextGap="6" text="${controller.statusText}" graphic="${controller.statusGraphic}" />
+			<Label fx:id="locationStatusLabel" alignment="CENTER_RIGHT" wrapText="true" visible="${controller.anyRadioButtonSelected}" maxWidth="Infinity" graphicTextGap="6" />
 		</VBox>
 
 		<Region VBox.vgrow="ALWAYS"/>