148 lines
4.5 KiB
Java
148 lines
4.5 KiB
Java
package nl.andrewlalis.crystalkeep.control;
|
|
|
|
import javafx.application.Platform;
|
|
import javafx.fxml.FXML;
|
|
import javafx.geometry.Pos;
|
|
import javafx.scene.control.*;
|
|
import javafx.scene.layout.VBox;
|
|
import javafx.stage.FileChooser;
|
|
import nl.andrewlalis.crystalkeep.io.ClusterIO;
|
|
import nl.andrewlalis.crystalkeep.model.*;
|
|
import nl.andrewlalis.crystalkeep.view.ClusterTreeItem;
|
|
import nl.andrewlalis.crystalkeep.view.CrystalItemTreeCell;
|
|
import nl.andrewlalis.crystalkeep.view.ShardTreeItem;
|
|
|
|
import java.io.File;
|
|
import java.nio.file.Path;
|
|
import java.util.Optional;
|
|
|
|
public class MainViewController implements ModelListener {
|
|
private Model model;
|
|
|
|
@FXML
|
|
public TreeView<CrystalItem> clusterTreeView;
|
|
@FXML
|
|
public VBox shardDetailContainer;
|
|
|
|
public void init(Model model) {
|
|
this.model = model;
|
|
this.model.addListener(this);
|
|
this.activeClusterUpdated();
|
|
assert(this.clusterTreeView != null);
|
|
this.clusterTreeView.setCellFactory(param -> new CrystalItemTreeCell(this.model));
|
|
this.clusterTreeView.getSelectionModel().selectedItemProperty()
|
|
.addListener(new ClusterTreeViewItemSelectionListener(this.shardDetailContainer));
|
|
}
|
|
|
|
@Override
|
|
public void activeClusterUpdated() {
|
|
if (this.model.getActiveCluster() == null) return;
|
|
TreeItem<CrystalItem> root = this.createNode(this.model.getActiveCluster());
|
|
this.clusterTreeView.setRoot(root);
|
|
this.clusterTreeView.setShowRoot(true);
|
|
}
|
|
|
|
private TreeItem<CrystalItem> createNode(Cluster cluster) {
|
|
ClusterTreeItem node = new ClusterTreeItem(cluster, this.clusterTreeView);
|
|
node.setExpanded(true);
|
|
for (Cluster child : cluster.getClustersOrdered()) {
|
|
node.getChildren().add(this.createNode(child));
|
|
}
|
|
for (Shard shard : cluster.getShardsOrdered()) {
|
|
node.getChildren().add(new ShardTreeItem(shard));
|
|
}
|
|
return node;
|
|
}
|
|
|
|
@FXML
|
|
public void exit() {
|
|
Platform.exit();
|
|
}
|
|
|
|
@FXML
|
|
public void load() {
|
|
FileChooser chooser = new FileChooser();
|
|
chooser.setTitle("Load a Cluster");
|
|
chooser.setInitialDirectory(ClusterIO.CLUSTER_PATH.toFile());
|
|
chooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("Cluster Files", "cts"));
|
|
File file = chooser.showOpenDialog(this.clusterTreeView.getScene().getWindow());
|
|
if (file == null) return;
|
|
ClusterIO loader = new ClusterIO();
|
|
var password = this.promptPassword();
|
|
Cluster cluster;
|
|
try {
|
|
if (password.isEmpty() || password.get().isEmpty()) {
|
|
cluster = loader.loadUnencrypted(file.toPath());
|
|
this.model.setActiveClusterPassword(null);
|
|
} else {
|
|
char[] pw = password.get().toCharArray();
|
|
cluster = loader.load(file.toPath(), pw);
|
|
this.model.setActiveClusterPassword(pw);
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
new Alert(Alert.AlertType.WARNING, "Could not load cluster.").showAndWait();
|
|
return;
|
|
}
|
|
model.setActiveCluster(cluster);
|
|
model.setActiveClusterPath(file.toPath());
|
|
}
|
|
|
|
@FXML
|
|
public void save() {
|
|
if (model.getActiveCluster() == null) return;
|
|
ClusterIO loader = new ClusterIO();
|
|
Path path = model.getActiveClusterPath();
|
|
if (path == null) {
|
|
FileChooser chooser = new FileChooser();
|
|
chooser.setTitle("Save Cluster");
|
|
chooser.setInitialDirectory(ClusterIO.CLUSTER_PATH.toFile());
|
|
chooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("Cluster Files", "cts"));
|
|
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("").toCharArray();
|
|
}
|
|
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();
|
|
}
|
|
}
|
|
|
|
@FXML
|
|
public void newCluster() {
|
|
Cluster c = new Cluster("Root");
|
|
model.setActiveCluster(c);
|
|
model.setActiveClusterPath(null);
|
|
}
|
|
|
|
private Optional<String> promptPassword() {
|
|
Dialog<String> d = new Dialog<>();
|
|
d.setTitle("Enter Password");
|
|
d.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
|
|
|
|
PasswordField pwField = new PasswordField();
|
|
VBox content = new VBox(10);
|
|
content.setAlignment(Pos.CENTER);
|
|
content.getChildren().addAll(new Label("Enter password"), pwField);
|
|
d.getDialogPane().setContent(content);
|
|
d.setResultConverter(param -> {
|
|
if (param == ButtonType.OK) {
|
|
return pwField.getText();
|
|
}
|
|
return null;
|
|
});
|
|
return d.showAndWait();
|
|
}
|
|
}
|