mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-25 06:01:31 +00:00
Merge branch 'feature/issue-363' into develop
This commit is contained in:
@@ -20,6 +20,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.util.ApplicationVersion;
|
||||
import org.cryptomator.ui.util.SingleInstanceManager;
|
||||
import org.cryptomator.ui.util.SingleInstanceManager.RemoteInstance;
|
||||
import org.eclipse.jetty.util.ConcurrentHashSet;
|
||||
@@ -33,63 +34,62 @@ public class Cryptomator {
|
||||
public static final CompletableFuture<Consumer<File>> OPEN_FILE_HANDLER = new CompletableFuture<>();
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class);
|
||||
private static final Set<Runnable> SHUTDOWN_TASKS = new ConcurrentHashSet<>();
|
||||
private static final CleanShutdownPerformer CLEAN_SHUTDOWN_PERFORMER = new CleanShutdownPerformer();
|
||||
|
||||
public static void main(String[] args) {
|
||||
String cryptomatorVersion = Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion()).orElse("SNAPSHOT");
|
||||
LOG.info("Starting Cryptomator {} on {} {} ({})", cryptomatorVersion, SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
||||
LOG.info("Starting Cryptomator {} on {} {} ({})", ApplicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
||||
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
/*
|
||||
* On OSX we're in an awkward position. We need to register a handler in the main thread of this application. However, we can't
|
||||
* even pass objects to the application, so we're forced to use a static CompletableFuture for the handler, which actually opens
|
||||
* the file in the application.
|
||||
*
|
||||
* Code taken from https://github.com/axet/desktop/blob/master/src/main/java/com/github/axet/desktop/os/mac/AppleHandlers.java
|
||||
*/
|
||||
try {
|
||||
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
|
||||
final Class<?> openFilesHandlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
|
||||
final Method getApplication = applicationClass.getMethod("getApplication");
|
||||
final Object application = getApplication.invoke(null);
|
||||
final Method setOpenFileHandler = applicationClass.getMethod("setOpenFileHandler", openFilesHandlerClass);
|
||||
|
||||
final ClassLoader openFilesHandlerClassLoader = openFilesHandlerClass.getClassLoader();
|
||||
final OpenFilesHandlerClassHandler openFilesHandlerHandler = new OpenFilesHandlerClassHandler();
|
||||
final Object openFilesHandlerObject = Proxy.newProxyInstance(openFilesHandlerClassLoader, new Class<?>[] {openFilesHandlerClass}, openFilesHandlerHandler);
|
||||
|
||||
setOpenFileHandler.invoke(application, openFilesHandlerObject);
|
||||
} catch (ReflectiveOperationException | RuntimeException e) {
|
||||
// Since we're trying to call OS-specific code, we'll just have
|
||||
// to hope for the best.
|
||||
LOG.error("exception adding OSX file open handler", e);
|
||||
}
|
||||
addOsxFileOpenHandler();
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform certain things on VM termination.
|
||||
*/
|
||||
Runtime.getRuntime().addShutdownHook(CLEAN_SHUTDOWN_PERFORMER);
|
||||
new CleanShutdownPerformer().registerShutdownHook();
|
||||
|
||||
/*
|
||||
* Before starting the application, we check if there is already an instance running on this computer. If so, we send our command
|
||||
* line arguments to that instance and quit.
|
||||
*/
|
||||
final Optional<RemoteInstance> remoteInstance = SingleInstanceManager.getRemoteInstance(MainApplication.APPLICATION_KEY);
|
||||
|
||||
if (remoteInstance.isPresent()) {
|
||||
try (RemoteInstance instance = remoteInstance.get()) {
|
||||
LOG.info("An instance of Cryptomator is already running at {}.", instance.getRemotePort());
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
remoteInstance.get().sendMessage(args[i], 100);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error forwarding arguments to remote instance", e);
|
||||
}
|
||||
final Optional<RemoteInstance> runningInstance = SingleInstanceManager.getRemoteInstance(MainApplication.APPLICATION_KEY);
|
||||
if (runningInstance.isPresent()) {
|
||||
sendArgsToRunningInstance(args, runningInstance);
|
||||
} else {
|
||||
Application.launch(MainApplication.class, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addOsxFileOpenHandler() {
|
||||
/*
|
||||
* On OSX we're in an awkward position. We need to register a handler in the main thread of this application. However, we can't
|
||||
* even pass objects to the application, so we're forced to use a static CompletableFuture for the handler, which actually opens
|
||||
* the file in the application.
|
||||
*
|
||||
* Code taken from https://github.com/axet/desktop/blob/master/src/main/java/com/github/axet/desktop/os/mac/AppleHandlers.java
|
||||
*/
|
||||
try {
|
||||
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
|
||||
final Class<?> openFilesHandlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
|
||||
final Method getApplication = applicationClass.getMethod("getApplication");
|
||||
final Object application = getApplication.invoke(null);
|
||||
final Method setOpenFileHandler = applicationClass.getMethod("setOpenFileHandler", openFilesHandlerClass);
|
||||
|
||||
final ClassLoader openFilesHandlerClassLoader = openFilesHandlerClass.getClassLoader();
|
||||
final OpenFilesHandlerClassHandler openFilesHandlerHandler = new OpenFilesHandlerClassHandler();
|
||||
final Object openFilesHandlerObject = Proxy.newProxyInstance(openFilesHandlerClassLoader, new Class<?>[] {openFilesHandlerClass}, openFilesHandlerHandler);
|
||||
|
||||
setOpenFileHandler.invoke(application, openFilesHandlerObject);
|
||||
} catch (ReflectiveOperationException | RuntimeException e) {
|
||||
// Since we're trying to call OS-specific code, we'll just have
|
||||
// to hope for the best.
|
||||
LOG.error("exception adding OSX file open handler", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendArgsToRunningInstance(String[] args, final Optional<RemoteInstance> remoteInstance) {
|
||||
try (RemoteInstance instance = remoteInstance.get()) {
|
||||
LOG.info("An instance of Cryptomator is already running at {}.", instance.getRemotePort());
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
remoteInstance.get().sendMessage(args[i], 100);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error forwarding arguments to remote instance", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addShutdownTask(Runnable r) {
|
||||
SHUTDOWN_TASKS.add(r);
|
||||
}
|
||||
@@ -111,6 +111,10 @@ public class Cryptomator {
|
||||
});
|
||||
SHUTDOWN_TASKS.clear();
|
||||
}
|
||||
|
||||
public void registerShutdownHook() {
|
||||
Runtime.getRuntime().addShutdownHook(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleOpenFileRequest(File file) {
|
||||
|
||||
@@ -37,6 +37,8 @@ interface CryptomatorComponent {
|
||||
|
||||
ExitUtil exitUtil();
|
||||
|
||||
DebugMode debugMode();
|
||||
|
||||
Optional<MacFunctions> nativeMacFunctions();
|
||||
|
||||
}
|
||||
|
||||
75
main/ui/src/main/java/org/cryptomator/ui/DebugMode.java
Normal file
75
main/ui/src/main/java/org/cryptomator/ui/DebugMode.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package org.cryptomator.ui;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.LoggerContext;
|
||||
import org.apache.logging.log4j.core.config.Configuration;
|
||||
import org.apache.logging.log4j.core.config.LoggerConfig;
|
||||
import org.cryptomator.ui.settings.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class DebugMode {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DebugMode.class);
|
||||
|
||||
private static final Collection<LoggerUpgrade> LOGGER_UPGRADES = asList( //
|
||||
loggerUpgrade(ROOT_LOGGER_NAME, Level.INFO), //
|
||||
loggerUpgrade("org.cryptomator", Level.TRACE), //
|
||||
loggerUpgrade("org.eclipse.jetty.server.Server", Level.DEBUG) //
|
||||
);
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
@Inject
|
||||
public DebugMode(Settings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
if (settings.getDebugMode()) {
|
||||
enable();
|
||||
LOG.debug("Debug mode initialized");
|
||||
}
|
||||
}
|
||||
|
||||
private void enable() {
|
||||
LoggerContext context = (LoggerContext) LogManager.getContext(false);
|
||||
Configuration config = context.getConfiguration();
|
||||
LOGGER_UPGRADES.forEach(loggerUpgrade -> loggerUpgrade.execute(config));
|
||||
context.updateLoggers();
|
||||
}
|
||||
|
||||
private static LoggerUpgrade loggerUpgrade(String loggerName, Level minLevel) {
|
||||
return new LoggerUpgrade(loggerName, minLevel);
|
||||
}
|
||||
|
||||
private static class LoggerUpgrade {
|
||||
|
||||
private final Level level;
|
||||
private final String loggerName;
|
||||
|
||||
public LoggerUpgrade(String loggerName, Level minLevel) {
|
||||
this.loggerName = loggerName;
|
||||
this.level = minLevel;
|
||||
}
|
||||
|
||||
public void execute(Configuration config) {
|
||||
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
|
||||
if (loggerConfig.getLevel().isMoreSpecificThan(level)) {
|
||||
loggerConfig.setLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,18 +43,46 @@ public class MainApplication extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
LOG.info("JavaFX application started");
|
||||
final CryptomatorComponent comp;
|
||||
|
||||
CryptomatorComponent comp = createCryptomatorComponent(primaryStage);
|
||||
MainController mainCtrl = comp.mainController();
|
||||
closer = comp.deferredCloser();
|
||||
|
||||
comp.debugMode().initialize();
|
||||
|
||||
setupFXMLClassLoader();
|
||||
setupStylesheets();
|
||||
|
||||
initializeStage(primaryStage, mainCtrl);
|
||||
showWindow(primaryStage);
|
||||
|
||||
registerExitHandler(comp);
|
||||
|
||||
openFilesRequestedDuringStartup(primaryStage, mainCtrl);
|
||||
registerApplicationToProcessOpenFileRequests(primaryStage, comp, mainCtrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
try {
|
||||
comp = DaggerCryptomatorComponent.builder() //
|
||||
closer.close();
|
||||
} catch (ExecutionException e) {
|
||||
LOG.error("Error closing ressources", e);
|
||||
}
|
||||
}
|
||||
|
||||
private CryptomatorComponent createCryptomatorComponent(Stage primaryStage) {
|
||||
try {
|
||||
return DaggerCryptomatorComponent.builder() //
|
||||
.cryptomatorModule(new CryptomatorModule(this, primaryStage)) //
|
||||
.secureRandomModule(new SecureRandomModule(SecureRandom.getInstanceStrong())) //
|
||||
.build();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("Every implementation of the Java platform is required to support at least one strong SecureRandom implementation.", e);
|
||||
}
|
||||
final MainController mainCtrl = comp.mainController();
|
||||
closer = comp.deferredCloser();
|
||||
}
|
||||
|
||||
private void setupFXMLClassLoader() {
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
FXMLLoader.setDefaultClassLoader(contextClassLoader);
|
||||
Platform.runLater(() -> {
|
||||
@@ -66,35 +94,55 @@ public class MainApplication extends Application {
|
||||
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set stylesheets and initialize stage:
|
||||
private void setupStylesheets() {
|
||||
Font.loadFont(getClass().getResourceAsStream("/css/ionicons.ttf"), 12.0);
|
||||
chooseNativeStylesheet();
|
||||
}
|
||||
|
||||
private void initializeStage(Stage primaryStage, MainController mainCtrl) {
|
||||
mainCtrl.initStage(primaryStage);
|
||||
primaryStage.titleProperty().bind(mainCtrl.windowTitle());
|
||||
primaryStage.setResizable(false);
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
primaryStage.getIcons().add(new Image(MainApplication.class.getResourceAsStream("/window_icon.png")));
|
||||
}
|
||||
}
|
||||
|
||||
// show window and start observing its focus:
|
||||
private void showWindow(Stage primaryStage) {
|
||||
primaryStage.show();
|
||||
ActiveWindowStyleSupport.startObservingFocus(primaryStage);
|
||||
comp.exitUtil().initExitHandler(this::quit);
|
||||
}
|
||||
|
||||
// open files, if requested during startup:
|
||||
private void registerExitHandler(CryptomatorComponent comp) {
|
||||
comp.exitUtil().initExitHandler(this::quit);
|
||||
}
|
||||
|
||||
private void openFilesRequestedDuringStartup(Stage primaryStage, final MainController mainCtrl) {
|
||||
for (String arg : getParameters().getUnnamed()) {
|
||||
handleCommandLineArg(arg, primaryStage, mainCtrl);
|
||||
}
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(file.getAbsolutePath(), primaryStage, mainCtrl));
|
||||
}
|
||||
}
|
||||
|
||||
// register this application instance as primary application, that other instances can send open file requests to:
|
||||
private void registerApplicationToProcessOpenFileRequests(Stage primaryStage, final CryptomatorComponent comp, final MainController mainCtrl) throws IOException {
|
||||
LocalInstance cryptomatorGuiInstance = closer.closeLater(SingleInstanceManager.startLocalInstance(APPLICATION_KEY, comp.executorService()), LocalInstance::close).get().get();
|
||||
cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(arg, primaryStage, mainCtrl));
|
||||
}
|
||||
|
||||
private void chooseNativeStylesheet() {
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
|
||||
} else if (SystemUtils.IS_OS_LINUX) {
|
||||
setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
|
||||
} else if (SystemUtils.IS_OS_WINDOWS) {
|
||||
setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCommandLineArg(String arg, Stage primaryStage, MainController mainCtrl) {
|
||||
// find correct location:
|
||||
final Path path = FileSystems.getDefault().getPath(arg);
|
||||
@@ -118,16 +166,6 @@ public class MainApplication extends Application {
|
||||
});
|
||||
}
|
||||
|
||||
private void chooseNativeStylesheet() {
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
|
||||
} else if (SystemUtils.IS_OS_LINUX) {
|
||||
setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
|
||||
} else if (SystemUtils.IS_OS_WINDOWS) {
|
||||
setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void quit() {
|
||||
Platform.runLater(() -> {
|
||||
stop();
|
||||
@@ -136,13 +174,4 @@ public class MainApplication extends Application {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (ExecutionException e) {
|
||||
LOG.error("Error closing ressources", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ public class SettingsController extends LocalizedFXMLViewController {
|
||||
@FXML
|
||||
private ChoiceBox<String> prefGvfsScheme;
|
||||
|
||||
@FXML
|
||||
private CheckBox debugModeCheckbox;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally());
|
||||
@@ -74,11 +77,13 @@ public class SettingsController extends LocalizedFXMLViewController {
|
||||
prefGvfsScheme.getItems().add("dav");
|
||||
prefGvfsScheme.getItems().add("webdav");
|
||||
prefGvfsScheme.setValue(settings.getPreferredGvfsScheme());
|
||||
debugModeCheckbox.setSelected(settings.getDebugMode());
|
||||
|
||||
EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), this::checkForUpdateDidChange);
|
||||
EasyBind.subscribe(portField.textProperty(), this::portDidChange);
|
||||
EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), this::useIpv6DidChange);
|
||||
EasyBind.subscribe(prefGvfsScheme.valueProperty(), this::prefGvfsSchemeDidChange);
|
||||
EasyBind.subscribe(debugModeCheckbox.selectedProperty(), this::debugModeDidChange);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,6 +119,11 @@ public class SettingsController extends LocalizedFXMLViewController {
|
||||
settings.save();
|
||||
}
|
||||
|
||||
private void debugModeDidChange(Boolean newValue) {
|
||||
settings.setDebugMode(newValue);
|
||||
settings.save();
|
||||
}
|
||||
|
||||
private void prefGvfsSchemeDidChange(String newValue) {
|
||||
settings.setPreferredGvfsScheme(newValue);
|
||||
settings.save();
|
||||
|
||||
@@ -58,15 +58,6 @@ public class UnlockedController extends LocalizedFXMLViewController {
|
||||
private Optional<LockListener> listener = Optional.empty();
|
||||
private Timeline ioAnimation;
|
||||
|
||||
@Inject
|
||||
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, AsyncTaskService asyncTaskService) {
|
||||
super(localization);
|
||||
this.macWarningsController = macWarningsControllerProvider.get();
|
||||
this.asyncTaskService = asyncTaskService;
|
||||
|
||||
macWarningsController.vault.bind(this.vault);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private Label messageLabel;
|
||||
|
||||
@@ -85,6 +76,15 @@ public class UnlockedController extends LocalizedFXMLViewController {
|
||||
@FXML
|
||||
private MenuItem revealVaultMenuItem;
|
||||
|
||||
@Inject
|
||||
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, AsyncTaskService asyncTaskService) {
|
||||
super(localization);
|
||||
this.macWarningsController = macWarningsControllerProvider.get();
|
||||
this.asyncTaskService = asyncTaskService;
|
||||
|
||||
macWarningsController.vault.bind(this.vault);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
macWarningsController.initStage(macWarningsWindow);
|
||||
|
||||
@@ -13,7 +13,6 @@ import java.net.URL;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
@@ -29,6 +28,7 @@ import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.settings.Settings;
|
||||
import org.cryptomator.ui.util.ApplicationVersion;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -104,7 +104,7 @@ public class WelcomeController extends LocalizedFXMLViewController {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
final HttpClient client = new HttpClient();
|
||||
final HttpMethod method = new GetMethod("https://cryptomator.org/downloads/latestVersion.json");
|
||||
client.getParams().setParameter(HttpClientParams.USER_AGENT, "Cryptomator VersionChecker/" + applicationVersion().orElse("SNAPSHOT"));
|
||||
client.getParams().setParameter(HttpClientParams.USER_AGENT, "Cryptomator VersionChecker/" + ApplicationVersion.orElse("SNAPSHOT"));
|
||||
client.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
|
||||
client.getParams().setConnectionManagerTimeout(5000);
|
||||
client.executeMethod(method);
|
||||
@@ -124,10 +124,6 @@ public class WelcomeController extends LocalizedFXMLViewController {
|
||||
}).run();
|
||||
}
|
||||
|
||||
private Optional<String> applicationVersion() {
|
||||
return Optional.ofNullable(getClass().getPackage().getImplementationVersion());
|
||||
}
|
||||
|
||||
private void compareVersions(final Map<String, String> latestVersions) {
|
||||
final String latestVersion;
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
@@ -140,7 +136,7 @@ public class WelcomeController extends LocalizedFXMLViewController {
|
||||
// no version check possible on unsupported OS
|
||||
return;
|
||||
}
|
||||
final String currentVersion = applicationVersion().orElse(null);
|
||||
final String currentVersion = ApplicationVersion.orElse(null);
|
||||
LOG.debug("Current version: {}, lastest version: {}", currentVersion, latestVersion);
|
||||
if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) {
|
||||
final String msg = String.format(localization.getString("welcome.newVersionMessage"), latestVersion, currentVersion);
|
||||
|
||||
@@ -28,6 +28,7 @@ public class Settings implements Serializable {
|
||||
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";
|
||||
public static final boolean DEFAULT_DEBUG_MODE = false;
|
||||
|
||||
private final Consumer<Settings> saveCmd;
|
||||
|
||||
@@ -49,6 +50,9 @@ public class Settings implements Serializable {
|
||||
@JsonProperty("preferredGvfsScheme")
|
||||
private String preferredGvfsScheme;
|
||||
|
||||
@JsonProperty("debugMode")
|
||||
private Boolean debugMode;
|
||||
|
||||
/**
|
||||
* Package-private constructor; use {@link SettingsProvider}.
|
||||
*/
|
||||
@@ -125,4 +129,12 @@ public class Settings implements Serializable {
|
||||
this.preferredGvfsScheme = preferredGvfsScheme;
|
||||
}
|
||||
|
||||
public boolean getDebugMode() {
|
||||
return debugMode == null ? DEFAULT_DEBUG_MODE : debugMode;
|
||||
}
|
||||
|
||||
public void setDebugMode(boolean debugMode) {
|
||||
this.debugMode = debugMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.ui.Cryptomator;
|
||||
|
||||
public class ApplicationVersion {
|
||||
|
||||
public static String orElse(String other) {
|
||||
return get().orElse(other);
|
||||
}
|
||||
|
||||
public static Optional<String> get() {
|
||||
return Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,6 +46,10 @@
|
||||
<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" />
|
||||
|
||||
<!-- Row 4 -->
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" fx:id="debugModeLabel" text="%settings.debugMode.label" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="debugModeCheckbox" cacheShape="true" cache="true" />
|
||||
|
||||
</children>
|
||||
</GridPane>
|
||||
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />
|
||||
|
||||
@@ -66,6 +66,7 @@ settings.checkForUpdates.label = Auf Updates prüfen
|
||||
settings.port.label = WebDAV Port *
|
||||
settings.port.prompt = 0 \= Automatisch wählen
|
||||
settings.useipv6.label = IPv6-Literal nutzen
|
||||
settings.debugMode.label= Debug Modus *
|
||||
settings.requiresRestartLabel = * benötigt Neustart von Cryptomator
|
||||
# tray icon
|
||||
tray.menu.open = Öffnen
|
||||
|
||||
@@ -102,6 +102,7 @@ settings.port.label=WebDAV Port *
|
||||
settings.port.prompt=0 = Choose automatically
|
||||
settings.useipv6.label=Use IPv6 literal
|
||||
settings.prefGvfsScheme.label=WebDAV scheme
|
||||
settings.debugMode.label=Debug mode *
|
||||
settings.requiresRestartLabel=* Cryptomator needs to restart
|
||||
|
||||
# tray icon
|
||||
|
||||
@@ -27,9 +27,13 @@
|
||||
</Appenders>
|
||||
|
||||
<Loggers>
|
||||
<!-- package-specific config: -->
|
||||
<Logger name="org.cryptomator" level="DEBUG" />
|
||||
<Logger name="org.eclipse.jetty.server.Server" level="DEBUG" />
|
||||
<!--
|
||||
= NOTE =
|
||||
All loggers below are set to info.
|
||||
This is required to allow changing the levels of the loggers programmatically.
|
||||
-->
|
||||
<Logger name="org.cryptomator" level="INFO" />
|
||||
<Logger name="org.eclipse.jetty.server.Server" level="INFO" />
|
||||
<Logger name="org.cryptomator.ui.model" level="INFO">
|
||||
<AppenderRef ref="UpgradeLog" />
|
||||
</Logger>
|
||||
|
||||
Reference in New Issue
Block a user