Sebastian Stenzel %!s(int64=9) %!d(string=hai) anos
pai
achega
c306151980

+ 2 - 1
main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java

@@ -90,7 +90,8 @@ class CryptomatorModule {
 
 	@Provides
 	@Singleton
-	FrontendFactory provideFrontendFactory(WebDavServer webDavServer) {
+	FrontendFactory provideFrontendFactory(WebDavServer webDavServer, Settings settings) {
+		webDavServer.setPort(settings.getPort());
 		webDavServer.start();
 		return closeLater(webDavServer, WebDavServer::stop);
 	}

+ 41 - 8
main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java

@@ -14,31 +14,39 @@ import java.util.ResourceBundle;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
+import org.apache.commons.lang3.CharUtils;
 import org.cryptomator.ui.settings.Settings;
 import org.fxmisc.easybind.EasyBind;
 
-import javafx.application.Application;
 import javafx.fxml.FXML;
 import javafx.scene.control.CheckBox;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyEvent;
 
 @Singleton
 public class SettingsController extends AbstractFXMLViewController {
 
-	private final Application app;
 	private final Settings settings;
 
 	@Inject
-	public SettingsController(Application app, Settings settings) {
-		this.app = app;
+	public SettingsController(Settings settings) {
 		this.settings = settings;
 	}
 
 	@FXML
 	private CheckBox checkForUpdatesCheckbox;
 
+	@FXML
+	private TextField portField;
+
 	@Override
 	public void initialize() {
-		checkForUpdatesCheckbox.setSelected(settings.isCheckForUpdatesEnabled());
+		checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally());
+		checkForUpdatesCheckbox.setSelected(settings.isCheckForUpdatesEnabled() && !areUpdatesManagedExternally());
+		portField.setText(String.valueOf(settings.getPort()));
+		portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents);
+
+		EasyBind.subscribe(portField.textProperty(), this::portDidChange);
 		EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), settings::setCheckForUpdatesEnabled);
 	}
 
@@ -52,8 +60,33 @@ public class SettingsController extends AbstractFXMLViewController {
 		return ResourceBundle.getBundle("localization");
 	}
 
-	// private boolean areUpdatesManagedExternally() {
-	// return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
-	// }
+	private void portDidChange(String newValue) {
+		try {
+			int port = Integer.parseInt(newValue);
+			if (port < Settings.MIN_PORT) {
+				settings.setPort(Settings.DEFAULT_PORT);
+			} else if (port < Settings.MAX_PORT) {
+				settings.setPort(port);
+			} else {
+				portField.setText(String.valueOf(Settings.MAX_PORT));
+			}
+		} catch (NumberFormatException e) {
+			portField.setText(String.valueOf(Settings.DEFAULT_PORT));
+		}
+	}
+
+	private void filterNumericKeyEvents(KeyEvent t) {
+		if (t.getCharacter() == null || t.getCharacter().length() == 0) {
+			return;
+		}
+		char c = CharUtils.toChar(t.getCharacter());
+		if (!(CharUtils.isAsciiNumeric(c) || c == '_')) {
+			t.consume();
+		}
+	}
+
+	private boolean areUpdatesManagedExternally() {
+		return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
+	}
 
 }

+ 7 - 3
main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java

@@ -21,6 +21,7 @@ import org.cryptomator.crypto.engine.InvalidPassphraseException;
 import org.cryptomator.crypto.engine.UnsupportedVaultFormatException;
 import org.cryptomator.frontend.CommandFailedException;
 import org.cryptomator.frontend.FrontendCreationFailedException;
+import org.cryptomator.frontend.FrontendFactory;
 import org.cryptomator.frontend.webdav.mount.WindowsDriveLetters;
 import org.cryptomator.ui.controls.SecPasswordField;
 import org.cryptomator.ui.model.Vault;
@@ -28,6 +29,7 @@ import org.fxmisc.easybind.EasyBind;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import dagger.Lazy;
 import javafx.application.Application;
 import javafx.application.Platform;
 import javafx.beans.property.ObjectProperty;
