diff --git a/designs/login_credentials_shard_node_icon.svg b/designs/login_credentials_shard_node_icon.svg deleted file mode 100644 index 514f0c0..0000000 --- a/designs/login_credentials_shard_node_icon.svg +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/designs/shard_node_icon.svg b/designs/shard_node_icon.svg index 24fc994..c5e7ae4 100644 --- a/designs/shard_node_icon.svg +++ b/designs/shard_node_icon.svg @@ -16,9 +16,9 @@ id="svg8" inkscape:version="0.92.4 (5da689c313, 2019-01-14)" sodipodi:docname="shard_node_icon.svg" - inkscape:export-filename="A:\Programming\GitHub-andrewlalis\CrystalKeep\src\main\resources\ui\images\shard_node_icon.png" - inkscape:export-xdpi="192" - inkscape:export-ydpi="192"> + inkscape:export-filename="A:\Programming\GitHub-andrewlalis\CrystalKeep\src\main\resources\nl\andrewlalis\crystalkeep\ui\images\shard_node_icon.png" + inkscape:export-xdpi="1536" + inkscape:export-ydpi="1536"> + units="px" + showguides="true" + inkscape:guide-bbox="true" /> @@ -58,21 +60,9 @@ id="layer1" transform="translate(0,-292.76667)"> + style="fill:#00f8c5;stroke:none;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1" + d="m 2.1143043,292.83045 1.1824699,2.0481 -1.1824699,2.0481 -1.18246994,-2.0481 1.18246994,-2.0481" + id="path820" + inkscape:connector-curvature="0" /> diff --git a/designs/shards/file.svg b/designs/shards/file.svg new file mode 100644 index 0000000..2ee1ef1 --- /dev/null +++ b/designs/shards/file.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/designs/shards/login_credentials.svg b/designs/shards/login_credentials.svg new file mode 100644 index 0000000..f2fcb90 --- /dev/null +++ b/designs/shards/login_credentials.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/designs/text_shard_node_icon.svg b/designs/shards/text.svg similarity index 52% rename from designs/text_shard_node_icon.svg rename to designs/shards/text.svg index 4a7b458..e9e50f1 100644 --- a/designs/text_shard_node_icon.svg +++ b/designs/shards/text.svg @@ -15,10 +15,10 @@ version="1.1" id="svg8" inkscape:version="0.92.4 (5da689c313, 2019-01-14)" - sodipodi:docname="text_shard_node_icon.svg" + sodipodi:docname="text.svg" inkscape:export-filename="A:\Programming\GitHub-andrewlalis\CrystalKeep\src\main\resources\nl\andrewlalis\crystalkeep\ui\images\text_shard_node_icon.png" - inkscape:export-xdpi="192" - inkscape:export-ydpi="192"> + inkscape:export-xdpi="1536" + inkscape:export-ydpi="1536"> + units="px" + showguides="true" + inkscape:guide-bbox="true" /> @@ -57,33 +59,16 @@ inkscape:groupmode="layer" id="layer1" transform="translate(0,-292.76667)"> - A + id="tspan815" + x="0.36164278" + y="296.76907" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.69617891px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.35601118">T diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/AddShardHandler.java b/src/main/java/nl/andrewlalis/crystalkeep/control/AddShardHandler.java index 528a24c..b15575b 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/control/AddShardHandler.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/AddShardHandler.java @@ -53,7 +53,7 @@ public class AddShardHandler implements EventHandler { switch (type) { case TEXT: return new TextShard(name); case LOGIN_CREDENTIALS: return new LoginCredentialsShard(name); - case FILE: return new FileShard(name, "", "", new byte[0]); + case FILE: return new FileShard(name, "", new byte[0]); default: return null; } } diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewItemSelectionListener.java b/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewItemSelectionListener.java index eee88e9..9c4f503 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewItemSelectionListener.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewItemSelectionListener.java @@ -6,7 +6,7 @@ import javafx.scene.control.TreeItem; import javafx.scene.layout.VBox; import nl.andrewlalis.crystalkeep.model.CrystalItem; import nl.andrewlalis.crystalkeep.view.ShardTreeItem; -import nl.andrewlalis.crystalkeep.view.shard_details.ViewModels; +import nl.andrewlalis.crystalkeep.view.shards.ViewModels; /** * This listener will update the shard detail container pane (the main center diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java b/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java index bb1ae55..48c7eea 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java @@ -23,6 +23,8 @@ public class MainViewController implements ModelListener { public TreeView clusterTreeView; @FXML public VBox shardDetailContainer; + @FXML + public Menu fileMenu; public void init(Model model) { this.model = model; @@ -91,7 +93,6 @@ public class MainViewController implements ModelListener { @FXML public void save() { if (model.getActiveCluster() == null) return; - ClusterIO loader = new ClusterIO(); Path path = model.getActiveClusterPath(); if (path == null) { FileChooser chooser = new FileChooser(); @@ -102,27 +103,12 @@ public class MainViewController implements ModelListener { if (file == null) return; path = file.toPath(); } - char[] pw = this.model.getActiveClusterPassword(); - if (pw == null) { - pw = this.promptPassword().orElse(new char[0]); - } - try { - if (pw.length == 0) { - loader.saveUnencrypted(model.getActiveCluster(), path); - } else { - loader.save(model.getActiveCluster(), path, pw); - } - } catch (Exception e) { - e.printStackTrace(); - var alert = new Alert(Alert.AlertType.ERROR, "Could not save cluster."); - alert.showAndWait(); - } + this.saveCluster(path); } @FXML public void saveAs() { if (model.getActiveCluster() == null) return; - ClusterIO clusterIO = new ClusterIO(); Path path = model.getActiveClusterPath(); FileChooser chooser = new FileChooser(); chooser.setTitle("Save Cluster"); @@ -133,21 +119,7 @@ public class MainViewController implements ModelListener { File file = chooser.showSaveDialog(this.clusterTreeView.getScene().getWindow()); if (file == null) return; path = file.toPath(); - char[] pw = this.model.getActiveClusterPassword(); - if (pw == null) { - pw = this.promptPassword().orElse(new char[0]); - } - try { - if (pw.length == 0) { - clusterIO.saveUnencrypted(model.getActiveCluster(), path); - } else { - clusterIO.save(model.getActiveCluster(), path, pw); - } - } catch (Exception e) { - e.printStackTrace(); - var alert = new Alert(Alert.AlertType.ERROR, "Could not save cluster."); - alert.showAndWait(); - } + this.saveCluster(path); } @FXML @@ -175,4 +147,23 @@ public class MainViewController implements ModelListener { }); return d.showAndWait(); } + + private void saveCluster(Path path) { + char[] pw = this.model.getActiveClusterPassword(); + if (pw == null) { + pw = this.promptPassword().orElse(new char[0]); + } + ClusterIO loader = new ClusterIO(); + try { + if (pw.length == 0) { + loader.saveUnencrypted(model.getActiveCluster(), path); + } else { + loader.save(model.getActiveCluster(), path, pw); + } + } catch (Exception e) { + e.printStackTrace(); + var alert = new Alert(Alert.AlertType.ERROR, "Could not save cluster."); + alert.showAndWait(); + } + } } diff --git a/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ByteUtils.java b/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ByteUtils.java index 5d4f0a6..97cfec5 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ByteUtils.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ByteUtils.java @@ -1,6 +1,5 @@ package nl.andrewlalis.crystalkeep.io.serialization; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -25,6 +24,32 @@ public class ByteUtils { os.write(toBytes(value)); } + public static byte[] longToBytes(long l) { + byte[] result = new byte[8]; + for (int i = 7; i >= 0; i--) { + result[i] = (byte)(l & 0xFF); + l >>= 8; + } + return result; + } + + public static long bytesToLong(final byte[] b) { + long result = 0; + for (int i = 0; i < 8; i++) { + result <<= 8; + result |= (b[i] & 0xFF); + } + return result; + } + + public static void writeLong(long value, OutputStream os) throws IOException { + os.write(longToBytes(value)); + } + + public static long readLong(InputStream is) throws IOException { + return bytesToLong(is.readNBytes(Long.BYTES)); + } + public static void writeLengthPrefixed(byte[] bytes, OutputStream os) throws IOException { os.write(toBytes(bytes.length)); os.write(bytes); @@ -34,12 +59,10 @@ public class ByteUtils { writeLengthPrefixed(s.getBytes(StandardCharsets.UTF_8), os); } - public static byte[] writeLengthPrefixedStrings(String[] strings) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + public static void writeLengthPrefixedStrings(String[] strings, OutputStream os) throws IOException { for (String s : strings) { - writeLengthPrefixed(s, bos); + writeLengthPrefixed(s, os); } - return bos.toByteArray(); } public static byte[] readLengthPrefixed(InputStream is) throws IOException { diff --git a/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ClusterSerializer.java b/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ClusterSerializer.java index 8603034..7745c6b 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ClusterSerializer.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ClusterSerializer.java @@ -2,8 +2,9 @@ package nl.andrewlalis.crystalkeep.io.serialization; import nl.andrewlalis.crystalkeep.model.Cluster; import nl.andrewlalis.crystalkeep.model.Shard; -import nl.andrewlalis.crystalkeep.model.shards.LoginCredentialsShard; import nl.andrewlalis.crystalkeep.model.ShardType; +import nl.andrewlalis.crystalkeep.model.shards.FileShard; +import nl.andrewlalis.crystalkeep.model.shards.LoginCredentialsShard; import nl.andrewlalis.crystalkeep.model.shards.TextShard; import java.io.IOException; @@ -27,6 +28,7 @@ public class ClusterSerializer { static { serializers.put(ShardType.TEXT, new TextShard.Serializer()); serializers.put(ShardType.LOGIN_CREDENTIALS, new LoginCredentialsShard.Serializer()); + serializers.put(ShardType.FILE, new FileShard.Serializer()); } /** @@ -82,7 +84,7 @@ public class ClusterSerializer { ByteUtils.writeLengthPrefixed(shard.getCreatedAt().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME).getBytes(StandardCharsets.UTF_8), os); os.write(ByteUtils.toBytes(shard.getType().getValue())); ShardSerializer serializer = serializers.get(shard.getType()); - os.write(serializer.serialize(shard)); + serializer.serialize(shard, os); } /** diff --git a/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ShardSerializer.java b/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ShardSerializer.java index 1106aec..9dc2496 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ShardSerializer.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/io/serialization/ShardSerializer.java @@ -4,10 +4,16 @@ import nl.andrewlalis.crystalkeep.model.Shard; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.time.LocalDateTime; +/** + * This interface should be implemented to provide the ability to serialize and + * deserialize a shard to and from a stream of bytes. + * @param The shard type. + */ public interface ShardSerializer { - byte[] serialize(T shard) throws IOException; + void serialize(T shard, OutputStream os) throws IOException; T deserialize(InputStream is, String name, LocalDateTime createdAt) throws IOException; } diff --git a/src/main/java/nl/andrewlalis/crystalkeep/model/shards/FileShard.java b/src/main/java/nl/andrewlalis/crystalkeep/model/shards/FileShard.java index ebd8d56..ba15c5e 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/model/shards/FileShard.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/model/shards/FileShard.java @@ -1,35 +1,57 @@ package nl.andrewlalis.crystalkeep.model.shards; +import nl.andrewlalis.crystalkeep.io.serialization.ByteUtils; +import nl.andrewlalis.crystalkeep.io.serialization.ShardSerializer; import nl.andrewlalis.crystalkeep.model.Shard; import nl.andrewlalis.crystalkeep.model.ShardType; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.time.LocalDateTime; public class FileShard extends Shard { private String fileName; - private String mimeType; private byte[] contents; - public FileShard(String name, LocalDateTime createdAt, String fileName, String mimeType, byte[] contents) { + public FileShard(String name, LocalDateTime createdAt, String fileName, byte[] contents) { super(name, createdAt, ShardType.FILE); this.fileName = fileName; - this.mimeType = mimeType; this.contents = contents; } - public FileShard(String name, String fileName, String mimeType, byte[] contents) { - this(name, LocalDateTime.now(), fileName, mimeType, contents); + public FileShard(String name, String fileName, byte[] contents) { + this(name, LocalDateTime.now(), fileName, contents); } public String getFileName() { return fileName; } - public String getMimeType() { - return mimeType; + public void setFileName(String fileName) { + this.fileName = fileName; } public byte[] getContents() { return contents; } + + public void setContents(byte[] contents) { + this.contents = contents; + } + + public static final class Serializer implements ShardSerializer { + @Override + public void serialize(FileShard shard, OutputStream os) throws IOException { + ByteUtils.writeLengthPrefixed(shard.getFileName(), os); + ByteUtils.writeLengthPrefixed(shard.getContents(), os); + } + + @Override + public FileShard deserialize(InputStream is, String name, LocalDateTime createdAt) throws IOException { + String fileName = ByteUtils.readLengthPrefixedString(is); + byte[] contents = ByteUtils.readLengthPrefixed(is); + return new FileShard(name, createdAt, fileName, contents); + } + } } diff --git a/src/main/java/nl/andrewlalis/crystalkeep/model/shards/LoginCredentialsShard.java b/src/main/java/nl/andrewlalis/crystalkeep/model/shards/LoginCredentialsShard.java index 7d7ba75..7e2103f 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/model/shards/LoginCredentialsShard.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/model/shards/LoginCredentialsShard.java @@ -1,12 +1,13 @@ package nl.andrewlalis.crystalkeep.model.shards; -import nl.andrewlalis.crystalkeep.model.Shard; -import nl.andrewlalis.crystalkeep.model.ShardType; import nl.andrewlalis.crystalkeep.io.serialization.ByteUtils; import nl.andrewlalis.crystalkeep.io.serialization.ShardSerializer; +import nl.andrewlalis.crystalkeep.model.Shard; +import nl.andrewlalis.crystalkeep.model.ShardType; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.time.LocalDateTime; public class LoginCredentialsShard extends Shard { @@ -44,11 +45,11 @@ public class LoginCredentialsShard extends Shard { return super.toString() + ", username=\"" + this.username + "\", password=\"" + this.password + "\""; } - public static class Serializer implements ShardSerializer { + public static final class Serializer implements ShardSerializer { @Override - public byte[] serialize(LoginCredentialsShard shard) throws IOException { - return ByteUtils.writeLengthPrefixedStrings(new String[]{shard.getUsername(), shard.getPassword()}); + public void serialize(LoginCredentialsShard shard, OutputStream os) throws IOException { + ByteUtils.writeLengthPrefixedStrings(new String[]{shard.getUsername(), shard.getPassword()}, os); } @Override diff --git a/src/main/java/nl/andrewlalis/crystalkeep/model/shards/TextShard.java b/src/main/java/nl/andrewlalis/crystalkeep/model/shards/TextShard.java index 328d132..44e5fed 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/model/shards/TextShard.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/model/shards/TextShard.java @@ -1,12 +1,13 @@ package nl.andrewlalis.crystalkeep.model.shards; -import nl.andrewlalis.crystalkeep.model.Shard; -import nl.andrewlalis.crystalkeep.model.ShardType; import nl.andrewlalis.crystalkeep.io.serialization.ByteUtils; import nl.andrewlalis.crystalkeep.io.serialization.ShardSerializer; +import nl.andrewlalis.crystalkeep.model.Shard; +import nl.andrewlalis.crystalkeep.model.ShardType; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.time.LocalDateTime; public class TextShard extends Shard { @@ -34,10 +35,10 @@ public class TextShard extends Shard { return super.toString() + ", text=\"" + this.text + "\""; } - public static class Serializer implements ShardSerializer { + public static final class Serializer implements ShardSerializer { @Override - public byte[] serialize(TextShard shard) throws IOException { - return ByteUtils.writeLengthPrefixedStrings(new String[]{shard.getText()}); + public void serialize(TextShard shard, OutputStream os) throws IOException { + ByteUtils.writeLengthPrefixedStrings(new String[]{shard.getText()}, os); } @Override diff --git a/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java b/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java new file mode 100644 index 0000000..66d3d50 --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/util/StringUtils.java @@ -0,0 +1,10 @@ +package nl.andrewlalis.crystalkeep.util; + +public class StringUtils { + public static boolean endsWithAny(String s, String... suffixes) { + for (String suffix : suffixes) { + if (s.endsWith(suffix)) return true; + } + return false; + } +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/CrystalItemTreeCell.java b/src/main/java/nl/andrewlalis/crystalkeep/view/CrystalItemTreeCell.java index 8bafa6e..3b377a2 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/view/CrystalItemTreeCell.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/CrystalItemTreeCell.java @@ -12,7 +12,7 @@ import nl.andrewlalis.crystalkeep.model.CrystalItem; import nl.andrewlalis.crystalkeep.model.Model; import nl.andrewlalis.crystalkeep.model.Shard; import nl.andrewlalis.crystalkeep.util.ImageCache; -import nl.andrewlalis.crystalkeep.view.shard_details.ViewModels; +import nl.andrewlalis.crystalkeep.view.shards.ViewModels; public class CrystalItemTreeCell extends TreeCell { private static final String CLUSTER_ICON = "/nl/andrewlalis/crystalkeep/ui/images/cluster_node_icon.png"; diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java new file mode 100644 index 0000000..51066bf --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/FileShardViewModel.java @@ -0,0 +1,92 @@ +package nl.andrewlalis.crystalkeep.view.shards; + +import javafx.geometry.Insets; +import javafx.geometry.Orientation; +import javafx.scene.Node; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import javafx.stage.FileChooser; +import nl.andrewlalis.crystalkeep.model.shards.FileShard; +import nl.andrewlalis.crystalkeep.util.StringUtils; + +import java.io.*; + +public class FileShardViewModel extends ShardViewModel { + public FileShardViewModel(FileShard shard) { + super(shard); + } + + @Override + protected Node getContent(FileShard shard) { + VBox container = new VBox(10); + container.setPadding(new Insets(5)); + GridPane gp = new GridPane(); + gp.setVgap(5); + gp.setHgap(5); + + gp.add(new Label("File Name"), 0, 0); + TextField nameField = new TextField(shard.getFileName()); + nameField.textProperty().addListener((observable, oldValue, newValue) -> { + shard.setFileName(newValue); + }); + gp.add(nameField, 1, 0); + gp.add(new Label("File Size"), 0, 1); + TextField sizeField = new TextField(shard.getContents().length + " bytes"); + sizeField.setEditable(false); + gp.add(sizeField, 1, 1); + + Button setFileButton = new Button("Set File"); + setFileButton.setOnAction(event -> { + FileChooser chooser = new FileChooser(); + chooser.setTitle("Choose a File"); + File file = chooser.showOpenDialog(gp.getScene().getWindow()); + if (file != null) { + try (FileInputStream fis = new FileInputStream(file)) { + byte[] contents = fis.readAllBytes(); + shard.setFileName(file.getName()); + shard.setContents(contents); + nameField.setText(shard.getFileName()); + sizeField.setText(shard.getContents().length + " bytes"); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + gp.add(setFileButton, 0, 2); + + Button extractFileButton = new Button("Extract File"); + extractFileButton.setOnAction(event -> { + FileChooser chooser = new FileChooser(); + chooser.setTitle("Extract File"); + chooser.setInitialFileName(shard.getFileName()); + File file = chooser.showSaveDialog(gp.getScene().getWindow()); + if (file != null) { + try (FileOutputStream fos = new FileOutputStream(file)) { + fos.write(shard.getContents()); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + gp.add(extractFileButton, 1, 2); + container.getChildren().add(gp); + + if (StringUtils.endsWithAny(shard.getFileName().toLowerCase(), ".png", ".jpg", ".jpeg", ".gif")) { + container.getChildren().add(new Separator(Orientation.HORIZONTAL)); + ImageView imageView = new ImageView(new Image(new ByteArrayInputStream(shard.getContents()))); + imageView.setPreserveRatio(true); + ScrollPane scrollPane = new ScrollPane(imageView); + container.getChildren().add(scrollPane); + } + + return container; + } + + @Override + public String getIconPath() { + return "/nl/andrewlalis/crystalkeep/ui/images/file_shard_node_icon.png"; + } +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/LoginCredentialsViewModel.java b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/LoginCredentialsViewModel.java similarity index 98% rename from src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/LoginCredentialsViewModel.java rename to src/main/java/nl/andrewlalis/crystalkeep/view/shards/LoginCredentialsViewModel.java index b23cfb1..cae0a50 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/LoginCredentialsViewModel.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/LoginCredentialsViewModel.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.crystalkeep.view.shard_details; +package nl.andrewlalis.crystalkeep.view.shards; import javafx.geometry.Insets; import javafx.scene.Node; diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/ShardViewModel.java b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/ShardViewModel.java similarity index 96% rename from src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/ShardViewModel.java rename to src/main/java/nl/andrewlalis/crystalkeep/view/shards/ShardViewModel.java index 7c7e194..8826c0a 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/ShardViewModel.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/ShardViewModel.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.crystalkeep.view.shard_details; +package nl.andrewlalis.crystalkeep.view.shards; import javafx.geometry.Insets; import javafx.geometry.Orientation; diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/TextShardViewModel.java b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/TextShardViewModel.java similarity index 92% rename from src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/TextShardViewModel.java rename to src/main/java/nl/andrewlalis/crystalkeep/view/shards/TextShardViewModel.java index 97ffc9a..c134fd0 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/TextShardViewModel.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/TextShardViewModel.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.crystalkeep.view.shard_details; +package nl.andrewlalis.crystalkeep.view.shards; import javafx.scene.Node; import javafx.scene.control.TextArea; diff --git a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/ViewModels.java b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/ViewModels.java similarity index 86% rename from src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/ViewModels.java rename to src/main/java/nl/andrewlalis/crystalkeep/view/shards/ViewModels.java index 09f4581..514f2a1 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/view/shard_details/ViewModels.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/view/shards/ViewModels.java @@ -1,6 +1,7 @@ -package nl.andrewlalis.crystalkeep.view.shard_details; +package nl.andrewlalis.crystalkeep.view.shards; import nl.andrewlalis.crystalkeep.model.Shard; +import nl.andrewlalis.crystalkeep.model.shards.FileShard; import nl.andrewlalis.crystalkeep.model.shards.LoginCredentialsShard; import nl.andrewlalis.crystalkeep.model.shards.TextShard; @@ -17,6 +18,7 @@ public class ViewModels { static { shardViewModels.put(TextShard.class, TextShardViewModel.class); shardViewModels.put(LoginCredentialsShard.class, LoginCredentialsViewModel.class); + shardViewModels.put(FileShard.class, FileShardViewModel.class); } public static Optional> get(Shard shard) { diff --git a/src/main/resources/nl/andrewlalis/crystalkeep/ui/crystalkeep.fxml b/src/main/resources/nl/andrewlalis/crystalkeep/ui/crystalkeep.fxml index cbc72e8..18ffd1c 100644 --- a/src/main/resources/nl/andrewlalis/crystalkeep/ui/crystalkeep.fxml +++ b/src/main/resources/nl/andrewlalis/crystalkeep/ui/crystalkeep.fxml @@ -4,7 +4,7 @@ - + diff --git a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/file_shard_node_icon.png b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/file_shard_node_icon.png new file mode 100644 index 0000000..f08919b Binary files /dev/null and b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/file_shard_node_icon.png differ diff --git a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/login_credentials_shard_node_icon.png b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/login_credentials_shard_node_icon.png index ba169d3..5940c2f 100644 Binary files a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/login_credentials_shard_node_icon.png and b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/login_credentials_shard_node_icon.png differ diff --git a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/shard_node_icon.png b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/shard_node_icon.png index efa63a5..44ae17f 100644 Binary files a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/shard_node_icon.png and b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/shard_node_icon.png differ diff --git a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/text_shard_node_icon.png b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/text_shard_node_icon.png index c623b85..e27069f 100644 Binary files a/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/text_shard_node_icon.png and b/src/main/resources/nl/andrewlalis/crystalkeep/ui/images/text_shard_node_icon.png differ