Parcourir la source

Merge branch 'master' of https://github.com/totalvoidness/cryptomator

Sebastian Stenzel il y a 10 ans
Parent
commit
fd54393f36

+ 34 - 10
main/ui/src/main/java/org/cryptomator/ui/MainController.java

@@ -16,12 +16,15 @@ import java.util.ResourceBundle;
 import java.util.stream.Collectors;
 
 import javafx.application.Platform;
+import javafx.collections.FXCollections;
 import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
 import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
 import javafx.fxml.FXMLLoader;
 import javafx.fxml.Initializable;
 import javafx.scene.Parent;
+import javafx.scene.control.ContextMenu;
 import javafx.scene.control.ListCell;
 import javafx.scene.control.ListView;
 import javafx.scene.layout.HBox;
@@ -44,6 +47,9 @@ public class MainController implements Initializable, InitializationListener, Un
 
 	private Stage stage;
 
+	@FXML
+	private ContextMenu directoryContextMenu;
+
 	@FXML
 	private HBox rootPane;
 
@@ -58,9 +64,11 @@ public class MainController implements Initializable, InitializationListener, Un
 	@Override
 	public void initialize(URL url, ResourceBundle rb) {
 		this.rb = rb;
+
+		final ObservableList<Directory> items = FXCollections.observableList(Settings.load().getDirectories());
+		directoryList.setItems(items);
 		directoryList.setCellFactory(this::createDirecoryListCell);
 		directoryList.getSelectionModel().getSelectedItems().addListener(this::selectedDirectoryDidChange);
-		directoryList.getItems().addAll(Settings.load().getDirectories());
 	}
 
 	@FXML
@@ -70,22 +78,38 @@ public class MainController implements Initializable, InitializationListener, Un
 		if (file != null && file.canWrite()) {
 			final Directory dir = new Directory(file.toPath());
 			directoryList.getItems().add(dir);
-			Settings.load().getDirectories().clear();
-			Settings.load().getDirectories().addAll(directoryList.getItems());
 			directoryList.getSelectionModel().selectLast();
 		}
 	}
 
 	private ListCell<Directory> createDirecoryListCell(ListView<Directory> param) {
-		return new DirectoryListCell();
+		final DirectoryListCell cell = new DirectoryListCell();
+		cell.setContextMenu(directoryContextMenu);
+		return cell;
 	}
 
 	private void selectedDirectoryDidChange(ListChangeListener.Change<? extends Directory> change) {
 		final Directory selectedDir = directoryList.getSelectionModel().getSelectedItem();
-		stage.setTitle(selectedDir.getName());
-		showDirectory(selectedDir);
+		if (selectedDir == null) {
+			stage.setTitle(rb.getString("app.name"));
+			showWelcomeView();
+		} else {
+			stage.setTitle(selectedDir.getName());
+			showDirectory(selectedDir);
+		}
 	}
 
+	@FXML
+	private void didClickRemoveSelectedEntry(ActionEvent e) {
+		final Directory selectedDir = directoryList.getSelectionModel().getSelectedItem();
+		directoryList.getItems().remove(selectedDir);
+		directoryList.getSelectionModel().clearSelection();
+	}
+
+	// ****************************************
+	// Subcontroller for right panel
+	// ****************************************
+
 	private void showDirectory(Directory directory) {
 		try {
 			if (directory.isUnlocked()) {
@@ -100,10 +124,6 @@ public class MainController implements Initializable, InitializationListener, Un
 		}
 	}
 
-	// ****************************************
-	// Subcontroller for right panel
-	// ****************************************
-
 	private <T> T showView(String fxml) {
 		try {
 			final FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml), rb);
@@ -116,6 +136,10 @@ public class MainController implements Initializable, InitializationListener, Un
 		}
 	}
 