@@ -51,16 +53,18 @@ public class UnlockController extends AbstractFXMLViewController {
 
 	private static final Logger LOG = LoggerFactory.getLogger(UnlockController.class);
 
-	private final ExecutorService exec;
 	private final Application app;
+	private final ExecutorService exec;
+	private final Lazy<FrontendFactory> frontendFactory;
 	private final WindowsDriveLetters driveLetters;
 	private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
 	final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
 
 	@Inject
-	public UnlockController(Application app, ExecutorService exec, WindowsDriveLetters driveLetters) {
+	public UnlockController(Application app, ExecutorService exec, Lazy<FrontendFactory> frontendFactory, WindowsDriveLetters driveLetters) {
 		this.app = app;
 		this.exec = exec;
+		this.frontendFactory = frontendFactory;
 		this.driveLetters = driveLetters;
 	}
 
@@ -272,7 +276,7 @@ public class UnlockController extends AbstractFXMLViewController {
 
 	private void unlock(CharSequence password) {
 		try {
-			vault.get().activateFrontend(password);
+			vault.get().activateFrontend(frontendFactory.get(), password);
 			vault.get().reveal();
 		} catch (InvalidPassphraseException e) {
 			Platform.runLater(() -> {

+ 3 - 6
main/ui/src/main/java/org/cryptomator/ui/model/Vault.java

@@ -45,7 +45,6 @@ import org.cryptomator.ui.util.FXThreads;
 
 import com.google.common.collect.ImmutableMap;
 
-import dagger.Lazy;
 import javafx.application.Platform;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.SimpleBooleanProperty;
@@ -59,7 +58,6 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 	public static final String VAULT_FILE_EXTENSION = ".cryptomator";
 
 	private final Path path;
-	private final Lazy<FrontendFactory> frontendFactory;
 	private final DeferredCloser closer;
 	private final ShorteningFileSystemFactory shorteningFileSystemFactory;
 	private final CryptoFileSystemFactory cryptoFileSystemFactory;
@@ -76,9 +74,8 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 	/**
 	 * Package private constructor, use {@link VaultFactory}.
 	 */
-	Vault(Path vaultDirectoryPath, Lazy<FrontendFactory> frontendFactory, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) {
+	Vault(Path vaultDirectoryPath, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) {
 		this.path = vaultDirectoryPath;
-		this.frontendFactory = frontendFactory;
 		this.closer = closer;
 		this.shorteningFileSystemFactory = shorteningFileSystemFactory;
 		this.cryptoFileSystemFactory = cryptoFileSystemFactory;
@@ -118,7 +115,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 		}
 	}
 
-	public synchronized void activateFrontend(CharSequence passphrase) throws FrontendCreationFailedException {
+	public synchronized void activateFrontend(FrontendFactory frontendFactory, CharSequence passphrase) throws FrontendCreationFailedException {
 		boolean success = false;
 		try {
 			FileSystem fs = getNioFileSystem();
@@ -127,7 +124,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
 			StatsFileSystem statsFs = new StatsFileSystem(cryptoFs);
 			statsFileSystem = Optional.of(statsFs);
 			String contextPath = StringUtils.prependIfMissing(mountName, "/");
-			Frontend frontend = frontendFactory.get().create(statsFs, contextPath);
+			Frontend frontend = frontendFactory.create(statsFs, contextPath);
 			filesystemFrontend = closer.closeLater(frontend);
 			frontend.mount(getMountParams());
 			success = true;

+ 2 - 7
main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java

@@ -15,30 +15,25 @@ import javax.inject.Singleton;
 
 import org.cryptomator.filesystem.crypto.CryptoFileSystemFactory;
 import org.cryptomator.filesystem.shortening.ShorteningFileSystemFactory;
-import org.cryptomator.frontend.FrontendFactory;
 import org.cryptomator.frontend.webdav.mount.WebDavMounter;
 import org.cryptomator.ui.util.DeferredCloser;
 
-import dagger.Lazy;
-
 @Singleton
 public class VaultFactory {
 
-	private final Lazy<FrontendFactory> frontendFactory;
 	private final ShorteningFileSystemFactory shorteningFileSystemFactory;
 	private final CryptoFileSystemFactory cryptoFileSystemFactory;
 	private final DeferredCloser closer;
 
 	@Inject
-	public VaultFactory(Lazy<FrontendFactory> frontendFactory, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, WebDavMounter mounter, DeferredCloser closer) {
-		this.frontendFactory = frontendFactory;
+	public VaultFactory(ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, WebDavMounter mounter, DeferredCloser closer) {
 		this.shorteningFileSystemFactory = shorteningFileSystemFactory;
 		this.cryptoFileSystemFactory = cryptoFileSystemFactory;
 		this.closer = closer;
 	}
 
 	public Vault createVault(Path path) {
-		return new Vault(path, frontendFactory, shorteningFileSystemFactory, cryptoFileSystemFactory, closer);
+		return new Vault(path, shorteningFileSystemFactory, cryptoFileSystemFactory, closer);
 	}
 
 }

+ 29 - 1
main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java

@@ -14,17 +14,26 @@ import java.util.List;
 
 import org.cryptomator.ui.model.Vault;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 
-@JsonPropertyOrder(value = {"directories", "checkForUpdatesEnabled"})
+@JsonPropertyOrder(value = {"directories", "checkForUpdatesEnabled", "port"})
 public class Settings implements Serializable {
 
 	private static final long serialVersionUID = 7609959894417878744L;
+	public static final int MIN_PORT = 1024;
+	public static final int MAX_PORT = 65535;
+	public static final int DEFAULT_PORT = 0;
 
+	@JsonProperty("directories")
 	private List<Vault> directories;
 
+	@JsonProperty("checkForUpdatesEnabled")
 	private Boolean checkForUpdatesEnabled;
 
+	@JsonProperty("port")
+	private Integer port;
+
 	/**
 	 * Package-private constructor; use {@link SettingsProvider}.
 	 */
@@ -54,4 +63,23 @@ public class Settings implements Serializable {
 		this.checkForUpdatesEnabled = checkForUpdatesEnabled;
 	}
 
+	public void setPort(int port) {
+		if (!isPortValid(port)) {
+			throw new IllegalArgumentException("Invalid port");
+		}
+		this.port = port;
+	}
+
+	public int getPort() {
+		if (port == null || !isPortValid(port)) {
+			return DEFAULT_PORT;
+		} else {
+			return port;
+		}
+	}
+
+	private boolean isPortValid(int port) {
+		return port == DEFAULT_PORT || port >= MIN_PORT && port <= MAX_PORT;
+	}
+
 }

+ 25 - 19
main/ui/src/main/resources/fxml/settings.fxml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2014 Sebastian Stenzel
+  Copyright (c) 2016 Sebastian Stenzel
   This file is licensed under the terms of the MIT license.
   See the LICENSE.txt file for more info.
   
@@ -13,23 +13,29 @@
 <?import javafx.scene.layout.ColumnConstraints?>
 <?import javafx.scene.control.Label?>
 <?import javafx.scene.control.CheckBox?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.layout.VBox?>
 
-<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
-	<padding>
-		<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
-	</padding>
+<VBox prefWidth="400.0" alignment="TOP_CENTER" spacing="12.0" cacheShape="true" cache="true">
+	<GridPane VBox.vgrow="ALWAYS" vgap="12.0" hgap="12.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
+		<padding>
+			<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
+		</padding>
+		
+		<columnConstraints>
+			<ColumnConstraints percentWidth="38.2"/>
+			<ColumnConstraints percentWidth="61.8"/>
+		</columnConstraints>
 	
-	<columnConstraints>
-		<ColumnConstraints percentWidth="38.2"/>
-		<ColumnConstraints percentWidth="61.8"/>
-	</columnConstraints>
-
-	<children>
-		<!-- Row 0 -->
-		<Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="%settings.checkForUpdates.label" cacheShape="true" cache="true" />
-		<CheckBox GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="checkForUpdatesCheckbox" cacheShape="true" cache="true" />
-	</children>
-</GridPane>
-
-
-					
+		<children>
+			<!-- Row 0 -->
+			<Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="%settings.checkForUpdates.label" cacheShape="true" cache="true" />
+			<CheckBox GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="checkForUpdatesCheckbox" cacheShape="true" cache="true" />
+			
+			<!-- Row 1 -->
+			<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%settings.port.label" cacheShape="true" cache="true" />
+			<TextField GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="portField" cacheShape="true" cache="true" promptText="%settings.port.prompt" />
+		</children>
+	</GridPane>
+	<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />
+</VBox>			

+ 3 - 0
main/ui/src/main/resources/localization.properties

@@ -73,6 +73,9 @@ macWarnings.whitelistButton=Decrypt selected anyway
 
 # settings.fxml
 settings.checkForUpdates.label=Check for updates
+settings.port.label=WebDAV Port *
+settings.port.prompt=0 = Choose automatically
+settings.requiresRestartLabel=* Restart required
 
 # tray icon
 tray.menu.open=Open