mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-04-19 17:16:53 -04:00
allow user to specify whether to use dav:// or webdav:// scheme for Linux GVFS mounts. Fixes #307
This commit is contained in:
@@ -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<MountParam, Optional<String>> map) throws CommandFailedException;
|
||||
|
||||
@@ -45,7 +45,7 @@ class WebDavFrontend implements Frontend {
|
||||
|
||||
@Override
|
||||
public void mount(Map<MountParam, Optional<String>> mountParams) throws CommandFailedException {
|
||||
mount = webdavMounterProvider.get().mount(uri, mountParams);
|
||||
mount = webdavMounterProvider.chooseMounter(mountParams).mount(uri, mountParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import org.cryptomator.frontend.Frontend.MountParam;
|
||||
final class FallbackWebDavMounter implements WebDavMounterStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldWork() {
|
||||
public boolean shouldWork(Map<MountParam, Optional<String>> mountParams) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<MountParam, Optional<String>> mountParams) {
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
Optional<String> 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<MountParam, Optional<String>> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,12 +30,14 @@ final class LinuxGvfsWebDavMounter implements WebDavMounterStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldWork() {
|
||||
public boolean shouldWork(Map<MountParam, Optional<String>> mountParams) {
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
Optional<String> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ final class MacOsXAppleScriptWebDavMounter implements WebDavMounterStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldWork() {
|
||||
public boolean shouldWork(Map<MountParam, Optional<String>> mountParams) {
|
||||
return SystemUtils.IS_OS_MAC_OSX && semVerComparator.compare(SystemUtils.OS_VERSION, "10.10") >= 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ final class MacOsXShellScriptWebDavMounter implements WebDavMounterStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldWork() {
|
||||
public boolean shouldWork(Map<MountParam, Optional<String>> mountParams) {
|
||||
return SystemUtils.IS_OS_MAC_OSX && semVerComparator.compare(SystemUtils.OS_VERSION, "10.10") < 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<WebDavMounterStrategy> {
|
||||
|
||||
private final Collection<WebDavMounterStrategy> 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<WebDavMounterStrategy> iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> 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<? extends WebDavMounterStrategy> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<WebDavMounterStrategy> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<WebDavMounter> {
|
||||
public class WebDavMounterProvider {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WebDavMounterProvider.class);
|
||||
private final WebDavMounterStrategy choosenStrategy;
|
||||
private final Collection<WebDavMounterStrategy> availableStrategies;
|
||||
private final WebDavMounterStrategy fallbackStrategy;
|
||||
|
||||
@Inject
|
||||
public WebDavMounterProvider(MountStrategies availableStrategies) {
|
||||
this.choosenStrategy = getStrategyWhichShouldWork(availableStrategies);
|
||||
public WebDavMounterProvider(Set<WebDavMounterStrategy> availableStrategies, @Named("fallback") WebDavMounterStrategy fallbackStrategy) {
|
||||
this.availableStrategies = availableStrategies;
|
||||
this.fallbackStrategy = fallbackStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebDavMounter get() {
|
||||
return this.choosenStrategy;
|
||||
}
|
||||
|
||||
private WebDavMounterStrategy getStrategyWhichShouldWork(Collection<WebDavMounterStrategy> availableStrategies) {
|
||||
WebDavMounterStrategy strategy = availableStrategies.stream().filter(WebDavMounterStrategy::shouldWork).findFirst().orElse(new FallbackWebDavMounter());
|
||||
LOG.info("Using {}", strategy.getClass().getSimpleName());
|
||||
return strategy;
|
||||
public WebDavMounter chooseMounter(Map<MountParam, Optional<String>> mountParams) {
|
||||
WebDavMounterStrategy result = availableStrategies.stream().filter(strategy -> strategy.shouldWork(mountParams)).findFirst().orElse(fallbackStrategy);
|
||||
LOG.info("Using {}", result.getClass().getSimpleName());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<MountParam, Optional<String>> mountParams);
|
||||
|
||||
/**
|
||||
* Invoked when mounting strategy gets chosen. On some operating systems (we don't want to tell names here) mounting might be faster,
|
||||
|
||||
@@ -61,7 +61,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldWork() {
|
||||
public boolean shouldWork(Map<MountParam, Optional<String>> 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<String> overrides = new HashSet<>();
|
||||
Matcher matcher = REG_QUERY_PROXY_OVERRIDES_PATTERN.matcher(queryStdOut);
|
||||
@@ -122,7 +122,7 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy {
|
||||
overrides.add("<local>");
|
||||
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");
|
||||
|
||||
@@ -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();
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<String> 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;
|
||||
|
||||
@@ -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()) //
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Settings> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
|
||||
<VBox prefWidth="400.0" alignment="TOP_CENTER" spacing="12.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
<Label VBox.vgrow="NEVER" fx:id="versionLabel" alignment="CENTER" cacheShape="true" cache="true" />
|
||||
@@ -40,6 +41,11 @@
|
||||
<!-- Row 2 -->
|
||||
<Label GridPane.rowIndex="2" GridPane.columnIndex="0" fx:id="useIpv6Label" text="%settings.useipv6.label" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="useIpv6Checkbox" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3 -->
|
||||
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.prefGvfsScheme.label" cacheShape="true" cache="true" />
|
||||
<ChoiceBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
</children>
|
||||
</GridPane>
|
||||
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />
|
||||
|
||||
@@ -94,6 +94,7 @@ settings.checkForUpdates.label=Check for updates
|
||||
settings.port.label=WebDAV Port *
|
||||
settings.port.prompt=0 = Choose automatically
|
||||
settings.useipv6.label=Use IPv6 literal
|
||||
settings.prefGvfsScheme.label=WebDAV scheme
|
||||
settings.requiresRestartLabel=* Cryptomator needs to restart
|
||||
|
||||
# tray icon
|
||||
|
||||
Reference in New Issue
Block a user