Browse Source

monster commit: Adding drag'n'drop functionality to add already existing vaults to cryptomator

Armin Schrenk 5 years ago
parent
commit
c6ad677e2b

+ 2 - 1
main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java

@@ -14,7 +14,8 @@ public enum FxmlFile {
 	REMOVE_VAULT("/fxml/remove_vault.fxml"), //
 	UNLOCK("/fxml/unlock2.fxml"), // TODO rename
 	UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), //
-	VAULT_OPTIONS("/fxml/vault_options.fxml");
+	VAULT_OPTIONS("/fxml/vault_options.fxml"), //
+	WRONGFILEALERT("/fxml/wrongfilealert.fxml");
 
 	private final String filename;
 

+ 51 - 1
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java

@@ -1,19 +1,27 @@
 package org.cryptomator.ui.mainwindow;
 
 import javafx.beans.binding.BooleanBinding;
+import javafx.collections.ObservableList;
 import javafx.fxml.FXML;
+import javafx.scene.input.TransferMode;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
 import javafx.stage.Stage;
+import org.cryptomator.common.settings.VaultSettings;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.common.vaults.VaultFactory;
 import org.cryptomator.ui.common.FontLoader;
 import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.fxapp.FxApplication;
 import org.cryptomator.ui.fxapp.UpdateChecker;
+import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.inject.Inject;
 import javax.inject.Named;
