diff --git a/main/frontend-api/src/main/java/org/cryptomator/frontend/Frontend.java b/main/frontend-api/src/main/java/org/cryptomator/frontend/Frontend.java index 2be80c778..25d0290ca 100644 --- a/main/frontend-api/src/main/java/org/cryptomator/frontend/Frontend.java +++ b/main/frontend-api/src/main/java/org/cryptomator/frontend/Frontend.java @@ -14,7 +14,12 @@ import java.util.Optional; public interface Frontend extends AutoCloseable { public enum MountParam { - MOUNT_NAME, HOSTNAME, WIN_DRIVE_LETTER + MOUNT_NAME, HOSTNAME, WIN_DRIVE_LETTER, + + /** + * "dav" or "webdav" + */ + PREFERRED_GVFS_SCHEME } void mount(Map> map) throws CommandFailedException; diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavFrontend.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavFrontend.java index 87ca8abee..50081c846 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavFrontend.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavFrontend.java @@ -45,7 +45,7 @@ class WebDavFrontend implements Frontend { @Override public void mount(Map> mountParams) throws CommandFailedException { - mount = webdavMounterProvider.get().mount(uri, mountParams); + mount = webdavMounterProvider.chooseMounter(mountParams).mount(uri, mountParams); } @Override diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavModule.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavModule.java new file mode 100644 index 000000000..7603d867e --- /dev/null +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavModule.java @@ -0,0 +1,11 @@ +package org.cryptomator.frontend.webdav; + +import org.cryptomator.common.CommonsModule; +import org.cryptomator.frontend.webdav.mount.WebDavMounterModule; + +import dagger.Module; + +@Module(includes = {CommonsModule.class, WebDavMounterModule.class}) +public class WebDavModule { + +} diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/FallbackWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/FallbackWebDavMounter.java index 7d83f10af..a05d19bd1 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/FallbackWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/FallbackWebDavMounter.java @@ -23,7 +23,7 @@ import org.cryptomator.frontend.Frontend.MountParam; final class FallbackWebDavMounter implements WebDavMounterStrategy { @Override - public boolean shouldWork() { + public boolean shouldWork(Map> mountParams) { return true; } diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsDavMounter.java new file mode 100644 index 000000000..d8c5224f6 --- /dev/null +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsDavMounter.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Sebastian Stenzel, Markus Kreusch + * This file is licensed under the terms of the MIT license. + * See the LICENSE.txt file for more info. + * + * Contributors: + * Sebastian Stenzel - initial API and implementation + * Markus Kreusch - Refactored WebDavMounter to use strategy pattern + * Mohit Raju - Added fallback schema-name "webdav" when opening file managers + ******************************************************************************/ +package org.cryptomator.frontend.webdav.mount; + +import java.net.URI; +import java.util.Map; +import java.util.Optional; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.frontend.CommandFailedException; +import org.cryptomator.frontend.Frontend.MountParam; +import org.cryptomator.frontend.webdav.mount.command.Script; + +@Singleton +final class LinuxGvfsDavMounter implements WebDavMounterStrategy { + + @Inject + LinuxGvfsDavMounter() { + } + + @Override + public boolean shouldWork(Map> mountParams) { + if (SystemUtils.IS_OS_LINUX) { + Optional prefScheme = mountParams.getOrDefault(MountParam.PREFERRED_GVFS_SCHEME, Optional.empty()); + boolean prefSchemeIsUnspecifiedOrDav = !prefScheme.isPresent() || prefScheme.get().equalsIgnoreCase("dav"); + final Script checkScripts = Script.fromLines("which gvfs-mount xdg-open"); + try { + checkScripts.execute(); + return prefSchemeIsUnspecifiedOrDav; + } catch (CommandFailedException e) { + return false; + } + } else { + return false; + } + } + + @Override + public void warmUp(int serverPort) { + // no-op + } + + @Override + public WebDavMount mount(URI uri, Map> mountParams) throws CommandFailedException { + final Script mountScript = Script.fromLines("set -x", "gvfs-mount \"dav:$DAV_SSP\"").addEnv("DAV_SSP", uri.getRawSchemeSpecificPart()); + mountScript.execute(); + return new LinuxGvfsDavMount(uri); + } + + private static class LinuxGvfsDavMount extends AbstractWebDavMount { + private final URI webDavUri; + private final Script testMountStillExistsScript; + private final Script unmountScript; + + private LinuxGvfsDavMount(URI webDavUri) { + this.webDavUri = webDavUri; + this.testMountStillExistsScript = Script.fromLines("set -x", "test `gvfs-mount --list | grep \"$DAV_SSP\" | wc -l` -eq 1").addEnv("DAV_SSP", webDavUri.getRawSchemeSpecificPart()); + this.unmountScript = Script.fromLines("set -x", "gvfs-mount -u \"dav:$DAV_SSP\"").addEnv("DAV_SSP", webDavUri.getRawSchemeSpecificPart()); + } + + @Override + public void unmount() throws CommandFailedException { + boolean mountStillExists; + try { + testMountStillExistsScript.execute(); + mountStillExists = true; + } catch (CommandFailedException e) { + mountStillExists = false; + } + // only attempt unmount if user didn't unmount manually: + if (mountStillExists) { + unmountScript.execute(); + } + } + + @Override + public void reveal() throws CommandFailedException { + Script.fromLines("set -x", "xdg-open \"webdav:$DAV_SSP\"").addEnv("DAV_SSP", webDavUri.getRawSchemeSpecificPart()).execute(); + } + + } + +} diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsWebDavMounter.java index 1feab0d2d..cbeffd5b2 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/LinuxGvfsWebDavMounter.java @@ -30,12 +30,14 @@ final class LinuxGvfsWebDavMounter implements WebDavMounterStrategy { } @Override - public boolean shouldWork() { + public boolean shouldWork(Map> mountParams) { if (SystemUtils.IS_OS_LINUX) { + Optional prefScheme = mountParams.getOrDefault(MountParam.PREFERRED_GVFS_SCHEME, Optional.empty()); + boolean prefSchemeIsUnspecifiedOrWebDav = !prefScheme.isPresent() || prefScheme.get().equalsIgnoreCase("webdav"); final Script checkScripts = Script.fromLines("which gvfs-mount xdg-open"); try { checkScripts.execute(); - return true; + return prefSchemeIsUnspecifiedOrWebDav; } catch (CommandFailedException e) { return false; } @@ -84,15 +86,7 @@ final class LinuxGvfsWebDavMounter implements WebDavMounterStrategy { @Override public void reveal() throws CommandFailedException { - try { - openMountWithWebdavUri("dav:" + webDavUri.getRawSchemeSpecificPart()).execute(); - } catch (CommandFailedException exception) { - openMountWithWebdavUri("webdav:" + webDavUri.getRawSchemeSpecificPart()).execute(); - } - } - - private Script openMountWithWebdavUri(String webdavUri) { - return Script.fromLines("set -x", "xdg-open \"$DAV_URI\"").addEnv("DAV_URI", webdavUri); + Script.fromLines("set -x", "xdg-open \"webdav:$DAV_SSP\"").addEnv("DAV_SSP", webDavUri.getRawSchemeSpecificPart()).execute(); } } diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java index f381e2e6f..0bd477541 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java @@ -38,7 +38,7 @@ final class MacOsXAppleScriptWebDavMounter implements WebDavMounterStrategy { } @Override - public boolean shouldWork() { + public boolean shouldWork(Map> mountParams) { return SystemUtils.IS_OS_MAC_OSX && semVerComparator.compare(SystemUtils.OS_VERSION, "10.10") >= 0; } diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java index 89e8a86a2..8e834821a 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java @@ -37,7 +37,7 @@ final class MacOsXShellScriptWebDavMounter implements WebDavMounterStrategy { } @Override - public boolean shouldWork() { + public boolean shouldWork(Map> mountParams) { return SystemUtils.IS_OS_MAC_OSX && semVerComparator.compare(SystemUtils.OS_VERSION, "10.10") < 0; } diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java deleted file mode 100644 index 3cd1b2a08..000000000 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Sebastian Stenzel and others. - * This file is licensed under the terms of the MIT license. - * See the LICENSE.txt file for more info. - * - * Contributors: - * Sebastian Stenzel - initial API and implementation - *******************************************************************************/ -package org.cryptomator.frontend.webdav.mount; - -import static java.util.Arrays.asList; -import static java.util.Collections.unmodifiableList; - -import java.util.Collection; -import java.util.Iterator; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -class MountStrategies implements Collection { - - private final Collection delegate; - - @Inject - MountStrategies(LinuxGvfsWebDavMounter linuxMounter, MacOsXAppleScriptWebDavMounter osxAppleScriptMounter, MacOsXShellScriptWebDavMounter osxShellScriptMounter, WindowsWebDavMounter winMounter) { - delegate = unmodifiableList(asList(linuxMounter, osxAppleScriptMounter, osxShellScriptMounter, winMounter)); - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return delegate.contains(o); - } - - @Override - public Iterator iterator() { - return delegate.iterator(); - } - - @Override - public Object[] toArray() { - return delegate.toArray(); - } - - @Override - public T[] toArray(T[] a) { - return delegate.toArray(a); - } - - @Override - public boolean add(WebDavMounterStrategy e) { - return delegate.add(e); - } - - @Override - public boolean remove(Object o) { - return delegate.remove(o); - } - - @Override - public boolean containsAll(Collection c) { - return delegate.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - return delegate.addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - return delegate.removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - return delegate.retainAll(c); - } - - @Override - public void clear() { - delegate.clear(); - } - - @Override - public boolean equals(Object o) { - return delegate.equals(o); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - -} diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterModule.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterModule.java new file mode 100644 index 000000000..c42151f40 --- /dev/null +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterModule.java @@ -0,0 +1,31 @@ +package org.cryptomator.frontend.webdav.mount; + +import java.util.Set; + +import javax.inject.Named; +import javax.inject.Singleton; + +import com.google.common.collect.Sets; + +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.ElementsIntoSet; + +@Module +public class WebDavMounterModule { + + @Provides + @ElementsIntoSet + static Set provideMounters(LinuxGvfsWebDavMounter linuxWebDavMounter, LinuxGvfsDavMounter linuxDavMounter, MacOsXAppleScriptWebDavMounter osxAppleScriptMounter, + MacOsXShellScriptWebDavMounter osxShellScriptMounter, WindowsWebDavMounter winMounter) { + return Sets.newHashSet(linuxWebDavMounter, linuxDavMounter, osxAppleScriptMounter, osxShellScriptMounter, winMounter); + } + + @Provides + @Singleton + @Named("fallback") + static WebDavMounterStrategy provideFallbackStrategy() { + return new FallbackWebDavMounter(); + } + +} diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterProvider.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterProvider.java index ae5341f9d..a1bdf1745 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterProvider.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterProvider.java @@ -10,34 +10,35 @@ package org.cryptomator.frontend.webdav.mount; import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import javax.inject.Inject; -import javax.inject.Provider; +import javax.inject.Named; import javax.inject.Singleton; +import org.cryptomator.frontend.Frontend.MountParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton -public class WebDavMounterProvider implements Provider { +public class WebDavMounterProvider { private static final Logger LOG = LoggerFactory.getLogger(WebDavMounterProvider.class); - private final WebDavMounterStrategy choosenStrategy; + private final Collection availableStrategies; + private final WebDavMounterStrategy fallbackStrategy; @Inject - public WebDavMounterProvider(MountStrategies availableStrategies) { - this.choosenStrategy = getStrategyWhichShouldWork(availableStrategies); + public WebDavMounterProvider(Set availableStrategies, @Named("fallback") WebDavMounterStrategy fallbackStrategy) { + this.availableStrategies = availableStrategies; + this.fallbackStrategy = fallbackStrategy; } - @Override - public WebDavMounter get() { - return this.choosenStrategy; - } - - private WebDavMounterStrategy getStrategyWhichShouldWork(Collection availableStrategies) { - WebDavMounterStrategy strategy = availableStrategies.stream().filter(WebDavMounterStrategy::shouldWork).findFirst().orElse(new FallbackWebDavMounter()); - LOG.info("Using {}", strategy.getClass().getSimpleName()); - return strategy; + public WebDavMounter chooseMounter(Map> mountParams) { + WebDavMounterStrategy result = availableStrategies.stream().filter(strategy -> strategy.shouldWork(mountParams)).findFirst().orElse(fallbackStrategy); + LOG.info("Using {}", result.getClass().getSimpleName()); + return result; } } diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterStrategy.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterStrategy.java index 99ec00162..ae5d6b687 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterStrategy.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WebDavMounterStrategy.java @@ -9,6 +9,11 @@ ******************************************************************************/ package org.cryptomator.frontend.webdav.mount; +import java.util.Map; +import java.util.Optional; + +import org.cryptomator.frontend.Frontend.MountParam; + /** * A strategy able to mount a webdav share and display it to the user. * @@ -19,7 +24,7 @@ interface WebDavMounterStrategy extends WebDavMounter { /** * @return {@code false} if this {@code WebDavMounterStrategy} can not work on the local machine, {@code true} if it could work */ - boolean shouldWork(); + boolean shouldWork(Map> mountParams); /** * Invoked when mounting strategy gets chosen. On some operating systems (we don't want to tell names here) mounting might be faster, diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java index ee8fd5b96..89268e864 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java @@ -61,7 +61,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { } @Override - public boolean shouldWork() { + public boolean shouldWork(Map> mountParams) { return SystemUtils.IS_OS_WINDOWS; } @@ -102,7 +102,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { mountScript.addEnv("DAV_UNC_PATH", uri.getRawPath().replace('/', '\\')); return mountScript.execute(MOUNT_TIMEOUT_SECONDS, TimeUnit.SECONDS); } - + private void addProxyOverrides(URI uri) throws IOException, CommandFailedException { try { // get existing value for ProxyOverride key from reqistry: @@ -110,7 +110,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { Process queryCmd = query.start(); String queryStdOut = IOUtils.toString(queryCmd.getInputStream(), StandardCharsets.UTF_8); int queryResult = queryCmd.waitFor(); - + // determine new value for ProxyOverride key: Set overrides = new HashSet<>(); Matcher matcher = REG_QUERY_PROXY_OVERRIDES_PATTERN.matcher(queryStdOut); @@ -122,7 +122,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { overrides.add(""); overrides.add(uri.getHost()); overrides.add(uri.getHost() + ":" + uri.getPort()); - + // set new value: String overridesStr = StringUtils.join(overrides, ';'); ProcessBuilder add = new ProcessBuilder("reg", "add", "\"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\"", "/v", "ProxyOverride", "/d", "\"" + overridesStr + "\"", "/f"); diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java b/main/frontend-webdav/src/test/java/org/cryptomator/frontend/webdav/WebDavComponent.java similarity index 86% rename from main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java rename to main/frontend-webdav/src/test/java/org/cryptomator/frontend/webdav/WebDavComponent.java index 68f1a43e7..cbeae7914 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java +++ b/main/frontend-webdav/src/test/java/org/cryptomator/frontend/webdav/WebDavComponent.java @@ -10,12 +10,10 @@ package org.cryptomator.frontend.webdav; import javax.inject.Singleton; -import org.cryptomator.common.CommonsModule; - import dagger.Component; @Singleton -@Component(modules = {CommonsModule.class}) +@Component(modules = {WebDavModule.class}) public interface WebDavComponent { WebDavServer server(); diff --git a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java index 3740b566d..457cd6d71 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java @@ -17,9 +17,8 @@ import javax.inject.Singleton; import org.cryptomator.common.CommonsModule; import org.cryptomator.crypto.engine.impl.CryptoEngineModule; import org.cryptomator.frontend.FrontendFactory; +import org.cryptomator.frontend.webdav.WebDavModule; import org.cryptomator.frontend.webdav.WebDavServer; -import org.cryptomator.frontend.webdav.mount.WebDavMounter; -import org.cryptomator.frontend.webdav.mount.WebDavMounterProvider; import org.cryptomator.ui.model.VaultObjectMapperProvider; import org.cryptomator.ui.settings.Settings; import org.cryptomator.ui.settings.SettingsProvider; @@ -32,7 +31,7 @@ import dagger.Provides; import javafx.application.Application; import javafx.stage.Stage; -@Module(includes = {CryptoEngineModule.class, CommonsModule.class}) +@Module(includes = {CryptoEngineModule.class, CommonsModule.class, WebDavModule.class}) class CryptomatorModule { private final Application application; @@ -83,12 +82,6 @@ class CryptomatorModule { return closer.closeLater(Executors.newCachedThreadPool(), ExecutorService::shutdown).get().orElseThrow(IllegalStateException::new); } - @Provides - @Singleton - WebDavMounter provideWebDavMounter(WebDavMounterProvider webDavMounterProvider) { - return webDavMounterProvider.get(); - } - @Provides @Singleton FrontendFactory provideFrontendFactory(DeferredCloser closer, WebDavServer webDavServer, Settings settings) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java index 7c1532775..34ef59b0d 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java @@ -22,6 +22,7 @@ import org.fxmisc.easybind.EasyBind; import javafx.fxml.FXML; import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.input.KeyEvent; @@ -52,6 +53,12 @@ public class SettingsController extends LocalizedFXMLViewController { @FXML private Label versionLabel; + @FXML + private Label prefGvfsSchemeLabel; + + @FXML + private ChoiceBox prefGvfsScheme; + @Override public void initialize() { checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally()); @@ -62,10 +69,16 @@ public class SettingsController extends LocalizedFXMLViewController { useIpv6Checkbox.setVisible(SystemUtils.IS_OS_WINDOWS); useIpv6Checkbox.setSelected(SystemUtils.IS_OS_WINDOWS && settings.shouldUseIpv6()); versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion().orElse("SNAPSHOT"))); + prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX); + prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX); + prefGvfsScheme.getItems().add("dav"); + prefGvfsScheme.getItems().add("webdav"); + prefGvfsScheme.setValue(settings.getPreferredGvfsScheme()); EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), this::checkForUpdateDidChange); EasyBind.subscribe(portField.textProperty(), this::portDidChange); EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), this::useIpv6DidChange); + EasyBind.subscribe(prefGvfsScheme.valueProperty(), this::prefGvfsSchemeDidChange); } @Override @@ -101,6 +114,11 @@ public class SettingsController extends LocalizedFXMLViewController { settings.save(); } + private void prefGvfsSchemeDidChange(String newValue) { + settings.setPreferredGvfsScheme(newValue); + settings.save(); + } + private void filterNumericKeyEvents(KeyEvent t) { if (t.getCharacter() == null || t.getCharacter().length() == 0) { return; diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java index d38f9152c..6868574ac 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java @@ -154,7 +154,8 @@ public class Vault implements CryptoFileSystemDelegate { return ImmutableMap.of( // MountParam.MOUNT_NAME, Optional.ofNullable(mountName), // MountParam.WIN_DRIVE_LETTER, Optional.ofNullable(CharUtils.toString(winDriveLetter)), // - MountParam.HOSTNAME, Optional.of(hostname) // + MountParam.HOSTNAME, Optional.of(hostname), // + MountParam.PREFERRED_GVFS_SCHEME, Optional.ofNullable(settings.getPreferredGvfsScheme()) // ); } diff --git a/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java b/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java index 6b00aeb41..f9323bf99 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java +++ b/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java @@ -18,7 +18,7 @@ import org.cryptomator.ui.model.Vault; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder(value = {"directories", "checkForUpdatesEnabled", "port", "useIpv6", "numTrayNotifications"}) +@JsonPropertyOrder(value = {"directories", "checkForUpdatesEnabled", "port", "useIpv6", "numTrayNotifications", "preferredGvfsScheme"}) public class Settings implements Serializable { private static final long serialVersionUID = 7609959894417878744L; @@ -27,6 +27,7 @@ public class Settings implements Serializable { public static final int DEFAULT_PORT = 42427; public static final boolean DEFAULT_USE_IPV6 = false; public static final Integer DEFAULT_NUM_TRAY_NOTIFICATIONS = 3; + public static final String DEFAULT_GVFS_SCHEME = "dav"; private final Consumer saveCmd; @@ -45,6 +46,9 @@ public class Settings implements Serializable { @JsonProperty("numTrayNotifications") private Integer numTrayNotifications; + @JsonProperty("preferredGvfsScheme") + private String preferredGvfsScheme; + /** * Package-private constructor; use {@link SettingsProvider}. */ @@ -113,4 +117,12 @@ public class Settings implements Serializable { this.numTrayNotifications = numTrayNotifications; } + public String getPreferredGvfsScheme() { + return preferredGvfsScheme == null ? DEFAULT_GVFS_SCHEME : preferredGvfsScheme; + } + + public void setPreferredGvfsScheme(String preferredGvfsScheme) { + this.preferredGvfsScheme = preferredGvfsScheme; + } + } diff --git a/main/ui/src/main/resources/css/linux_theme.css b/main/ui/src/main/resources/css/linux_theme.css index cb3c407f0..38f453feb 100644 --- a/main/ui/src/main/resources/css/linux_theme.css +++ b/main/ui/src/main/resources/css/linux_theme.css @@ -325,6 +325,32 @@ -fx-background-color: COLOR_TEXT; } +/******************************************************************************* + * * + * ChoiceBox * + * * + ******************************************************************************/ + +.choice-box { + -fx-background-color: COLOR_BORDER_DARK, COLOR_BACKGROUND; + -fx-background-insets: 0, 1; + -fx-background-radius: 0, 0; + -fx-padding: 0.1em 0.6em 0.1em 0.6em; + -fx-text-fill: COLOR_TEXT; +} + +.choice-box > .open-button > .arrow { + -fx-background-color: transparent, COLOR_TEXT; + -fx-background-insets: 0 0 -1 0, 0; + -fx-padding: 0.166667em 0.333333em 0.166667em 0.333333em; /* 2 4 2 4 */ + -fx-shape: "M 0 0 h 7 l -3.5 4 z"; +} + +.choice-box .context-menu { + -fx-background-color: COLOR_BORDER, #FFF; + -fx-background-insets: 0, 1; +} + /**************************************************************************** * * * ProgressIndicator * diff --git a/main/ui/src/main/resources/fxml/settings.fxml b/main/ui/src/main/resources/fxml/settings.fxml index 73f26630f..41f770be2 100644 --- a/main/ui/src/main/resources/fxml/settings.fxml +++ b/main/ui/src/main/resources/fxml/settings.fxml @@ -15,6 +15,7 @@ +