Skip to content

Commit

Permalink
Custom mount point now selected via DirectoryChooser. Fixes #762
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed Feb 8, 2019
1 parent 98cab7e commit 492e986
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 51 deletions.
Expand Up @@ -26,8 +26,12 @@
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.SystemUtils;
Expand All @@ -50,6 +54,8 @@
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Named;
import java.io.File;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.NotDirectoryException;
import java.util.Arrays;
Expand All @@ -68,6 +74,7 @@ public class UnlockController implements ViewController {
.precomputed();

private final Application app;
private final Stage mainWindow;
private final Localization localization;
private final WindowsDriveLetters driveLetters;
private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
Expand All @@ -79,8 +86,9 @@ public class UnlockController implements ViewController {
private Subscription vaultSubs = Subscription.EMPTY;

@Inject
public UnlockController(Application app, Localization localization, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess, Settings settings, ExecutorService executor) {
public UnlockController(Application app, @Named("mainWindow") Stage mainWindow, Localization localization, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess, Settings settings, ExecutorService executor) {
this.app = app;
this.mainWindow = mainWindow;
this.localization = localization;
this.driveLetters = driveLetters;
this.keychainAccess = keychainAccess;
Expand Down Expand Up @@ -116,13 +124,13 @@ public UnlockController(Application app, Localization localization, WindowsDrive
private ChoiceBox<Character> winDriveLetter;

@FXML
private CheckBox useCustomMountPath;
private CheckBox useCustomMountPoint;

@FXML
private Label customMountPathLabel;
private HBox customMountPoint;

@FXML
private TextField customMountPathField;
private Label customMountPointField;

@FXML
private ProgressIndicator progressIndicator;
Expand Down Expand Up @@ -151,11 +159,8 @@ public void initialize() {
savePassword.setDisable(!keychainAccess.isPresent());
unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not()));

customMountPathLabel.visibleProperty().bind(useCustomMountPath.selectedProperty());
customMountPathLabel.managedProperty().bind(useCustomMountPath.selectedProperty());
customMountPathField.visibleProperty().bind(useCustomMountPath.selectedProperty());
customMountPathField.managedProperty().bind(useCustomMountPath.selectedProperty());
customMountPathField.textProperty().addListener(this::mountPathDidChange);
customMountPoint.visibleProperty().bind(useCustomMountPoint.selectedProperty());
customMountPoint.managedProperty().bind(useCustomMountPoint.selectedProperty());
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());

if (!SystemUtils.IS_OS_WINDOWS) {
Expand All @@ -166,16 +171,17 @@ public void initialize() {
}

if (VolumeImpl.WEBDAV.equals(settings.preferredVolumeImpl().get())) {
useCustomMountPath.setVisible(false);
useCustomMountPath.setManaged(false);
customMountPathField.setMouseTransparent(true);
useCustomMountPoint.setVisible(false);
useCustomMountPoint.setManaged(false);
customMountPoint.setVisible(false);
customMountPoint.setManaged(false);
} else {
useCustomMountPath.setVisible(true);
useCustomMountPoint.setVisible(true);
if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.visibleProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetter.managedProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetterLabel.visibleProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetterLabel.managedProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetter.visibleProperty().bind(useCustomMountPoint.selectedProperty().not());
winDriveLetter.managedProperty().bind(useCustomMountPoint.selectedProperty().not());
winDriveLetterLabel.visibleProperty().bind(useCustomMountPoint.selectedProperty().not());
winDriveLetterLabel.managedProperty().bind(useCustomMountPoint.selectedProperty().not());
}
}
}
Expand Down Expand Up @@ -236,13 +242,13 @@ void setVault(Vault vault, State state) {
revealAfterMount.setSelected(vaultSettings.revealAfterMount().get());

if (!settings.preferredVolumeImpl().get().equals(VolumeImpl.WEBDAV)) {
useCustomMountPath.setSelected(vaultSettings.usesIndividualMountPath().get());
customMountPathField.textProperty().setValue(vaultSettings.individualMountPath().getValueSafe());
useCustomMountPoint.setSelected(vaultSettings.usesIndividualMountPath().get());
customMountPointField.textProperty().setValue(vaultSettings.individualMountPath().getValueSafe());
}

vaultSubs = vaultSubs.and(EasyBind.subscribe(unlockAfterStartup.selectedProperty(), vaultSettings.unlockAfterStartup()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), vaultSettings.revealAfterMount()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(useCustomMountPath.selectedProperty(), vaultSettings.usesIndividualMountPath()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(useCustomMountPoint.selectedProperty(), vaultSettings.usesIndividualMountPath()::set));

}

Expand Down Expand Up @@ -285,8 +291,13 @@ private void mountNameDidChange(ObservableValue<? extends String> property, Stri
}
}

private void mountPathDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
vault.setCustomMountPath(newValue);
public void didClickChooseCustomMountPoint(ActionEvent actionEvent) {
DirectoryChooser dirChooser = new DirectoryChooser();
File file = dirChooser.showDialog(mainWindow);
if (file != null) {
customMountPointField.setText(file.toString());
vault.setCustomMountPath(file.toString());
}
}

/**
Expand All @@ -299,7 +310,7 @@ public String toString(Character letter) {
if (letter == null) {
return localization.getString("unlock.choicebox.winDriveLetter.auto");
} else {
return Character.toString(letter) + ":";
return letter + ":";
}
}

Expand Down Expand Up @@ -417,20 +428,17 @@ private void didClickUnlockButton(ActionEvent event) {
} else if (e.getDetectedVersion() == Integer.MAX_VALUE) {
messageText.setText(localization.getString("unlock.errorMessage.unauthenticVersionMac"));
}
}).onError(ServerLifecycleException.class, e -> {
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).onError(NotDirectoryException.class, e -> {
LOG.error("Mount point not a directory.", e);
LOG.error("Unlock failed. Mount point not a directory: {}", e.getMessage());
advancedOptions.setVisible(true);
customMountPathField.setStyle("-fx-border-color: red;");
messageText.setText(null);
showUnlockFailedErrorDialog("unlock.failedDialog.content.mountPathNonExisting");
}).onError(DirectoryNotEmptyException.class, e -> {
LOG.error("Mount point not empty.", e);
LOG.error("Unlock failed. Mount point not empty: {}", e.getMessage());
advancedOptions.setVisible(true);
customMountPathField.setStyle("-fx-border-color: red;");
messageText.setText(null);
showUnlockFailedErrorDialog("unlock.failedDialog.content.mountPathNotEmpty");
}).onError(Exception.class, e -> {
}).onError(Exception.class, e -> { // including RuntimeExceptions
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).andFinally(() -> {
Expand All @@ -439,9 +447,6 @@ private void didClickUnlockButton(ActionEvent event) {
}
advancedOptions.setDisable(false);
progressIndicator.setVisible(false);
if (advancedOptions.isVisible()) { //dirty programming, but otherwise the focus is wrong
customMountPathField.requestFocus();
}
}).runOnce(executor);
}

Expand Down
33 changes: 16 additions & 17 deletions main/ui/src/main/resources/fxml/unlock.fxml
Expand Up @@ -7,23 +7,20 @@
Contributors:
Sebastian Stenzel - initial API and implementation
-->
<?import org.cryptomator.ui.controls.SecPasswordField?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.text.TextFlow?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.text.TextFlow?>
<?import org.cryptomator.ui.controls.SecPasswordField?>
<GridPane fx:controller="org.cryptomator.ui.controllers.UnlockController" fx:id="root" vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
<padding>
<Insets top="24.0" right="12.0" bottom="24.0" left="12.0" />
Expand Down Expand Up @@ -83,16 +80,18 @@
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />

<!-- Row 3.5 -->
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="useCustomMountPath" text="%unlock.label.useOwnMountPath" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="useCustomMountPoint" text="%unlock.label.useOwnMountPath" cacheShape="true" cache="true" />

<!-- Row 3.6 Alt1 -->
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="winDriveLetterLabel" text="%unlock.label.winDriveLetter" cacheShape="true" cache="true" />
<ChoiceBox GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="winDriveLetter" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />

<!-- Row 3.6 Alt2 -->
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="customMountPathLabel" text="%unlock.label.mountPath" cacheShape="true" cache="true" />
<TextField GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="customMountPathField" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />

<HBox fx:id="customMountPoint" GridPane.rowIndex="6" GridPane.columnIndex="0" GridPane.columnSpan="2" spacing="6">
<Label HBox.hgrow="NEVER" minWidth="-Infinity" text="%unlock.label.mountPath" cacheShape="true" cache="true" />
<Label HBox.hgrow="ALWAYS" fx:id="customMountPointField" textOverrun="LEADING_ELLIPSIS" cacheShape="true" cache="true" />
<Button HBox.hgrow="NEVER" minWidth="-Infinity" text="&#xf434;" styleClass="ionicons" onAction="#didClickChooseCustomMountPoint" focusTraversable="true" cacheShape="true" cache="true"/>
</HBox>
</GridPane>

<!-- Row 4 -->
Expand Down

0 comments on commit 492e986

Please sign in to comment.