Kaynağa Gözat

Fill window with first functionality

Armin Schrenk 5 ay önce
ebeveyn
işleme
3c7b0ca048

+ 93 - 0
src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesView.java

@@ -0,0 +1,93 @@
+package org.cryptomator.ui.decryptname;
+
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+
+import javax.inject.Inject;
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleListProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.text.Text;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+import java.io.File;
+import java.nio.file.Path;
+import java.time.temporal.Temporal;
+import java.util.List;
+import java.util.ResourceBundle;
+
+@DecryptNameScoped
+public class DecryptFileNamesView implements FxController {
+
+	private final ListProperty<Path> pathsToDecrypt;
+	private final StringProperty dropZoneText = new SimpleStringProperty();
+	private final ObjectProperty<FontAwesome5Icon> dropZoneIcon = new SimpleObjectProperty<>();
+	private final Stage window;
+	private final Vault vault;
+	private final ResourceBundle resourceBundle;
+
+	@FXML
+	public ListView<Path> decryptedNamesView;
+
+	@Inject
+	public DecryptFileNamesView(@DecryptNameWindow Stage window, @DecryptNameWindow Vault vault, @DecryptNameWindow List<Path> pathsToDecrypt, ResourceBundle resourceBundle) {
+		this.window = window;
+		this.vault = vault;
+		this.resourceBundle = resourceBundle;
+		this.pathsToDecrypt = new SimpleListProperty<>(FXCollections.observableArrayList(pathsToDecrypt));
+	}
+
+	@FXML
+	public void initialize() {
+		decryptedNamesView.setItems(pathsToDecrypt);
+		//decryptedNamesView.setCellFactory(this::createListCell);
+	}
+
+	@FXML
+	public void selectAndDecrypt() {
+		var fileChooser = new FileChooser();
+		fileChooser.setTitle(resourceBundle.getString("main.vaultDetail.decryptName.filePickerTitle"));
+
+		fileChooser.setInitialDirectory(vault.getPath().toFile());
+		var ciphertextNodes = fileChooser.showOpenMultipleDialog(window);
+		if (ciphertextNodes != null) {
+			pathsToDecrypt.clear();
+			pathsToDecrypt.addAll(ciphertextNodes.stream().map(File::toPath).toList());
+		}
+	}
+	//obvservable getter
+
+	public ObservableValue<String> dropZoneTextProperty() {
+		return dropZoneText;
+	}
+
+	public String getDropZoneText() {
+		return dropZoneText.get();
+	}
+
+	public ObservableValue<FontAwesome5Icon> dropZoneIconProperty() {
+		return dropZoneIcon;
+	}
+
+	public FontAwesome5Icon getDropZoneIcon() {
+		return dropZoneIcon.get();
+	}
+
+	public ObservableValue<Boolean> decryptedPathsListEmptyProperty() {
+		return pathsToDecrypt.emptyProperty();
+	}
+
+	public boolean isDecryptedPathsListEmpty() {
+		return pathsToDecrypt.isEmpty();
+	}
+
+}

+ 4 - 5
src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java

@@ -3,7 +3,6 @@ package org.cryptomator.ui.decryptname;
 import dagger.BindsInstance;
 import dagger.Lazy;
 import dagger.Subcomponent;
-import org.cryptomator.common.Nullable;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultState;
 import org.cryptomator.ui.common.FxmlFile;
@@ -14,7 +13,7 @@ import org.slf4j.LoggerFactory;
 import javax.inject.Named;
 import javafx.scene.Scene;
 import javafx.stage.Stage;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.List;
 
 @DecryptNameScoped
