Skip to content

Commit

Permalink
- Added settings (references #88)
Browse files Browse the repository at this point in the history
- Added dependency EasyBind to UI
- Using property bindings instead of listeners in lots of places of the UI now
  • Loading branch information
overheadhunter committed Mar 1, 2016
1 parent ca92924 commit 94b8726
Show file tree
Hide file tree
Showing 21 changed files with 505 additions and 500 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ private MacWebDavMount(String volumeIdentifier) {
String activateAppleScript = String.format("tell application \"Finder\" to activate \"%s\"", volumeIdentifier);
String ejectAppleScript = String.format("tell application \"Finder\" to if \"%s\" exists then eject \"%s\"", volumeIdentifier, volumeIdentifier);

System.err.println("open: " + openAppleScript + "\nactivate: " + activateAppleScript + "\neject: " + ejectAppleScript);

this.revealCommand = new ProcessBuilder("/usr/bin/osascript", "-e", openAppleScript, "-e", activateAppleScript);
this.unmountCommand = new ProcessBuilder("/usr/bin/osascript", "-e", ejectAppleScript);
}
Expand Down
7 changes: 7 additions & 0 deletions main/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@
<artifactId>commons-httpclient</artifactId>
<version>${commons-httpclient.version}</version>
</dependency>

<!-- EasyBind -->
<dependency>
<groupId>org.fxmisc.easybind</groupId>
<artifactId>easybind</artifactId>
<version>1.0.3</version>
</dependency>

<!-- Guava -->
<dependency>
Expand Down
6 changes: 6 additions & 0 deletions main/ui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
<groupId>org.cryptomator</groupId>
<artifactId>frontend-webdav</artifactId>
</dependency>

<!-- EasyBind -->
<dependency>
<groupId>org.fxmisc.easybind</groupId>
<artifactId>easybind</artifactId>
</dependency>

<!-- JSON -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void start(final Stage primaryStage) throws IOException {
mainCtrl.initStage(primaryStage);

final ResourceBundle rb = ResourceBundle.getBundle("localization");
primaryStage.setTitle(rb.getString("app.name"));
primaryStage.titleProperty().bind(mainCtrl.windowTitle());
primaryStage.setResizable(false);
primaryStage.getIcons().add(new Image(MainApplication.class.getResourceAsStream("/window_icon.png")));
primaryStage.show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicReference;

import org.cryptomator.common.LazyInitializer;

import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
Expand All @@ -23,7 +26,7 @@
*/
abstract class AbstractFXMLViewController implements Initializable {

private Parent fxmlRoot;
private final AtomicReference<Parent> fxmlRoot = new AtomicReference<>();

/**
* URL from #initialize(URL, ResourceBundle)
Expand Down Expand Up @@ -80,16 +83,15 @@ protected FXMLLoader createFxmlLoader() {
*
* @return Parent view element.
*/
protected final synchronized Parent loadFxml() {
if (fxmlRoot == null) {
protected final Parent loadFxml() {
return LazyInitializer.initializeLazily(fxmlRoot, () -> {
final FXMLLoader loader = createFxmlLoader();
try {
fxmlRoot = loader.load();
return loader.load();
} catch (IOException e) {
throw new IllegalStateException("Could not load FXML file from location: " + loader.getLocation(), e);
}
}
return fxmlRoot;
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.cryptomator.ui.controllers;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
Expand All @@ -17,14 +18,17 @@
import javax.inject.Singleton;

import org.cryptomator.crypto.engine.InvalidPassphraseException;
import org.cryptomator.crypto.engine.UnsupportedVaultFormatException;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.model.Vault;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
Expand All @@ -36,8 +40,14 @@ public class ChangePasswordController extends AbstractFXMLViewController {

private static final Logger LOG = LoggerFactory.getLogger(ChangePasswordController.class);

private final Application app;
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
private Optional<ChangePasswordListener> listener = Optional.empty();
private Vault vault;

@Inject
public ChangePasswordController(Application app) {
this.app = app;
}

@FXML
private SecPasswordField oldPasswordField;
Expand All @@ -57,12 +67,12 @@ public class ChangePasswordController extends AbstractFXMLViewController {
@FXML
private Hyperlink downloadsPageLink;

private final Application app;

@Inject
public ChangePasswordController(Application app) {
super();
this.app = app;
@Override
public void initialize() {
BooleanBinding oldPasswordIsEmpty = oldPasswordField.textProperty().isEmpty();
BooleanBinding newPasswordIsEmpty = newPasswordField.textProperty().isEmpty();
BooleanBinding passwordsDiffer = newPasswordField.textProperty().isNotEqualTo(retypePasswordField.textProperty());
changePasswordButton.disableProperty().bind(oldPasswordIsEmpty.or(newPasswordIsEmpty.or(passwordsDiffer)));
}

@Override
Expand All @@ -75,24 +85,6 @@ protected ResourceBundle getFxmlResourceBundle() {
return ResourceBundle.getBundle("localization");
}

@Override
public void initialize() {
oldPasswordField.textProperty().addListener(this::passwordFieldsDidChange);
newPasswordField.textProperty().addListener(this::passwordFieldsDidChange);
retypePasswordField.textProperty().addListener(this::passwordFieldsDidChange);
}

// ****************************************
// Password fields
// ****************************************

private void passwordFieldsDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
boolean oldPasswordIsEmpty = oldPasswordField.getText().isEmpty();
boolean newPasswordIsEmpty = newPasswordField.getText().isEmpty();
boolean passwordsAreEqual = newPasswordField.getText().equals(retypePasswordField.getText());
changePasswordButton.setDisable(oldPasswordIsEmpty || newPasswordIsEmpty || !passwordsAreEqual);
}

// ****************************************
// Downloads link
// ****************************************
Expand All @@ -110,31 +102,23 @@ public void didClickDownloadsLink(ActionEvent event) {
private void didClickChangePasswordButton(ActionEvent event) {
downloadsPageLink.setVisible(false);
try {
vault.changePassphrase(oldPasswordField.getCharacters(), newPasswordField.getCharacters());
vault.get().changePassphrase(oldPasswordField.getCharacters(), newPasswordField.getCharacters());
messageText.setText(resourceBundle.getString("changePassword.infoMessage.success"));
listener.ifPresent(this::invokeListenerLater);
} catch (InvalidPassphraseException e) {
messageText.setText(resourceBundle.getString("changePassword.errorMessage.wrongPassword"));
newPasswordField.swipe();
retypePasswordField.swipe();
Platform.runLater(oldPasswordField::requestFocus);
return;
} catch (IOException ex) {
} catch (UncheckedIOException | IOException ex) {
messageText.setText(resourceBundle.getString("changePassword.errorMessage.decryptionFailed"));
LOG.error("Decryption failed for technical reasons.", ex);
newPasswordField.swipe();
retypePasswordField.swipe();
return;
// } catch (UnsupportedVaultException e) {
// downloadsPageLink.setVisible(true);
// if (e.isVaultOlderThanSoftware()) {
// messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
// } else if (e.isSoftwareOlderThanVault()) {
// messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
// }
// newPasswordField.swipe();
// retypePasswordField.swipe();
// return;
} catch (UnsupportedVaultFormatException e) {
downloadsPageLink.setVisible(true);
LOG.warn("Unable to unlock vault: " + e.getMessage());
if (e.isVaultOlderThanSoftware()) {
messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
} else if (e.isSoftwareOlderThanVault()) {
messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
}
} finally {
oldPasswordField.swipe();
newPasswordField.swipe();
Expand All @@ -144,14 +128,6 @@ private void didClickChangePasswordButton(ActionEvent event) {

/* Getter/Setter */

public Vault getVault() {
return vault;
}

public void setVault(Vault vault) {
this.vault = vault;
}

public ChangePasswordListener getListener() {
return listener.orElse(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.cryptomator.ui.controllers;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.nio.file.FileAlreadyExistsException;
import java.util.Optional;
Expand All @@ -23,7 +24,9 @@
import org.slf4j.LoggerFactory;

import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
Expand All @@ -34,9 +37,13 @@ public class InitializeController extends AbstractFXMLViewController {

private static final Logger LOG = LoggerFactory.getLogger(InitializeController.class);

private Vault vault;
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
private Optional<InitializationListener> listener = Optional.empty();

@Inject
public InitializeController() {
}

@FXML
private SecPasswordField passwordField;

Expand All @@ -49,8 +56,11 @@ public class InitializeController extends AbstractFXMLViewController {
@FXML
private Label messageLabel;

@Inject
public InitializeController() {
@Override
public void initialize() {
BooleanBinding passwordIsEmpty = passwordField.textProperty().isEmpty();
BooleanBinding passwordsDiffer = passwordField.textProperty().isNotEqualTo(retypePasswordField.textProperty());
okButton.disableProperty().bind(passwordIsEmpty.or(passwordsDiffer));
}

@Override
Expand All @@ -63,60 +73,29 @@ protected ResourceBundle getFxmlResourceBundle() {
return ResourceBundle.getBundle("localization");
}

@Override
public void initialize() {
passwordField.textProperty().addListener(this::passwordFieldsDidChange);
retypePasswordField.textProperty().addListener(this::passwordFieldsDidChange);
}

// ****************************************
// Password fields
// ****************************************

private void passwordFieldsDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
boolean passwordIsEmpty = passwordField.getText().isEmpty();
boolean passwordsAreEqual = passwordField.getText().equals(retypePasswordField.getText());
okButton.setDisable(passwordIsEmpty || !passwordsAreEqual);
}

// ****************************************
// OK button
// ****************************************

@FXML
protected void initializeVault(ActionEvent event) {
setControlsDisabled(true);
final CharSequence passphrase = passwordField.getCharacters();
try {
vault.create(passphrase);
vault.get().create(passphrase);
listener.ifPresent(this::invokeListenerLater);
} catch (FileAlreadyExistsException ex) {
messageLabel.setText(resourceBundle.getString("initialize.messageLabel.alreadyInitialized"));
} catch (IOException ex) {
} catch (UncheckedIOException | IOException ex) {
LOG.error("I/O Exception", ex);
messageLabel.setText(resourceBundle.getString("initialize.messageLabel.initializationFailed"));
} finally {
setControlsDisabled(false);
passwordField.swipe();
retypePasswordField.swipe();
}
}

private void setControlsDisabled(boolean disable) {
passwordField.setDisable(disable);
retypePasswordField.setDisable(disable);
okButton.setDisable(disable);
}

/* Getter/Setter */

public Vault getVault() {
return vault;
}

public void setVault(Vault vault) {
this.vault = vault;
}

public InitializationListener getListener() {
return listener.orElse(null);
}
Expand Down
Loading

0 comments on commit 94b8726

Please sign in to comment.