+	private void showWelcomeView() {
+		this.showView("/welcome.fxml");
+	}
+
 	private void showInitializeView(Directory directory) {
 		final InitializeController ctrl = showView("/initialize.fxml");
 		ctrl.setDirectory(directory);

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/UnlockController.java

@@ -77,7 +77,7 @@ public class UnlockController implements Initializable {
 	// ****************************************
 
 	@FXML
-	protected void didClickUnlockButton(ActionEvent event) {
+	private void didClickUnlockButton(ActionEvent event) {
 		final String masterKeyFileName = usernameBox.getValue() + Aes256Cryptor.MASTERKEY_FILE_EXT;
 		final Path masterKeyPath = directory.getPath().resolve(masterKeyFileName);
 		final CharSequence password = passwordField.getCharacters();

+ 2 - 2
main/ui/src/main/java/org/cryptomator/ui/UnlockedController.java

@@ -52,7 +52,7 @@ public class UnlockedController implements Initializable {
 	}
 
 	@FXML
-	protected void closeVault(ActionEvent event) {
+	private void didClickCloseVault(ActionEvent event) {
 		directory.unmount();
 		directory.stopServer();
 		directory.setUnlocked(false);
@@ -82,7 +82,7 @@ public class UnlockedController implements Initializable {
 
 	private class IoSamplingAnimationHandler implements EventHandler<ActionEvent> {
 
-		private static final double BYTES_TO_MEGABYTES_FACTOR = IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
+		private static final double BYTES_TO_MEGABYTES_FACTOR = 1.0 / IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
 		private final CryptorIOSampling sampler;
 		private final Series<Number, Number> decryptedBytes;
 		private final Series<Number, Number> encryptedBytes;

+ 37 - 1
main/ui/src/main/java/org/cryptomator/ui/controls/DirectoryListCell.java

@@ -1,19 +1,55 @@
 package org.cryptomator.ui.controls;
 
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.ContentDisplay;
 import javafx.scene.control.ListCell;
+import javafx.scene.control.Tooltip;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Circle;
 
 import org.cryptomator.ui.model.Directory;
 
-public class DirectoryListCell extends ListCell<Directory> {
+public class DirectoryListCell extends ListCell<Directory> implements ChangeListener<Boolean> {
+
+	// TODO: fancy graphics instead of circles ;-)
+	private final Circle statusIndicator = new Circle(3.0);
+
+	public DirectoryListCell() {
+		setGraphic(statusIndicator);
+		setGraphicTextGap(12.0);
+		setContentDisplay(ContentDisplay.LEFT);
+	}
 
 	@Override
 	protected void updateItem(Directory item, boolean empty) {
+		final Directory oldItem = super.getItem();
+		if (oldItem != null) {
+			oldItem.unlockedProperty().removeListener(this);
+		}
 		super.updateItem(item, empty);
 		if (item == null) {
 			setText(null);
+			setTooltip(null);
+			statusIndicator.setVisible(false);
 		} else {
 			setText(item.getName());
+			setTooltip(new Tooltip(item.getPath().toString()));
+			statusIndicator.setVisible(true);
+			item.unlockedProperty().addListener(this);
+			updateStatusIndicator();
 		}
 	}
 
+	@Override
+	public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+		updateStatusIndicator();
+	}
+
+	private void updateStatusIndicator() {
+		final Paint statusColor = getItem().isUnlocked() ? Color.LIME : Color.RED;
+		statusIndicator.setFill(statusColor);
+	}
+
 }

+ 11 - 3
main/ui/src/main/java/org/cryptomator/ui/model/Directory.java

@@ -5,6 +5,9 @@ import java.io.Serializable;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+
 import org.apache.commons.lang3.StringUtils;
 import org.cryptomator.crypto.Cryptor;
 import org.cryptomator.crypto.SamplingDecorator;
@@ -29,8 +32,9 @@ public class Directory implements Serializable {
 
 	private final WebDAVServer server = new WebDAVServer();
 	private final Cryptor cryptor = SamplingDecorator.decorate(new Aes256Cryptor());
+	private final ObjectProperty<Boolean> unlocked = new SimpleObjectProperty<Boolean>(this, "unlocked", Boolean.FALSE);
 	private final Path path;
-	private boolean unlocked;
+	// private boolean unlocked;
 	private String unmountCommand;
 	private final Runnable shutdownTask = new ShutdownTask();
 
@@ -103,12 +107,16 @@ public class Directory implements Serializable {
 		return cryptor;
 	}
 
-	public boolean isUnlocked() {
+	public ObjectProperty<Boolean> unlockedProperty() {
 		return unlocked;
 	}
 
+	public boolean isUnlocked() {
+		return unlocked.get();
+	}
+
 	public void setUnlocked(boolean unlocked) {
-		this.unlocked = unlocked;
+		this.unlocked.set(unlocked);
 	}
 
 	public WebDAVServer getServer() {

+ 4 - 4
main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java

@@ -18,7 +18,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.List;
 
 import org.apache.commons.lang3.SystemUtils;
 import org.cryptomator.ui.model.Directory;
@@ -54,7 +54,7 @@ public class Settings implements Serializable {
 		}
 	}
 
-	private Collection<Directory> directories;
+	private List<Directory> directories;
 	private String username;
 
 	private Settings() {
@@ -96,14 +96,14 @@ public class Settings implements Serializable {
 
 	/* Getter/Setter */
 
-	public Collection<Directory> getDirectories() {
+	public List<Directory> getDirectories() {
 		if (directories == null) {
 			directories = new ArrayList<>();
 		}
 		return directories;
 	}
 
-	public void setDirectories(Collection<Directory> directories) {
+	public void setDirectories(List<Directory> directories) {
 		this.directories = directories;
 	}
 

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

@@ -9,6 +9,11 @@
 
 app.name=Cryptomator
 
+# main.fxml
+main.directoryList.contextMenu.remove=Remove from list
+main.directoryList.contextMenu.addUser=Add user
+main.directoryList.contextMenu.changePassword=Change password
+
 
 # welcome.fxml
 welcome.welcomeLabel=Welcome to Cryptomator

+ 13 - 3
main/ui/src/main/resources/main.fxml

@@ -14,13 +14,23 @@
 <?import javafx.scene.layout.Pane?>
 <?import javafx.scene.control.ToolBar?>
 <?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ContextMenu?>
+<?import javafx.scene.control.MenuItem?>
 
 <HBox fx:id="rootPane" prefHeight="400.0" prefWidth="600.0" fx:controller="org.cryptomator.ui.MainController" xmlns:fx="http://javafx.com/fxml">
-	
+
 	<fx:define>
 		<fx:include fx:id="welcomeView" source="welcome.fxml" />
+		<ContextMenu fx:id="directoryContextMenu">
+			<items>
+				<MenuItem text="%main.directoryList.contextMenu.remove" onAction="#didClickRemoveSelectedEntry" />
+				<!-- TODO: -->
+				<MenuItem text="%main.directoryList.contextMenu.addUser" disable="true" />
+				<MenuItem text="%main.directoryList.contextMenu.changePassword" disable="true" />
+			</items>
+		</ContextMenu>
 	</fx:define>
-	
+
 	<children>
 		<VBox prefWidth="200.0">
 			<children>
@@ -34,7 +44,7 @@
 		</VBox>
 		<Pane fx:id="contentPane">
 			<children>
-				<fx:reference source="welcomeView"/>
+				<fx:reference source="welcomeView" />
 			</children>
 		</Pane>
 	</children>

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

@@ -33,7 +33,7 @@
 		<Label fx:id="messageLabel" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" />
 		
 		<!-- Row 1 -->
-		<Button text="%unlocked.button.lock" defaultButton="true" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" prefWidth="150.0" onAction="#closeVault" focusTraversable="false"/>
+		<Button text="%unlocked.button.lock" defaultButton="true" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" prefWidth="150.0" onAction="#didClickCloseVault" focusTraversable="false"/>
 		
 		<!-- Row 2 -->
 		<LineChart fx:id="ioGraph" GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" animated="false" createSymbols="false" prefHeight="300.0" legendVisible="true" legendSide="BOTTOM" verticalZeroLineVisible="false" verticalGridLinesVisible="false" horizontalGridLinesVisible="true">