diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 90cd3c60e..1d53dad6c 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -7,26 +7,26 @@
-
-
+
+
-
+
-
+
+
-
-
-
+
+
diff --git a/.idea/runConfigurations/Cryptomator_Windows.xml b/.idea/runConfigurations/Cryptomator_Windows.xml
new file mode 100644
index 000000000..05852ad59
--- /dev/null
+++ b/.idea/runConfigurations/Cryptomator_Windows.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Cryptomator_macOS.xml b/.idea/runConfigurations/Cryptomator_macOS.xml
index 372287203..f6c166163 100644
--- a/.idea/runConfigurations/Cryptomator_macOS.xml
+++ b/.idea/runConfigurations/Cryptomator_macOS.xml
@@ -2,14 +2,8 @@
-
-
-
-
-
-
-
-
+
+
diff --git a/main/buildkit/pom.xml b/main/buildkit/pom.xml
index aadcb0778..3c0f98d47 100644
--- a/main/buildkit/pom.xml
+++ b/main/buildkit/pom.xml
@@ -4,7 +4,7 @@
org.cryptomator
main
- 1.4.6
+ 1.4.7
buildkit
pom
diff --git a/main/commons/pom.xml b/main/commons/pom.xml
index 93c86b51b..9681e58fc 100644
--- a/main/commons/pom.xml
+++ b/main/commons/pom.xml
@@ -4,7 +4,7 @@
org.cryptomator
main
- 1.4.6
+ 1.4.7
commons
Cryptomator Commons
diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java
index 2ece80909..6c0bf84ae 100644
--- a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java
+++ b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java
@@ -80,6 +80,7 @@ public class SettingsJsonAdapter extends TypeAdapter {
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
+ break;
}
}
in.endObject();
diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java
index 3f4da5c45..732b66fef 100644
--- a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java
+++ b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java
@@ -8,6 +8,16 @@
*******************************************************************************/
package org.cryptomator.common.settings;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.cryptomator.common.Environment;
+import org.cryptomator.common.LazyInitializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Singleton;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -16,8 +26,6 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
@@ -30,20 +38,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.SystemUtils;
-import org.cryptomator.common.Environment;
-import org.cryptomator.common.LazyInitializer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
@Singleton
public class SettingsProvider implements Provider {
diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java
index 996c9a358..7a3f03b39 100644
--- a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java
+++ b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java
@@ -76,6 +76,7 @@ class VaultSettingsJsonAdapter {
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
+ break;
}
}
in.endObject();
diff --git a/main/keychain/pom.xml b/main/keychain/pom.xml
index 97e710b80..457209bf5 100644
--- a/main/keychain/pom.xml
+++ b/main/keychain/pom.xml
@@ -4,7 +4,7 @@
org.cryptomator
main
- 1.4.6
+ 1.4.7
keychain
System Keychain Access
diff --git a/main/keychain/src/test/java/org/cryptomator/keychain/WindowsProtectedKeychainAccessTest.java b/main/keychain/src/test/java/org/cryptomator/keychain/WindowsProtectedKeychainAccessTest.java
index 796634f5e..aa5c2b2f4 100644
--- a/main/keychain/src/test/java/org/cryptomator/keychain/WindowsProtectedKeychainAccessTest.java
+++ b/main/keychain/src/test/java/org/cryptomator/keychain/WindowsProtectedKeychainAccessTest.java
@@ -15,19 +15,17 @@ import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
-import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.stream.Stream;
public class WindowsProtectedKeychainAccessTest {
- private Path keychainPath;
private WindowsProtectedKeychainAccess keychain;
@BeforeEach
- public void setup(@TempDir Path tempDir) throws IOException {
- keychainPath = tempDir.resolve("keychainfile.tmp");
+ public void setup(@TempDir Path tempDir) {
+ Path keychainPath = tempDir.resolve("keychainfile.tmp");
Environment env = Mockito.mock(Environment.class);
Mockito.when(env.getKeychainPath()).thenReturn(Stream.of(keychainPath));
WinFunctions winFunctions = Mockito.mock(WinFunctions.class);
@@ -40,7 +38,7 @@ public class WindowsProtectedKeychainAccessTest {
}
@Test
- public void testStoreAndLoad() throws IOException {
+ public void testStoreAndLoad() {
String storedPw1 = "topSecret";
String storedPw2 = "bottomSecret";
keychain.storePassphrase("myPassword", storedPw1);
diff --git a/main/launcher/pom.xml b/main/launcher/pom.xml
index aa501fa19..dc95631ad 100644
--- a/main/launcher/pom.xml
+++ b/main/launcher/pom.xml
@@ -4,7 +4,7 @@
org.cryptomator
main
- 1.4.6
+ 1.4.7
launcher
Cryptomator Launcher
diff --git a/main/launcher/src/main/java/org/cryptomator/launcher/Cryptomator.java b/main/launcher/src/main/java/org/cryptomator/launcher/Cryptomator.java
index 5309a80bc..8651553e3 100644
--- a/main/launcher/src/main/java/org/cryptomator/launcher/Cryptomator.java
+++ b/main/launcher/src/main/java/org/cryptomator/launcher/Cryptomator.java
@@ -6,7 +6,6 @@
package org.cryptomator.launcher;
import javafx.application.Application;
-import javafx.application.Platform;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.logging.DebugMode;
@@ -20,7 +19,6 @@ import javax.inject.Named;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.Optional;
-import java.util.concurrent.CountDownLatch;
@Singleton
public class Cryptomator {
@@ -56,14 +54,35 @@ public class Cryptomator {
private int run(String[] args) {
logConfig.init();
LOG.info("Starting Cryptomator {} on {} {} ({})", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
+ debugMode.initialize();
- if (sendArgsToRunningInstance(args)) {
- LOG.info("Found running application instance. Shutting down...");
- return 0;
+ /*
+ * Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
+ * If no external process could be reached, the args will be handled by the loopback IPC endpoint.
+ */
+ try (IpcFactory.IpcEndpoint endpoint = ipcFactory.create()) {
+ endpoint.getRemote().handleLaunchArgs(args); // if we are the server, getRemote() returns self.
+ if (endpoint.isConnectedToRemote()) {
+ LOG.info("Found running application instance. Shutting down...");
+ return 2;
+ } else {
+ LOG.debug("Did not find running application instance. Launching GUI...");
+ return runGuiApplication();
+ }
+ } catch (IOException e) {
+ LOG.error("Failed to initiate inter-process communication.", e);
+ return runGuiApplication();
}
+ }
+ /**
+ * Launches the JavaFX application and waits until shutdown is requested.
+ * @return Nonzero exit code in case of an error.
+ */
+ private int runGuiApplication() {
try {
- runGuiApplication();
+ CleanShutdownPerformer.registerShutdownHook();
+ Application.launch(MainApp.class);
LOG.info("Shutting down...");
return 0;
} catch (Throwable e) {
@@ -72,37 +91,6 @@ public class Cryptomator {
}
}
- /**
- * Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
- * If no external process could be reached, the args will be handled by the loopback IPC endpoint.
- *
- * @param args Arguments to send to the instance (if possible)
- * @return true if a different process could be reached, false otherwise.
- */
- private boolean sendArgsToRunningInstance(String[] args) {
- try (IpcFactory.IpcEndpoint endpoint = ipcFactory.create()) {
- endpoint.getRemote().handleLaunchArgs(args); // if we are the server, getRemote() returns self.
- return endpoint.isConnectedToRemote();
- } catch (IOException e) {
- LOG.error("Failed to initiate inter-process communication.", e);
- return false;
- }
- }
-
- /**
- * Launches the JavaFX application and waits until shutdown is requested.
- */
- private void runGuiApplication() {
- debugMode.initialize();
- CleanShutdownPerformer.registerShutdownHook();
- Application.launch(MainApp.class);
-// Platform.startup(() -> {
-// assert Platform.isFxApplicationThread();
-// FxApplication app = CRYPTOMATOR_COMPONENT.fxApplicationComponent().application();
-// app.start();
-// });
- }
-
// We need a separate FX Application class, until we can use the module system. See https://stackoverflow.com/q/54756176/4014509
public static class MainApp extends Application {
diff --git a/main/launcher/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java b/main/launcher/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java
index e22a85f9e..6d5c47b05 100644
--- a/main/launcher/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java
+++ b/main/launcher/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java
@@ -2,13 +2,9 @@ package org.cryptomator.launcher;
import dagger.Component;
import org.cryptomator.common.CommonsModule;
-import org.cryptomator.common.Environment;
-import org.cryptomator.logging.DebugMode;
import org.cryptomator.logging.LoggerModule;
-import javax.inject.Named;
import javax.inject.Singleton;
-import java.util.Optional;
@Singleton
@Component(modules = {CryptomatorModule.class, CommonsModule.class, LoggerModule.class})
diff --git a/main/launcher/src/main/java/org/cryptomator/launcher/FileOpenRequestHandler.java b/main/launcher/src/main/java/org/cryptomator/launcher/FileOpenRequestHandler.java
index c422b8b51..a2f9c901e 100644
--- a/main/launcher/src/main/java/org/cryptomator/launcher/FileOpenRequestHandler.java
+++ b/main/launcher/src/main/java/org/cryptomator/launcher/FileOpenRequestHandler.java
@@ -6,9 +6,15 @@
*******************************************************************************/
package org.cryptomator.launcher;
+import org.cryptomator.ui.model.AppLaunchEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
import java.awt.Desktop;
import java.awt.desktop.OpenFilesEvent;
-import java.awt.desktop.QuitStrategy;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
@@ -17,17 +23,8 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
-import java.util.function.Function;
import java.util.stream.Stream;
-import org.cryptomator.ui.model.AppLaunchEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
@Singleton
class FileOpenRequestHandler {
diff --git a/main/launcher/src/main/java/org/cryptomator/launcher/FxApplicationComponent.java b/main/launcher/src/main/java/org/cryptomator/launcher/FxApplicationComponent.java
index 701e3e546..562151f43 100644
--- a/main/launcher/src/main/java/org/cryptomator/launcher/FxApplicationComponent.java
+++ b/main/launcher/src/main/java/org/cryptomator/launcher/FxApplicationComponent.java
@@ -10,7 +10,6 @@ import dagger.Subcomponent;
import javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.common.FxApplicationScoped;
-import org.cryptomator.logging.DebugMode;
import org.cryptomator.ui.controllers.ViewControllerLoader;
import javax.inject.Named;
diff --git a/main/pom.xml b/main/pom.xml
index 08ce7861b..0b63d78e8 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -3,7 +3,7 @@
4.0.0
org.cryptomator
main
- 1.4.6
+ 1.4.7
pom
Cryptomator
@@ -25,29 +25,29 @@
1.2.1
- 1.7.0
+ 1.8.0
2.0.0
- 1.1.1
- 1.1.3
+ 1.1.2
+ 1.1.6
1.0.9
- 11.0.2
+ 12
2.6
3.8.1
1.0.3
- 27.0-jre
- 2.20
+ 27.1-jre
+ 2.22.1
2.8.5
- 1.7.25
+ 1.7.26
1.2.3
- 5.4.0
- 2.24.0
- 1.3
+ 5.4.2
+ 2.27.0
+ 2.1
@@ -212,7 +212,7 @@
org.hamcrest
- hamcrest-all
+ hamcrest
${hamcrest.version}
@@ -236,7 +236,7 @@
org.hamcrest
- hamcrest-all
+ hamcrest
test
diff --git a/main/ui/pom.xml b/main/ui/pom.xml
index 8748d94d9..9fdbe79b7 100644
--- a/main/ui/pom.xml
+++ b/main/ui/pom.xml
@@ -4,7 +4,7 @@
org.cryptomator
main
- 1.4.6
+ 1.4.7
ui
Cryptomator GUI
diff --git a/main/ui/src/main/java/org/cryptomator/ui/UiModule.java b/main/ui/src/main/java/org/cryptomator/ui/UiModule.java
index f1cbc1c00..b93c5ddae 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/UiModule.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/UiModule.java
@@ -14,7 +14,6 @@ import javafx.beans.binding.Binding;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
-import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.keychain.KeychainModule;
import org.cryptomator.ui.controllers.ViewControllerModule;
diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java
index 2965d5dbd..c72dda3dd 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java
@@ -9,27 +9,9 @@
*******************************************************************************/
package org.cryptomator.ui.controllers;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.inject.Inject;
-
-import javafx.beans.Observable;
-import org.cryptomator.cryptolib.api.InvalidPassphraseException;
-import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
-import org.cryptomator.ui.controls.SecPasswordField;
-import org.cryptomator.ui.l10n.Localization;
-import org.cryptomator.ui.model.Vault;
-import org.cryptomator.ui.util.PasswordStrengthUtil;
-import org.fxmisc.easybind.EasyBind;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import javafx.application.Application;
import javafx.application.Platform;
-import javafx.beans.binding.BooleanBinding;
+import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.event.ActionEvent;
@@ -41,6 +23,21 @@ import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
+import org.cryptomator.cryptolib.api.InvalidPassphraseException;
+import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
+import org.cryptomator.ui.controls.SecPasswordField;
+import org.cryptomator.ui.l10n.Localization;
+import org.cryptomator.ui.model.Vault;
+import org.cryptomator.ui.util.PasswordStrengthUtil;
+import org.fxmisc.easybind.EasyBind;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Objects;
+import java.util.Optional;
public class ChangePasswordController implements ViewController {
@@ -113,7 +110,7 @@ public class ChangePasswordController implements ViewController {
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
}
- private void passwordsChanged(Observable observable) {
+ private void passwordsChanged(@SuppressWarnings("unused") Observable observable) {
boolean oldPasswordEmpty = oldPasswordField.getCharacters().length() == 0;
boolean newPasswordEmpty = newPasswordField.getCharacters().length() == 0;
boolean passwordsEqual = newPasswordField.getCharacters().equals(retypePasswordField.getCharacters());
diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java
index 5e727d5f1..44ddcecd1 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java
@@ -9,16 +9,17 @@
******************************************************************************/
package org.cryptomator.ui.controllers;
-import java.io.IOException;
-import java.nio.file.FileAlreadyExistsException;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.inject.Inject;
-
+import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
-import javafx.beans.value.ObservableIntegerValue;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Region;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
@@ -27,17 +28,11 @@ import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javafx.application.Platform;
-import javafx.beans.binding.BooleanBinding;
-import javafx.beans.property.SimpleIntegerProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Parent;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.Region;
+import javax.inject.Inject;
+import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+import java.util.Objects;
+import java.util.Optional;
public class InitializeController implements ViewController {
@@ -101,7 +96,7 @@ public class InitializeController implements ViewController {
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
}
- private void passwordsChanged(Observable observable) {
+ private void passwordsChanged(@SuppressWarnings("unused") Observable observable) {
boolean passwordsEmpty = passwordField.getCharacters().length() == 0;
boolean passwordsEqual = passwordField.getCharacters().equals(retypePasswordField.getCharacters());
okButton.setDisable(passwordsEmpty || !passwordsEqual);
diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java
index f4f498938..9e435e389 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java
@@ -20,7 +20,6 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
-import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Side;
import javafx.scene.Parent;
@@ -52,11 +51,11 @@ import org.cryptomator.ui.controls.DirectoryListCell;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.AppLaunchEvent;
import org.cryptomator.ui.model.AutoUnlocker;
-import org.cryptomator.ui.model.upgrade.UpgradeStrategies;
-import org.cryptomator.ui.model.upgrade.UpgradeStrategy;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.VaultFactory;
import org.cryptomator.ui.model.VaultList;
+import org.cryptomator.ui.model.upgrade.UpgradeStrategies;
+import org.cryptomator.ui.model.upgrade.UpgradeStrategy;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.cryptomator.ui.util.Tasks;
import org.fxmisc.easybind.EasyBind;
@@ -220,12 +219,12 @@ public class MainController implements ViewController {
private void gracefulShutdown() {
vaults.filtered(Vault.NOT_LOCKED).forEach(Vault::prepareForShutdown);
if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) {
+ mainWindow.show(); // to keep the application open
ButtonType tryAgainButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.tryAgain"));
ButtonType forceShutdownButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.forceShutdown"));
Alert gracefulShutdownDialog = DialogBuilderUtil.buildGracefulShutdownDialog(
localization.getString("main.gracefulShutdown.dialog.title"), localization.getString("main.gracefulShutdown.dialog.header"), localization.getString("main.gracefulShutdown.dialog.content"),
forceShutdownButtonType, ButtonType.CANCEL, forceShutdownButtonType, tryAgainButtonType);
-
Optional choice = gracefulShutdownDialog.showAndWait();
choice.ifPresent(btnType -> {
if (tryAgainButtonType.equals(btnType)) {
@@ -233,7 +232,11 @@ public class MainController implements ViewController {
} else if (forceShutdownButtonType.equals(btnType)) {
Platform.runLater(Platform::exit);
} else {
- return;
+ if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) {
+ showUnlockedView(vaults.get(0), false); //if there are still unlocked vaults, show one of them
+ } else {
+ showUnlockView(UnlockController.State.UNLOCKING); //otherwise show any vault
+ }
}
});
} else {
@@ -271,7 +274,7 @@ public class MainController implements ViewController {
// ****************************************
@FXML
- private void didClickAddVault(ActionEvent event) {
+ private void didClickAddVault() {
if (addVaultContextMenu.isShowing()) {
addVaultContextMenu.hide();
} else {
@@ -280,7 +283,7 @@ public class MainController implements ViewController {
}
@FXML
- private void didClickCreateNewVault(ActionEvent event) {
+ private void didClickCreateNewVault() {
final FileChooser fileChooser = new FileChooser();
final File file = fileChooser.showSaveDialog(mainWindow);
if (file == null) {
@@ -313,7 +316,7 @@ public class MainController implements ViewController {
}
@FXML
- private void didClickAddExistingVaults(ActionEvent event) {
+ private void didClickAddExistingVaults() {
final FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
final List files = fileChooser.showOpenMultipleDialog(mainWindow);
@@ -356,7 +359,7 @@ public class MainController implements ViewController {
}
@FXML
- private void didClickRemoveSelectedEntry(ActionEvent e) {
+ private void didClickRemoveSelectedEntry() {
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
localization.getString("main.directoryList.remove.confirmation.title"), //
localization.getString("main.directoryList.remove.confirmation.header"), //
@@ -375,12 +378,12 @@ public class MainController implements ViewController {
}
@FXML
- private void didClickChangePassword(ActionEvent e) {
+ private void didClickChangePassword() {
showChangePasswordView();
}
@FXML
- private void didClickShowSettings(ActionEvent e) {
+ private void didClickShowSettings() {
toggleShowSettings();
}
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 70a792f37..f055573c5 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
@@ -130,7 +130,7 @@ public class SettingsController implements ViewController {
}
@FXML
- private void changePort(ActionEvent evt) {
+ private void changePort() {
assert isPortValid() : "Button must be disabled, if port is invalid.";
try {
int port = Integer.parseInt(portField.getText());
@@ -143,11 +143,8 @@ public class SettingsController implements ViewController {
private boolean isPortValid() {
try {
int port = Integer.parseInt(portField.getText());
- if (port == 0 || port >= Settings.MIN_PORT && port <= Settings.MAX_PORT) {
- return true;
- } else {
- return false;
- }
+ return port == 0 // choose port automatically
+ || port >= Settings.MIN_PORT && port <= Settings.MAX_PORT; // port within range
} catch (NumberFormatException e) {
return false;
}
@@ -159,7 +156,7 @@ public class SettingsController implements ViewController {
}
}
- private void setVisibilityGvfsElements(Observable obs, Object oldValue, Object newValue) {
+ private void setVisibilityGvfsElements(@SuppressWarnings("unused") Observable obs, @SuppressWarnings("unused")Object oldValue, Object newValue) {
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java
index a9ab0049e..3d90c689f 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java
@@ -13,7 +13,6 @@ import com.google.common.base.Strings;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
-import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Alert;
@@ -287,7 +286,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
- public void didClickDownloadsLink(ActionEvent event) {
+ public void didClickDownloadsLink() {
app.getHostServices().showDocument("https://cryptomator.org/downloads/#allVersions");
}
@@ -296,7 +295,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
- private void didClickAdvancedOptionsButton(ActionEvent event) {
+ private void didClickAdvancedOptionsButton() {
messageText.setText(null);
advancedOptions.setVisible(!advancedOptions.isVisible());
if (advancedOptions.isVisible()) {
@@ -312,7 +311,7 @@ public class UnlockController implements ViewController {
}
}
- private void mountNameDidChange(ObservableValue extends String> property, String oldValue, String newValue) {
+ private void mountNameDidChange(@SuppressWarnings("unused") ObservableValue extends String> property, @SuppressWarnings("unused")String oldValue, String newValue) {
// newValue is guaranteed to be a-z0-9_, see #filterAlphanumericKeyEvents
if (newValue.isEmpty()) {
mountName.setText(vault.getMountName());
@@ -321,7 +320,8 @@ public class UnlockController implements ViewController {
}
}
- public void didClickChooseCustomMountPoint(ActionEvent actionEvent) {
+ @FXML
+ public void didClickChooseCustomMountPoint() {
DirectoryChooser dirChooser = new DirectoryChooser();
File file = dirChooser.showDialog(mainWindow);
if (file != null) {
@@ -372,7 +372,7 @@ public class UnlockController implements ViewController {
}
}
- private void winDriveLetterDidChange(ObservableValue extends Character> property, Character oldValue, Character newValue) {
+ private void winDriveLetterDidChange(@SuppressWarnings("unused") ObservableValue extends Character> property, @SuppressWarnings("unused") Character oldValue, Character newValue) {
vault.setWinDriveLetter(newValue);
}
@@ -396,7 +396,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
- private void didClickSavePasswordCheckbox(ActionEvent event) {
+ private void didClickSavePasswordCheckbox() {
if (!savePassword.isSelected() && hasStoredPassword()) {
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
localization.getString("unlock.savePassword.delete.confirmation.title"), //
@@ -427,7 +427,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
- private void didClickUnlockButton(ActionEvent event) {
+ private void didClickUnlockButton() {
advancedOptions.setDisable(true);
advancedOptions.setVisible(false);
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.show"));
@@ -441,9 +441,10 @@ public class UnlockController implements ViewController {
keychainAccess.get().storePassphrase(vault.getId(), password);
}
}).onSuccess(() -> {
- messageText.setText(null);
+ messageText.setText("");
downloadsPageLink.setVisible(false);
listener.ifPresent(lstnr -> lstnr.didUnlock(vault));
+ passwordField.swipe();
}).onError(InvalidPassphraseException.class, e -> {
messageText.setText(localization.getString("unlock.errorMessage.wrongPassword"));
passwordField.selectAll();
@@ -473,9 +474,6 @@ public class UnlockController implements ViewController {
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).andFinally(() -> {
- if (!savePassword.isSelected()) {
- passwordField.swipe();
- }
advancedOptions.setDisable(false);
progressIndicator.setVisible(false);
progressText.setText(null);
diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java
index 3143f8c3d..3171da98f 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java
@@ -2,16 +2,12 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
- *
+ *
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.ui.controllers;
-import javax.inject.Inject;
-import java.util.Optional;
-import java.util.concurrent.ExecutorService;
-
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
@@ -42,6 +38,10 @@ import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.inject.Inject;
+import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+
import static java.lang.String.format;
public class UnlockedController implements ViewController {
@@ -49,7 +49,7 @@ public class UnlockedController implements ViewController {
private static final Logger LOG = LoggerFactory.getLogger(UnlockedController.class);
private static final int IO_SAMPLING_STEPS = 100;
- private static final double IO_SAMPLING_INTERVAL = 0.25;
+ private static final double IO_SAMPLING_INTERVAL = 0.5;
private final Localization localization;
private final ExecutorService executor;
@@ -103,7 +103,7 @@ public class UnlockedController implements ViewController {
}
@FXML
- private void didClickLockVault(ActionEvent event) {
+ private void didClickLockVault() {
regularLockVault(this::lockVaultSucceeded);
}
@@ -156,7 +156,7 @@ public class UnlockedController implements ViewController {
}
@FXML
- private void didClickMoreOptions(ActionEvent event) {
+ private void didClickMoreOptions() {
if (moreOptionsMenu.isShowing()) {
moreOptionsMenu.hide();
} else {
@@ -166,7 +166,7 @@ public class UnlockedController implements ViewController {
}
@FXML
- private void didClickRevealVault(ActionEvent event) {
+ private void didClickRevealVault() {
revealVault(vault.get());
}
@@ -211,43 +211,42 @@ public class UnlockedController implements ViewController {
private class IoSamplingAnimationHandler implements EventHandler {
private static final double BYTES_TO_MEGABYTES_FACTOR = 1.0 / IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
- private static final double SMOOTHING_FACTOR = 0.3;
- private static final long EFFECTIVELY_ZERO = 100000; // 100kb
private final Series decryptedBytes;
private final Series encryptedBytes;
- private int step = 0;
- private long oldDecBytes = 0;
- private long oldEncBytes = 0;
public IoSamplingAnimationHandler(Series decryptedBytes, Series encryptedBytes) {
this.decryptedBytes = decryptedBytes;
this.encryptedBytes = encryptedBytes;
+
+ // initialize data once and change value of datapoints later:
+ for (int i = 0; i < IO_SAMPLING_STEPS; i++) {
+ decryptedBytes.getData().add(new Data<>(i, 0));
+ encryptedBytes.getData().add(new Data<>(i, 0));
+ }
+
+ xAxis.setLowerBound(0);
+ xAxis.setUpperBound(IO_SAMPLING_STEPS);
}
@Override
public void handle(ActionEvent event) {
- step++;
+ // move all values one step:
+ for (int i = 0; i < IO_SAMPLING_STEPS - 1; i++) {
+ int j = i + 1;
+ Number tmp = decryptedBytes.getData().get(j).getYValue();
+ decryptedBytes.getData().get(i).setYValue(tmp);
+ tmp = encryptedBytes.getData().get(j).getYValue();
+ encryptedBytes.getData().get(i).setYValue(tmp);
+ }
+
+ // add latest value:
final long decBytes = vault.get().pollBytesRead();
- final double smoothedDecBytes = oldDecBytes + SMOOTHING_FACTOR * (decBytes - oldDecBytes);
- final double smoothedDecMb = smoothedDecBytes * BYTES_TO_MEGABYTES_FACTOR;
- oldDecBytes = smoothedDecBytes > EFFECTIVELY_ZERO ? (long) smoothedDecBytes : 0l;
- decryptedBytes.getData().add(new Data(step, smoothedDecMb));
- if (decryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
- decryptedBytes.getData().remove(0);
- }
-
+ final double decMb = decBytes * BYTES_TO_MEGABYTES_FACTOR;
final long encBytes = vault.get().pollBytesWritten();
- final double smoothedEncBytes = oldEncBytes + SMOOTHING_FACTOR * (encBytes - oldEncBytes);
- final double smoothedEncMb = smoothedEncBytes * BYTES_TO_MEGABYTES_FACTOR;
- oldEncBytes = smoothedEncBytes > EFFECTIVELY_ZERO ? (long) smoothedEncBytes : 0l;
- encryptedBytes.getData().add(new Data(step, smoothedEncMb));
- if (encryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
- encryptedBytes.getData().remove(0);
- }
-
- xAxis.setLowerBound(step - IO_SAMPLING_STEPS);
- xAxis.setUpperBound(step);
+ final double encMb = encBytes * BYTES_TO_MEGABYTES_FACTOR;
+ decryptedBytes.getData().get(IO_SAMPLING_STEPS - 1).setYValue(decMb);
+ encryptedBytes.getData().get(IO_SAMPLING_STEPS - 1).setYValue(encMb);
}
}
@@ -269,6 +268,7 @@ public class UnlockedController implements ViewController {
@FunctionalInterface
interface LockListener {
+
void didLock(UnlockedController ctrl);
}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java b/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java
index b2eb7cf0f..fcd69493d 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/FuseVolume.java
@@ -16,7 +16,6 @@ import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
-import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
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 acaa33fdf..bd48150fc 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
@@ -18,7 +18,6 @@ import javafx.beans.property.SimpleObjectProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.LazyInitializer;
-import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
@@ -52,9 +51,7 @@ public class Vault {
public static final Predicate NOT_LOCKED = hasState(State.LOCKED).negate();
private static final Logger LOG = LoggerFactory.getLogger(Vault.class);
private static final String MASTERKEY_FILENAME = "masterkey.cryptomator";
- private static final String LOCALHOST_ALIAS = "cryptomator-vault";
- private final Settings settings;
private final VaultSettings vaultSettings;
private final Provider volumeProvider;
private final AtomicReference cryptoFileSystem = new AtomicReference<>();
@@ -67,8 +64,7 @@ public class Vault {
}
@Inject
- Vault(Settings settings, VaultSettings vaultSettings, Provider volumeProvider) {
- this.settings = settings;
+ Vault(VaultSettings vaultSettings, Provider volumeProvider) {
this.vaultSettings = vaultSettings;
this.volumeProvider = volumeProvider;
}
diff --git a/main/ui/src/main/resources/fxml/unlocked.fxml b/main/ui/src/main/resources/fxml/unlocked.fxml
index d87db5000..7d83369cb 100644
--- a/main/ui/src/main/resources/fxml/unlocked.fxml
+++ b/main/ui/src/main/resources/fxml/unlocked.fxml
@@ -7,22 +7,17 @@
Contributors:
Sebastian Stenzel - initial API and implementation
-->
-
-
-
+
-
-
-
-
+
+
-
-
+
-
+