mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 10:11:27 +00:00
monster commit: Adding drag'n'drop functionality to add already existing vaults to cryptomator
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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
main/ui/src/main/resources/fxml/wrongfilealert.fxml
Normal file
35
main/ui/src/main/resources/fxml/wrongfilealert.fxml
Normal file
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user