@@ -27,14 +26,14 @@ public interface DecryptNameComponent {
 	Stage window();
 
 	@FxmlScene(FxmlFile.DECRYPTNAMES)
-	Lazy<Scene> namesDecryptedScene();
+	Lazy<Scene> decryptNamesView();
 
 	@DecryptNameWindow
 	Vault vault();
 
 	default void showDecryptFileNameWindow() {
 		Stage s = window();
-		s.setScene(null);
+		s.setScene(decryptNamesView().get());
 		s.sizeToScene();
 		if (vault().isUnlocked()) {
 			s.show();
@@ -46,6 +45,6 @@ public interface DecryptNameComponent {
 	@Subcomponent.Factory
 	interface Factory {
 
-		DecryptNameComponent create(@BindsInstance @DecryptNameWindow Vault vault, @BindsInstance @Named("windowOwner") Stage owner, @Nullable @BindsInstance List<Paths> ciphertextPaths);
+		DecryptNameComponent create(@BindsInstance @DecryptNameWindow Vault vault, @BindsInstance @Named("windowOwner") Stage owner, @BindsInstance @DecryptNameWindow List<Path> pathsToDecrypt);
 	}
 }

+ 2 - 3
src/main/java/org/cryptomator/ui/decryptname/DecryptNameModule.java

@@ -5,7 +5,6 @@ import dagger.Module;
 import dagger.Provides;
 import dagger.multibindings.IntoMap;
 import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.common.vaults.VaultState;
 import org.cryptomator.ui.common.DefaultSceneFactory;
 import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
@@ -55,6 +54,6 @@ public abstract class DecryptNameModule {
 
 	@Binds
 	@IntoMap
-	@FxControllerKey(OverviewController.class)
-	abstract FxController bindOverviewController(OverviewController controller);
+	@FxControllerKey(DecryptFileNamesView.class)
+	abstract FxController bindOverviewController(DecryptFileNamesView controller);
 }

+ 0 - 13
src/main/java/org/cryptomator/ui/decryptname/OverviewController.java

@@ -1,13 +0,0 @@
-package org.cryptomator.ui.decryptname;
-
-import org.cryptomator.ui.common.FxController;
-
-import javax.inject.Inject;
-
-@DecryptNameScoped
-public class OverviewController implements FxController {
-
-	@Inject
-	public OverviewController() {}
-
-}

+ 50 - 42
src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java

@@ -48,7 +48,6 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Function;
-import java.util.stream.Collectors;
 
 @MainWindowScoped
 public class VaultDetailUnlockedController implements FxController {
@@ -72,7 +71,6 @@ public class VaultDetailUnlockedController implements FxController {
 	private final BooleanProperty draggingOverLocateEncrypted = new SimpleBooleanProperty();
 	private final BooleanProperty draggingOverDecryptName = new SimpleBooleanProperty();
 	private final BooleanProperty ciphertextPathsCopied = new SimpleBooleanProperty();
-	private final BooleanProperty cleartextNamesCopied = new SimpleBooleanProperty();
 
 	@FXML
 	public Button revealEncryptedDropZone;
@@ -117,7 +115,7 @@ public class VaultDetailUnlockedController implements FxController {
 		revealEncryptedDropZone.setOnDragExited(_ -> draggingOverLocateEncrypted.setValue(false));
 
 		decryptNameDropZone.setOnDragOver(e -> handleDragOver(e, draggingOverDecryptName));
-		decryptNameDropZone.setOnDragDropped(e -> handleDragDropped(e, this::getCleartextName, this::copyDecryptedNamesToClipboard));
+		decryptNameDropZone.setOnDragDropped(e -> showDecryptNameWindow(e.getDragboard().getFiles().stream().map(File::toPath).toList()));
 		decryptNameDropZone.setOnDragExited(_ -> draggingOverDecryptName.setValue(false));
 
 		EasyBind.includeWhen(revealEncryptedDropZone.getStyleClass(), ACTIVE_CLASS, draggingOverLocateEncrypted);
@@ -164,43 +162,12 @@ public class VaultDetailUnlockedController implements FxController {
 	}
 
 	@FXML
-	public void chooseEncryptedFileAndCopyNames() {
-		decryptNameWindowFactory.create(vault.get(),mainWindow, List.of()).showDecryptFileNameWindow();
-		/*
-		var fileChooser = new FileChooser();
-		fileChooser.setTitle(resourceBundle.getString("main.vaultDetail.decryptName.filePickerTitle"));
-
-		fileChooser.setInitialDirectory(vault.getValue().getPath().toFile());
-		var ciphertextNode = fileChooser.showOpenDialog(mainWindow);
-		if (ciphertextNode != null) {
-			var nodeName = getCleartextName(ciphertextNode.toPath());
-			copyDecryptedNamesToClipboard(List.of(nodeName));
-		}
-
-		 */
-	}
-
-	private void copyDecryptedNamesToClipboard(List<CipherToCleartext> mapping) {
-		if (mapping.size() == 1) {
-			Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, mapping.getFirst().cleartext));
-		} else {
-			var content = mapping.stream().map(CipherToCleartext::toString).collect(Collectors.joining("\n"));
-			Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, content));
-		}
-		cleartextNamesCopied.setValue(true);
-		CompletableFuture.delayedExecutor(2, TimeUnit.SECONDS, Platform::runLater).execute(() -> {
-			cleartextNamesCopied.set(false);
-		});
+	public void showDecryptNameWindow() {
+		showDecryptNameWindow(List.of());
 	}
 
-	@Nullable
-	private CipherToCleartext getCleartextName(Path ciphertextNode) {
-		try {
-			return new CipherToCleartext(ciphertextNode.getFileName().toString(), vault.get().getCleartextName(ciphertextNode));
-		} catch (IOException e) {
-			LOG.warn("Failed to decrypt filename for {}", ciphertextNode, e);
-			return null;
-		}
+	private void showDecryptNameWindow(List<Path> pathsToDecrypt) {
+		decryptNameWindowFactory.create(vault.get(), mainWindow, pathsToDecrypt).showDecryptFileNameWindow();
 	}
 
 	private boolean startsWithVaultAccessPoint(Path path) {
@@ -325,11 +292,52 @@ public class VaultDetailUnlockedController implements FxController {
 		return ciphertextPathsCopied.get();
 	}
 
-	public BooleanProperty cleartextNamesCopiedProperty() {
-		return cleartextNamesCopied;
+	//new stuff
+
+
+	/*
+	@Nullable
+	private CipherToCleartext getCleartextName(Path ciphertextNode) {
+		try {
+			return new CipherToCleartext(ciphertextNode.getFileName().toString(), vault.get().getCleartextName(ciphertextNode));
+		} catch (IOException e) {
+			LOG.warn("Failed to decrypt filename for {}", ciphertextNode, e);
+			return null;
+		}
 	}
 
-	public boolean isCleartextNamesCopied() {
-		return cleartextNamesCopied.get();
+	private ListCell<Path> createListCell(ListView<Path> pathListView) {
+		return new ListCell<Path>() {
+			private final HBox root;
+			private final FontAwesome5IconView icon;
+			private final Label encryptedName;
+
+			{
+				setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
+				encryptedName = new Label();
+				icon = new FontAwesome5IconView();
+				root = new HBox(icon, encryptedName);
+				root.setSpacing(6.0);
+				root.setPadding(new Insets(6));
+			}
+
+			@Override
+			protected void updateItem(Path item, boolean empty) {
+				super.updateItem(item, empty);
+
+				if (item == null || empty) {
+					setGraphic(null);
+				} else {
+					encryptedName.setText(item.toString());
+					icon.setGlyph(FontAwesome5Icon.LOCK);
+					setGraphic(root);
+					getStyleClass().add("test-list-cell");
+				}
+			}
+		};
 	}
+
+	 */
+
 }
+

+ 58 - 0
src/main/resources/css/dark_theme.css

@@ -972,4 +972,62 @@
 	-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_NORMAL;
 	-fx-background-insets: 0, 1px;
 	-fx-background-radius: 4px;
+}
+
+.test-style {
+	/*-fx-background-color: rgba(88,94,98,0.7), rgba(53,57,59,0.7) ;*/
+	-fx-background-color: CONTROL_BORDER_NORMAL, MAIN_BG;
+	-fx-background-insets: 0, 1px;
+	-fx-background-radius: 4px;
+}
+
+.test-style2 {
+	/*-fx-background-color: rgba(88,94,98,0.7), rgba(53,57,59,0.7) ;*/
+	-fx-background-color: CONTROL_BG_NORMAL;
+	-fx-background-insets: 1px;
+	-fx-background-radius: 4px;
+	-fx-border-width: 4px;
+	-fx-border-style: dashed inside;
+	-fx-border-color: CONTROL_BORDER_NORMAL;
+	-fx-border-radius: 4px;
+}
+
+.test-style2:hover {
+	/*-fx-background-color: rgba(88,94,98,0.7), rgba(53,57,59,0.7) ;*/
+	-fx-background-color: CONTROL_BG_HOVER;
+}
+
+.test-list-view {
+	-fx-background-color: CONTROL_BG_NORMAL;
+}
+
+.test-list-view:focused .list-cell:selected {
+	-fx-background-color: PRIMARY, CONTROL_BG_SELECTED;
+	-fx-background-insets: 0, 0 0 0 3px;
+}
+
+.test-list-cell:selected {
+	-fx-background-color: CONTROL_BG_SELECTED;
+}
+
+.test-list-cell .glyph-icon {
+	-fx-fill: TEXT_FILL_MUTED;
+}
+
+.test-list-cell .header-label {
+	-fx-font-family: 'Open Sans SemiBold';
+	-fx-font-size: 1.0em;
+}
+
+.test-list-cell .detail-label {
+	-fx-text-fill: TEXT_FILL_MUTED;
+	-fx-font-size: 0.8em;
+}
+
+.test-list-cell:selected .glyph-icon {
+	-fx-fill: PRIMARY;
+}
+
+.test-list-cell:selected .header-label {
+	-fx-text-fill: TEXT_FILL_HIGHLIGHTED;
 }

+ 22 - 6
src/main/resources/fxml/decryptnames.fxml

@@ -6,9 +6,25 @@
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 
-<AnchorPane xmlns="http://javafx.com/javafx"
-			xmlns:fx="http://javafx.com/fxml"
-			fx:controller="org.cryptomator.ui.decryptname.OverviewController"
-			prefHeight="400.0" prefWidth="600.0">
-
-</AnchorPane>
+<?import javafx.geometry.Insets?>
+<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<VBox xmlns="http://javafx.com/javafx"
+	  xmlns:fx="http://javafx.com/fxml"
+	  fx:controller="org.cryptomator.ui.decryptname.DecryptFileNamesView"
+	  minWidth="400"
+	  maxWidth="400"
+	  minHeight="145">
+	<padding>
+		<Insets topRightBottomLeft="24"/>
+	</padding>
+	<Label text="Decrypt File Name" styleClass="label-large"/>
+	<VBox alignment="CENTER" VBox.vgrow="ALWAYS" styleClass="test-style2" visible="${controller.decryptedPathsListEmpty}" managed="${controller.decryptedPathsListEmpty}" onMouseClicked="#selectAndDecrypt">
+		<!-- Drop or click to decrypt names of files -->
+		<Label text="${controller.dropZoneText}" contentDisplay="TOP">
+			<graphic>
+				<FontAwesome5IconView glyph="${controller.dropZoneIcon}" glyphSize="16"/>
+			</graphic>
+		</Label>
+	</VBox>
+	<ListView fx:id="decryptedNamesView" styleClass="test-list-view" VBox.vgrow="ALWAYS" visible="${!controller.decryptedPathsListEmpty}" managed="${!controller.decryptedPathsListEmpty}"/>
+</VBox>

+ 8 - 23
src/main/resources/fxml/vault_detail_unlocked.fxml

@@ -58,31 +58,16 @@
 					<Tooltip text="%main.vaultDetail.locateEncryptedFileBtn.tooltip"/>
 				</tooltip>
 			</Button>
-			<Button styleClass="drag-n-drop" text="%main.vaultDetail.encryptedPathsCopied" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseDecryptedFileAndReveal" contentDisplay="TOP" visible="${controller.ciphertextPathsCopied}" managed="${controller.ciphertextPathsCopied}">
-				<graphic>
-					<FontAwesome5IconView glyph="CHECK" glyphSize="15"/>
-				</graphic>
-			</Button>
 		</StackPane>
 		<!-- decrypt file name -->
-		<StackPane>
-			<padding>
-				<Insets topRightBottomLeft="0"/>
-			</padding>
-			<Button fx:id="decryptNameDropZone" styleClass="drag-n-drop" text="%main.vaultDetail.decryptName.buttonLabel" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseEncryptedFileAndCopyNames" contentDisplay="TOP" visible="${!controller.cleartextNamesCopied}" managed="${!controller.cleartextNamesCopied}">
-				<graphic>
-					<Text styleClass="cryptic-text" text="101010 → abc"/>
-				</graphic>
-				<tooltip>
-					<Tooltip text="%main.vaultDetail.decryptName.tooltip"/>
-				</tooltip>
-			</Button>
-			<Button styleClass="drag-n-drop" text="%main.vaultDetail.decryptName.copied" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseEncryptedFileAndCopyNames" contentDisplay="TOP" visible="${controller.cleartextNamesCopied}" managed="${controller.cleartextNamesCopied}">
-				<graphic>
-					<FontAwesome5IconView glyph="CHECK" glyphSize="15"/>
-				</graphic>
-			</Button>
-		</StackPane>
+		<Button fx:id="decryptNameDropZone" styleClass="drag-n-drop" text="%main.vaultDetail.decryptName.buttonLabel" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#showDecryptNameWindow" contentDisplay="TOP">
+			<graphic>
+				<Text styleClass="cryptic-text" text="101010 → abc"/>
+			</graphic>
+			<tooltip>
+				<Tooltip text="%main.vaultDetail.decryptName.tooltip"/>
+			</tooltip>
+		</Button>
 
 		<Region HBox.hgrow="ALWAYS"/>