diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java
index 72856c186..fd1abcd68 100644
--- a/src/main/java/org/cryptomator/common/settings/Settings.java
+++ b/src/main/java/org/cryptomator/common/settings/Settings.java
@@ -113,7 +113,12 @@ public class Settings {
migrateLegacySettings(json);
directories.addListener(this::somethingChanged);
- networkSettings.addListener(this::somethingChanged);
+ networkSettings.get().mode.addListener(this::somethingChanged);
+ networkSettings.get().httpProxy.addListener(this::somethingChanged);
+ networkSettings.get().httpPort.addListener(this::somethingChanged);
+ networkSettings.get().samePortProxyForHttpHttps.addListener(this::somethingChanged);
+ networkSettings.get().httpsProxy.addListener(this::somethingChanged);
+ networkSettings.get().httpsPort.addListener(this::somethingChanged);
askedForUpdateCheck.addListener(this::somethingChanged);
checkForUpdates.addListener(this::somethingChanged);
startHidden.addListener(this::somethingChanged);
diff --git a/src/main/java/org/cryptomator/ui/preferences/NetworkPreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/NetworkPreferencesController.java
index 2a2bba45b..79d91ad6e 100644
--- a/src/main/java/org/cryptomator/ui/preferences/NetworkPreferencesController.java
+++ b/src/main/java/org/cryptomator/ui/preferences/NetworkPreferencesController.java
@@ -1,42 +1,159 @@
package org.cryptomator.ui.preferences;
+import org.cryptomator.common.settings.NetworkSettings;
+import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.controls.NumericTextField;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.inject.Inject;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
+import javafx.scene.control.CheckBox;
import javafx.scene.control.RadioButton;
+import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
+import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
@PreferencesScoped
public class NetworkPreferencesController implements FxController {
- private static final Logger LOG = LoggerFactory.getLogger(NetworkPreferencesController.class);
+ private final Settings settings;
public ToggleGroup proxyToggleGroup;
public RadioButton noProxyBtn;
public RadioButton systemSettingsBtn;
public RadioButton manualProxyBtn;
public VBox manualProxyBox;
- public NumericTextField httpProxyPort;
- public NumericTextField httpsProxyPort;
+ public HBox httpsProxyBox;
+
+ @FXML
+ public TextField httpProxy;
+ public NumericTextField httpPort;
+ public CheckBox samePortProxyForHttpHttps;
+ public TextField httpsProxy;
+ public NumericTextField httpsPort;
@Inject
- NetworkPreferencesController() {
+ NetworkPreferencesController(Settings settings) {
+ this.settings = settings;
}
@FXML
public void initialize() {
- proxyToggleGroup.selectToggle(noProxyBtn);
+
+ initializeTextFieldWithValidation(httpProxy, settings.networkSettings.get().httpProxy);
+ initializeTextFieldWithValidation(httpPort, settings.networkSettings.get().httpPort);
+ initializeTextFieldWithValidation(httpsProxy, settings.networkSettings.get().httpsProxy);
+ initializeTextFieldWithValidation(httpsPort, settings.networkSettings.get().httpsPort);
+
+ samePortProxyForHttpHttps.selectedProperty().bindBidirectional(settings.networkSettings.get().samePortProxyForHttpHttps);
+ httpsProxyBox.setDisable(settings.networkSettings.get().samePortProxyForHttpHttps.get());
+ samePortProxyForHttpHttps.selectedProperty().addListener((_, _, newValue) -> {
+ httpsProxyBox.setDisable(newValue);
+ });
+
+ switch (settings.networkSettings.get().mode.get()) {
+ case NO -> {
+ proxyToggleGroup.selectToggle(noProxyBtn);
+ manualProxyBox.setDisable(true);
+ }
+ case SYSTEM -> {
+ proxyToggleGroup.selectToggle(systemSettingsBtn);
+ manualProxyBox.setDisable(true);
+ }
+ case MANUAL -> {
+ proxyToggleGroup.selectToggle(manualProxyBtn);
+ manualProxyBox.setDisable(false);
+ }
+ }
+
proxyToggleGroup.selectedToggleProperty().addListener((_, _, newValue) -> {
if (newValue != null) {
- RadioButton selectedRadioButton = (RadioButton) newValue;
- manualProxyBox.setDisable(!selectedRadioButton.equals(manualProxyBtn));
+ manualProxyBox.setDisable(!newValue.equals(manualProxyBtn));
+
+ if (newValue.equals(noProxyBtn)) {
+ settings.networkSettings.get().mode.set(NetworkSettings.ProxyMode.NO);
+ } else if (newValue.equals(systemSettingsBtn)) {
+ settings.networkSettings.get().mode.set(NetworkSettings.ProxyMode.SYSTEM);
+ } else if (newValue.equals(manualProxyBtn)) {
+ settings.networkSettings.get().mode.set(NetworkSettings.ProxyMode.MANUAL);
+ }
+ }
+ });
+
+ }
+
+ private void initializeTextFieldWithValidation(TextField textField, StringProperty property) {
+ textField.setText(property.get());
+
+ textField.textProperty().addListener((_, _, newValue) -> {
+ if (isValidHttpProxy(newValue)) {
+ textField.setStyle("-fx-border-color: green; -fx-border-width: 2px; -fx-border-radius: 3px; -fx-padding: 3px;");
+ } else {
+ textField.setStyle("-fx-border-color: red; -fx-border-width: 2px; -fx-border-radius: 3px; -fx-padding: 3px;");
+ }
+ });
+
+ textField.focusedProperty().addListener((_, oldValue, newValue) -> {
+ if (!newValue) {
+ String text = textField.getText();
+ if (isValidHttpProxy(text)) {
+ property.set(text);
+ textField.setStyle("");
+ }
}
});
}
+ private boolean isValidHttpProxy(String text) {
+ if (text == null || text.isEmpty()) {
+ return false;
+ }
+ String regex = "^([\\w.-]+)$";
+ return text.matches(regex);
+ }
+
+ private void initializeTextFieldWithValidation(TextField textField, IntegerProperty property) {
+ textField.setText(String.valueOf(property.get()));
+
+ textField.textProperty().addListener((observable, oldValue, newValue) -> {
+ if (isValidPort(newValue)) {
+ textField.setStyle("-fx-border-color: green; -fx-border-width: 2px; -fx-border-radius: 3px; -fx-padding: 3px;");
+ } else {
+ textField.setStyle("-fx-border-color: red; -fx-border-width: 2px; -fx-border-radius: 3px; -fx-padding: 3px;");
+ }
+ });
+
+ textField.focusedProperty().addListener((_, _, newValue) -> {
+ if (!newValue) {
+ String text = textField.getText();
+ if (isValidPort(text)) {
+ property.set(Integer.parseInt(text));
+ textField.setText(removeLeadingZeros(textField.getText()));
+ textField.setStyle("");
+ }
+ }
+ });
+ }
+
+ public static String removeLeadingZeros(String str) {
+ if (str == null || str.isEmpty()) {
+ return str;
+ }
+ return str.replaceFirst("^0+(?!$)", "");
+ }
+
+ private boolean isValidPort(String text) {
+ if (text == null || text.isEmpty()) {
+ return false;
+ }
+ try {
+ int value = Integer.parseInt(text);
+ return value >= 1024 && value <= 8888;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
}
diff --git a/src/main/resources/fxml/preferences_network.fxml b/src/main/resources/fxml/preferences_network.fxml
index 9936d5a16..6b00a80d3 100644
--- a/src/main/resources/fxml/preferences_network.fxml
+++ b/src/main/resources/fxml/preferences_network.fxml
@@ -33,14 +33,14 @@
-
+
-
-
+
+
-
+