+import java.io.File;
 
 @MainWindowScoped
 public class MainWindowController implements FxController {
@@ -26,18 +34,26 @@ public class MainWindowController implements FxController {
 	private final boolean minimizeToSysTray;
 	private final UpdateChecker updateChecker;
 	private final BooleanBinding updateAvailable;
+	private final ObservableList<Vault> vaults;
+	private final VaultFactory vaultFactory;
+	private final WrongFileAlertComponent.Builder wrongFileAlert;
 	public HBox titleBar;
+	public VBox dragAndDropRegion;
+	public VBox dragNDropIndicator;
 	public Region resizer;
 	private double xOffset;
 	private double yOffset;
 
 	@Inject
-	public MainWindowController(@MainWindow Stage window, FxApplication application, @Named("trayMenuSupported") boolean minimizeToSysTray, UpdateChecker updateChecker) {
+	public MainWindowController(@MainWindow Stage window, FxApplication application, @Named("trayMenuSupported") boolean minimizeToSysTray, UpdateChecker updateChecker, ObservableList<Vault> vaults, VaultFactory vaultFactory, WrongFileAlertComponent.Builder wrongFileAlert) {
 		this.window = window;
 		this.application = application;
 		this.minimizeToSysTray = minimizeToSysTray;
 		this.updateChecker = updateChecker;
 		this.updateAvailable = updateChecker.latestVersionProperty().isNotNull();
+		this.vaults = vaults;
+		this.vaultFactory = vaultFactory;
+		this.wrongFileAlert = wrongFileAlert;
 	}
 
 	@FXML
@@ -58,6 +74,40 @@ public class MainWindowController implements FxController {
 			window.setHeight(event.getSceneY());
 		});
 		updateChecker.automaticallyCheckForUpdatesIfEnabled();
+		dragNDropIndicator.setVisible(false);
+		dragAndDropRegion.setOnDragOver(event -> {
+			if (event.getGestureSource() != dragAndDropRegion && event.getDragboard().hasFiles()) {
+				/* allow for both copying and moving, whatever user chooses */
+				event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+				dragNDropIndicator.setVisible(true);
+			}
+			event.consume();
+		});
+		dragAndDropRegion.setOnDragExited(event -> dragNDropIndicator.setVisible(false));
+		dragAndDropRegion.setOnDragDropped(event -> {
+			if (event.getGestureSource() != dragAndDropRegion && event.getDragboard().hasFiles()) {
+				/* allow for both copying and moving, whatever user chooses */
+				event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+				File dropped = event.getDragboard().getFiles().get(0);
+				if (dropped.getName().endsWith(".cryptomator")) {
+					addVault(dropped);
+				} else {
+					wrongFileAlert.build().showWrongFileAlertWindow();
+				}
+			}
+			event.consume();
+		});
+
+	}
+
+	private void addVault(final File dropped) {
+		if (dropped != null) {
+			VaultSettings vaultSettings = VaultSettings.withRandomId();
+			vaultSettings.path().setValue(dropped.toPath().toAbsolutePath().getParent());
+			Vault newVault = vaultFactory.get(vaultSettings);
+			vaults.add(newVault);
+			//TODO: error handling?
+		}
 	}
 
 	private void loadFont(String resourcePath) {

+ 4 - 1
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java

@@ -19,6 +19,7 @@ import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.removevault.RemoveVaultComponent;
 import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
+import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
 
 import javax.inject.Named;
 import javax.inject.Provider;
@@ -26,7 +27,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.ResourceBundle;
 
-@Module(subcomponents = {AddVaultWizardComponent.class, RemoveVaultComponent.class, VaultOptionsComponent.class})
+@Module(subcomponents = {AddVaultWizardComponent.class, RemoveVaultComponent.class, VaultOptionsComponent.class, WrongFileAlertComponent.class})
 abstract class MainWindowModule {
 
 	@Provides
@@ -88,4 +89,6 @@ abstract class MainWindowModule {
 	@FxControllerKey(VaultListCellController.class)
 	abstract FxController bindVaultListCellController(VaultListCellController controller);
 
+
+
 }

+ 14 - 0
main/ui/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlert.java

@@ -0,0 +1,14 @@
+package org.cryptomator.ui.wrongfilealert;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface WrongFileAlert {
+
+}

+ 33 - 0
main/ui/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertComponent.java

@@ -0,0 +1,33 @@
+package org.cryptomator.ui.wrongfilealert;
+
+import dagger.Lazy;
+import dagger.Subcomponent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
+
+@WrongFileAlertScoped
+@Subcomponent(modules = {WrongFileAlertModule.class})
+public interface WrongFileAlertComponent {
+
+	@WrongFileAlert
+	Stage window();
+
+	@FxmlScene(FxmlFile.WRONGFILEALERT)
+	Lazy<Scene> scene();
+
+	default void showWrongFileAlertWindow() {
+		Stage stage = window();
+		stage.setScene(scene().get());
+		stage.sizeToScene();
+		stage.show();
+	}
+
+	@Subcomponent.Builder
+	interface Builder {
+
+		WrongFileAlertComponent build();
+	}
+
+}

+ 21 - 0
main/ui/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertController.java

@@ -0,0 +1,21 @@
+package org.cryptomator.ui.wrongfilealert;
+
+import javafx.stage.Stage;
+import org.cryptomator.ui.common.FxController;
+
+import javax.inject.Inject;
+
+@WrongFileAlertScoped
+public class WrongFileAlertController implements FxController {
+
+	private final Stage window;
+
+	@Inject
+	public WrongFileAlertController(@WrongFileAlert Stage window) {
+		this.window = window;
+	}
+
+	public void close() {
+		window.close();
+	}
+}

+ 58 - 0
main/ui/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertModule.java

@@ -0,0 +1,58 @@
+package org.cryptomator.ui.wrongfilealert;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.Provides;
+import dagger.multibindings.IntoMap;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import org.cryptomator.ui.common.FXMLLoaderFactory;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.FxControllerKey;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
+
+import javax.inject.Named;
+import javax.inject.Provider;
+import java.util.Map;
+import java.util.Optional;
+import java.util.ResourceBundle;
+
+@Module
+abstract class WrongFileAlertModule {
+
+	@Provides
+	@WrongFileAlert
+	@WrongFileAlertScoped
+	static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, ResourceBundle resourceBundle) {
+		return new FXMLLoaderFactory(factories, resourceBundle);
+	}
+
+	@Provides
+	@WrongFileAlert
+	@WrongFileAlertScoped
+	static Stage provideStage(ResourceBundle resourceBundle, @Named("windowIcon") Optional<Image> windowIcon) {
+		Stage stage = new Stage();
+		stage.setTitle(resourceBundle.getString("wrongFileAlert.title"));
+		stage.setResizable(false);
+		stage.initModality(Modality.WINDOW_MODAL);
+		windowIcon.ifPresent(stage.getIcons()::add);
+		return stage;
+	}
+
+	@Provides
+	@FxmlScene(FxmlFile.WRONGFILEALERT)
+	@WrongFileAlertScoped
+	static Scene provideWrongFileAlertScene(@WrongFileAlert FXMLLoaderFactory fxmlLoaders) {
+		return fxmlLoaders.createScene("/fxml/wrongfilealert.fxml"); // TODO rename fxml file
+	}
+
+	// ------------------
+
+	@Binds
+	@IntoMap
+	@FxControllerKey(WrongFileAlertController.class)
+	abstract FxController bindWrongFileAlertController(WrongFileAlertController controller);
+}

+ 13 - 0
main/ui/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertScoped.java

@@ -0,0 +1,13 @@
+package org.cryptomator.ui.wrongfilealert;
+
+import javax.inject.Scope;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Scope
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface WrongFileAlertScoped {
+
+}

+ 8 - 0
main/ui/src/main/resources/fxml/main_window.fxml

@@ -10,8 +10,10 @@
 <?import javafx.scene.layout.StackPane?>
 <?import javafx.scene.layout.VBox?>
 <?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<?import javafx.scene.shape.Rectangle?>
 <VBox xmlns="http://javafx.com/javafx"
 	  xmlns:fx="http://javafx.com/fxml"
+	  fx:id="dragAndDropRegion"
 	  fx:controller="org.cryptomator.ui.mainwindow.MainWindowController"
 	  styleClass="main-window">
 	<HBox styleClass="title" fx:id="titleBar" alignment="CENTER" minHeight="50" maxHeight="50" VBox.vgrow="NEVER" spacing="6">
@@ -48,5 +50,11 @@
 			<fx:include source="/fxml/vault_detail.fxml" SplitPane.resizableWithParent="true"/>
 		</SplitPane>
 		<Region styleClass="resizer" StackPane.alignment="BOTTOM_RIGHT" fx:id="resizer" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity"/>
+		<VBox fx:id="dragNDropIndicator" >
+			<padding>
+				<Insets topRightBottomLeft="20"/>
+			</padding>
+			<Rectangle fill="red" stroke="black" height="200" width="200" />
+		</VBox>
 	</StackPane>
 </VBox>

+ 35 - 0
main/ui/src/main/resources/fxml/wrongfilealert.fxml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonBar?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.StackPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.shape.Circle?>
+<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<VBox xmlns="http://javafx.com/javafx"
+	  xmlns:fx="http://javafx.com/fxml"
+	  fx:controller="org.cryptomator.ui.wrongfilealert.WrongFileAlertController"
+	  maxHeight="400"
+	  maxWidth="400"
+	  minHeight="144"
+	  spacing="12">
+	<padding>
+		<Insets topRightBottomLeft="12"/>
+	</padding>
+	<children>
+		<HBox spacing="12" alignment="CENTER_LEFT" VBox.vgrow="ALWAYS">
+			<StackPane alignment="CENTER" HBox.hgrow="NEVER">
+				<Circle styleClass="glyph-icon-orange" radius="24"/>
+				<FontAwesome5IconView styleClass="glyph-icon-white" glyph="QUESTION" glyphSize="24"/>
+			</StackPane>
+			<Label text="%wrongFileAlert.information" wrapText="true" textAlignment="LEFT" HBox.hgrow="ALWAYS"/>
+		</HBox>
+
+		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
+		   <Button text="%wrongFileAlert.btn" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
+		</VBox>
+	</children>
+</VBox>

+ 5 - 0
main/ui/src/main/resources/i18n/strings.properties

@@ -121,6 +121,11 @@ main.vaultDetail.throughput.idle=idle
 main.vaultDetail.throughput.kbps=%.1f kiB/s
 main.vaultDetail.throughput.mbps=%.1f MiB/s
 
+# Wrong File Alert
+wrongFileAlert.title=Ooopsie
+wrongFileAlert.btn=Ok, understood!
+wrongFileAlert.information=TODO Wrong place
+
 # Vault Options
 vaultOptions.general=General
 vaultOptions.general.changePasswordBtn=Change Password

+ 5 - 0
main/ui/src/main/resources/i18n/strings_de.properties

@@ -121,6 +121,11 @@ main.vaultDetail.throughput.idle=idle
 main.vaultDetail.throughput.kbps=%.1f kiB/s
 main.vaultDetail.throughput.mbps=%.1f MiB/s
 
+# Wrong File Alert
+wrongFileAlert.title=Hoppala
+wrongFileAlert.btn=Ok, verstanden!
+wrongFileAlert.information=TODO Falscher Ort, gehe in den Dateimanager.
+
 # Vault Options
 vaultOptions.general=Allgemein
 vaultOptions.general.changePasswordBtn=Passwort ändern