浏览代码

- Fixed "return" key in unlock view
- Fixed password field focus
- Don't show unlock error messages from one vault, when switching to another vault
- Hide advanced mount options by default (preparation for things like #74)

Sebastian Stenzel 9 年之前
父节点
当前提交
1bef4e786d

+ 2 - 2
main/pom.xml

@@ -129,12 +129,12 @@
 			<dependency>
 				<groupId>com.google.dagger</groupId>
 				<artifactId>dagger</artifactId>
-				<version>2.0</version>
+				<version>2.0.1</version>
 			</dependency>
 			<dependency>
 				<groupId>com.google.dagger</groupId>
 				<artifactId>dagger-compiler</artifactId>
-				<version>2.0</version>
+				<version>2.0.1</version>
 				<scope>provided</scope>
 			</dependency>
 

+ 37 - 12
main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java

@@ -42,6 +42,7 @@ import javafx.scene.control.Hyperlink;
 import javafx.scene.control.ProgressIndicator;
 import javafx.scene.control.TextField;
 import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.GridPane;
 import javafx.scene.text.Text;
 
 public class UnlockController extends AbstractFXMLViewController {
@@ -57,6 +58,9 @@ public class UnlockController extends AbstractFXMLViewController {
 	@FXML
 	private TextField mountName;
 
+	@FXML
+	private Button advancedOptionsButton;
+
 	@FXML
 	private Button unlockButton;
 
@@ -69,6 +73,9 @@ public class UnlockController extends AbstractFXMLViewController {
 	@FXML
 	private Hyperlink downloadsPageLink;
 
+	@FXML
+	private GridPane advancedOptions;
+
 	private final ExecutorService exec;
 	private final Application app;
 
@@ -93,6 +100,17 @@ public class UnlockController extends AbstractFXMLViewController {
 		passwordField.textProperty().addListener(this::passwordFieldsDidChange);
 		mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents);
 		mountName.textProperty().addListener(this::mountNameDidChange);
+		advancedOptions.managedProperty().bind(advancedOptions.visibleProperty());
+	}
+
+	private void resetView() {
+		unlockButton.setDisable(true);
+		advancedOptions.setVisible(false);
+		advancedOptionsButton.setText(resourceBundle.getString("unlock.button.advancedOptions.show"));
+		progressIndicator.setVisible(false);
+		passwordField.clear();
+		downloadsPageLink.setVisible(false);
+		messageText.setText(null);
 	}
 
 	// ****************************************
@@ -113,6 +131,20 @@ public class UnlockController extends AbstractFXMLViewController {
 		app.getHostServices().showDocument("https://cryptomator.org/downloads/");
 	}
 
+	// ****************************************
+	// Advanced options button
+	// ****************************************
+
+	@FXML
+	private void didClickAdvancedOptionsButton(ActionEvent event) {
+		advancedOptions.setVisible(!advancedOptions.isVisible());
+		if (advancedOptions.isVisible()) {
+			advancedOptionsButton.setText(resourceBundle.getString("unlock.button.advancedOptions.hide"));
+		} else {
+			advancedOptionsButton.setText(resourceBundle.getString("unlock.button.advancedOptions.show"));
+		}
+	}
+
 	// ****************************************
 	// Unlock button
 	// ****************************************
@@ -138,23 +170,14 @@ public class UnlockController extends AbstractFXMLViewController {
 			final Future<Boolean> futureMount = exec.submit(() -> (boolean) vault.mount());
 			FXThreads.runOnMainThreadWhenFinished(exec, futureMount, this::unlockAndMountFinished);
 		} catch (IOException ex) {
-			setControlsDisabled(false);
-			progressIndicator.setVisible(false);
 			messageText.setText(resourceBundle.getString("unlock.errorMessage.decryptionFailed"));
 			LOG.error("Decryption failed for technical reasons.", ex);
 		} catch (WrongPasswordException e) {
-			setControlsDisabled(false);
-			progressIndicator.setVisible(false);
 			messageText.setText(resourceBundle.getString("unlock.errorMessage.wrongPassword"));
-			Platform.runLater(passwordField::requestFocus);
 		} catch (UnsupportedKeyLengthException ex) {
-			setControlsDisabled(false);
-			progressIndicator.setVisible(false);
 			messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedKeyLengthInstallJCE"));
 			LOG.warn("Unsupported Key-Length. Please install Oracle Java Cryptography Extension (JCE).", ex);
 		} catch (UnsupportedVaultException e) {
-			setControlsDisabled(false);
-			progressIndicator.setVisible(false);
 			downloadsPageLink.setVisible(true);
 			if (e.isVaultOlderThanSoftware()) {
 				messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
@@ -162,11 +185,12 @@ public class UnlockController extends AbstractFXMLViewController {
 				messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
 			}
 		} catch (DestroyFailedException e) {
-			setControlsDisabled(false);
-			progressIndicator.setVisible(false);
 			LOG.error("Destruction of cryptor threw an exception.", e);
 		} finally {
+			setControlsDisabled(false);
+			progressIndicator.setVisible(false);
 			passwordField.swipe();
+			Platform.runLater(passwordField::requestFocus);
 		}
 	}
 
@@ -174,6 +198,7 @@ public class UnlockController extends AbstractFXMLViewController {
 		passwordField.setDisable(disable);
 		mountName.setDisable(disable);
 		unlockButton.setDisable(disable);
+		advancedOptionsButton.setDisable(disable);
 	}
 
 	private void unlockAndMountFinished(boolean mountSuccess) {
@@ -214,9 +239,9 @@ public class UnlockController extends AbstractFXMLViewController {
 	}
 
 	public void setVault(Vault vault) {
+		this.resetView();
 		this.vault = vault;
 		this.mountName.setText(vault.getMountName());
-		this.passwordField.clear();
 	}
 
 	public UnlockListener getListener() {

+ 7 - 7
main/ui/src/main/java/org/cryptomator/ui/controls/SecPasswordField.java

@@ -16,18 +16,18 @@ import javafx.scene.control.PasswordField;
  * Compromise in security. While the text can be swiped, any access to the {@link #getText()} method will create a copy of the String in the heap.
  */
 public class SecPasswordField extends PasswordField {
-	
+
 	private static final char SWIPE_CHAR = ' ';
-	
+
 	/**
 	 * {@link #getContent()} uses a StringBuilder, which in turn is backed by a char[].
 	 * The delete operation of AbstractStringBuilder closes the gap, that forms by deleting chars, by moving up the following chars.
 	 * <br/>
 	 * Imagine the following example with <code>pass</code> being the password, <code>x</code> being the swipe char and <code>'</code> being the offset of the char array:
 	 * <ol>
-	 * 	<li>Append filling chars to the end of the password: <code>passxxxx'</code></li>
-	 * 	<li>Delete first 4 chars. Internal implementation will then copy the following chars to the position, where the deletion occured: <code>xxxx'xxxx</code></li>
-	 * 	<li>Delete first 4 chars again, as we appended 4 chars in step 1: <code>'xxxxxx</code></li>
+	 * <li>Append filling chars to the end of the password: <code>passxxxx'</code></li>
+	 * <li>Delete first 4 chars. Internal implementation will then copy the following chars to the position, where the deletion occured: <code>xxxx'xxxx</code></li>
+	 * <li>Delete first 4 chars again, as we appended 4 chars in step 1: <code>'xxxxxx</code></li>
 	 * </ol>
 	 */
 	public void swipe() {
@@ -37,8 +37,8 @@ public class SecPasswordField extends PasswordField {
 		this.getContent().insert(pwLength, new String(fillingChars), false);
 		this.getContent().delete(0, pwLength, true);
 		this.getContent().delete(0, pwLength, true);
+		// previous text has now been overwritten. still we need to update the text to trigger some property bindings:
+		this.setText("");
 	}
-	
-	
 
 }

+ 16 - 0
main/ui/src/main/resources/css/linux_theme.css

@@ -225,6 +225,22 @@
 	-fx-font-size: 0.8em;
 }
 
+/****************************************************************************
+ *																			*
+ * Separator																*
+ *																			*
+ ****************************************************************************/
+
+.separator .line {
+    -fx-border-style: solid;
+    -fx-border-width: 1px;
+    -fx-background-color: null;
+}
+
+.separator:horizontal .line {
+    -fx-border-color: COLOR_BORDER transparent transparent transparent;
+}
+
 /****************************************************************************
  *																			*
  * CheckBox																 	*

+ 16 - 0
main/ui/src/main/resources/css/mac_theme.css

@@ -291,6 +291,22 @@
     -fx-font-size: 0.8em;
 }
 
+/****************************************************************************
+ *																			*
+ * Separator																*
+ *																			*
+ ****************************************************************************/
+
+.separator .line {
+    -fx-border-style: solid;
+    -fx-border-width: 1px;
+    -fx-background-color: null;
+}
+
+.separator:horizontal .line {
+    -fx-border-color: COLOR_BORDER transparent transparent transparent;
+}
+
 /*******************************************************************************
  *                                                                             *
  * CheckBox                                                                    *

+ 16 - 0
main/ui/src/main/resources/css/win_theme.css

@@ -281,6 +281,22 @@
     -fx-font-size: 0.9em;
 }
 
+/****************************************************************************
+ *																			*
+ * Separator																*
+ *																			*
+ ****************************************************************************/
+
+.separator .line {
+    -fx-border-style: solid;
+    -fx-border-width: 1px;
+    -fx-background-color: null;
+}
+
+.separator:horizontal .line {
+    -fx-border-color: COLOR_BORDER transparent transparent transparent;
+}
+
 /*******************************************************************************
  *                                                                             *
  * CheckBox                                                                    *

+ 40 - 10
main/ui/src/main/resources/fxml/unlock.fxml

@@ -21,6 +21,8 @@
 <?import javafx.scene.text.TextFlow?>
 <?import javafx.scene.control.Hyperlink?>
 <?import javafx.scene.text.Text?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.control.Separator?>
 
 <GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
 	<padding>
@@ -36,24 +38,52 @@
 		<!-- Row 0 -->
 		<Label text="%unlock.label.password" GridPane.rowIndex="0" GridPane.columnIndex="0" />
 		<SecPasswordField fx:id="passwordField" GridPane.rowIndex="0" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" maxWidth="Infinity" />
-		
+
 		<!-- Row 1 -->
-		<Label text="%unlock.label.mountName" GridPane.rowIndex="1" GridPane.columnIndex="0" />
-		<TextField fx:id="mountName" GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" maxWidth="Infinity" />
+		<HBox GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" spacing="12.0" alignment="CENTER_RIGHT">
+			<Button fx:id="advancedOptionsButton" text="%unlock.button.advancedOptions.show" prefWidth="150.0" onAction="#didClickAdvancedOptionsButton"/>
+			<Button fx:id="unlockButton" text="%unlock.button.unlock" defaultButton="true" prefWidth="150.0" onAction="#didClickUnlockButton" disable="true"/>
+		</HBox>
 		
-		<!-- Row 2 -->
-		<Button fx:id="unlockButton" text="%unlock.button.unlock" defaultButton="true" GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" prefWidth="150.0" onAction="#didClickUnlockButton" disable="true"/>
-		
-		<!-- Row 3-->
-		<ProgressIndicator progress="-1" fx:id="progressIndicator" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" visible="false"/>
+		<!-- Row 3 -->
+		<GridPane fx:id="advancedOptions" vgap="12.0" hgap="12.0" prefWidth="400.0" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" visible="false">
+			<padding>
+				<Insets top="24.0" />
+			</padding>
+			
+			<columnConstraints>
+				<ColumnConstraints percentWidth="38.2"/>
+				<ColumnConstraints percentWidth="61.8"/>
+			</columnConstraints>
+			
+			<!-- Row 3.0 -->
+			<Separator GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" />
+			<HBox alignment="CENTER" prefWidth="400.0" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2">
+				<Label text="%unlock.label.advancedHeading" style="-fx-background-color: COLOR_BACKGROUND;">
+					<padding>
+						<Insets left="6.0" right="6.0"/>
+					</padding>
+				</Label>
+			</HBox>
+			
+			<!-- Row 3.1 -->
+			<Label text="%unlock.label.mountName" GridPane.rowIndex="1" GridPane.columnIndex="0" />
+			<TextField fx:id="mountName" GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" maxWidth="Infinity" />
+		</GridPane>
 		
 		<!-- Row 4 -->
-		<TextFlow GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" >
+		<TextFlow GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2">
+			<GridPane.margin>
+				<Insets top="24.0"/>
+			</GridPane.margin>
 			<children>
-				<Text fx:id="messageText" />
+				<Text fx:id="messageText" text="asd"/>
 				<Hyperlink fx:id="downloadsPageLink" text="%unlock.label.downloadsPageLink" visible="false" onAction="#didClickDownloadsLink" />
 			</children>
 		</TextFlow>
+		
+		<!-- Row 5-->
+		<ProgressIndicator progress="-1" fx:id="progressIndicator" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" />
 	</children>
 </GridPane>
 

+ 1 - 1
main/ui/src/main/resources/fxml/unlocked.fxml

@@ -36,7 +36,7 @@
 		
 		<!-- Row 1 -->
 		<Label fx:id="messageLabel" GridPane.rowIndex="1" GridPane.columnIndex="0" />
-		<Button text="%unlocked.button.lock" defaultButton="true" GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.halignment="RIGHT" prefWidth="150.0" onAction="#didClickCloseVault" focusTraversable="false"/>
+		<Button text="%unlocked.button.lock" GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.halignment="RIGHT" prefWidth="150.0" onAction="#didClickCloseVault" focusTraversable="false"/>
 	</children>
 </GridPane>
 

+ 3 - 0
main/ui/src/main/resources/localization.properties

@@ -31,7 +31,10 @@ initialize.button.ok=Create vault
 unlock.label.password=Password
 unlock.label.mountName=Drive name
 unlock.label.downloadsPageLink=All Cryptomator versions
+unlock.label.advancedHeading=Advanced options
 unlock.button.unlock=Unlock vault
+unlock.button.advancedOptions.show=More options
+unlock.button.advancedOptions.hide=Less options
 unlock.errorMessage.wrongPassword=Wrong password.
 unlock.errorMessage.decryptionFailed=Decryption failed.
 unlock.errorMessage.unsupportedKeyLengthInstallJCE=Decryption failed. Please install Oracle JCE Unlimited Strength Policy.