ctbrec-5.3.2-experimental/client/src/main/java/ctbrec/ui/settings/PostProcessingStepPanel.java

200 lines
7.1 KiB
Java

package ctbrec.ui.settings;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import ctbrec.Config;
import ctbrec.recorder.postprocessing.Copy;
import ctbrec.recorder.postprocessing.DeleteOriginal;
import ctbrec.recorder.postprocessing.DeleteTooShort;
import ctbrec.recorder.postprocessing.Move;
import ctbrec.recorder.postprocessing.PostProcessor;
import ctbrec.recorder.postprocessing.RemoveKeepFile;
import ctbrec.recorder.postprocessing.Remux;
import ctbrec.recorder.postprocessing.Rename;
import ctbrec.recorder.postprocessing.Script;
import ctbrec.ui.controls.Dialogs;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceDialog;
import javafx.scene.control.ListView;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class PostProcessingStepPanel extends GridPane {
private Config config;
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[] { // @formatter: off
Copy.class,
Rename.class,
Move.class,
Remux.class,
Script.class,
DeleteOriginal.class,
DeleteTooShort.class,
RemoveKeepFile.class
}; // @formatter: on
ListView<PostProcessor> stepListView;
ObservableList<PostProcessor> stepList;
Button up;
Button down;
Button add;
Button remove;
Button edit;
public PostProcessingStepPanel(Config config) {
this.config = config;
initGui();
}
private void initGui() {
setHgap(5);
vgapProperty().bind(hgapProperty());
up = createUpButton();
down = createDownButton();
add = createAddButton();
remove = createRemoveButton();
edit = createEditButton();
VBox buttons = new VBox(5, add, edit, up, down, remove);
stepList = FXCollections.observableList(config.getSettings().postProcessors);
stepList.addListener((ListChangeListener<PostProcessor>) change -> {
try {
config.save();
} catch (IOException e) {
Dialogs.showError(getScene(), "Couldn't save configuration", "An error occurred while saving the configuration", e);
}
});
stepListView = new ListView<>(stepList);
GridPane.setHgrow(stepListView, Priority.ALWAYS);
add(stepListView, 0, 0);
add(buttons, 1, 0);
stepListView.getSelectionModel().selectedIndexProperty().addListener((obs, oldV, newV) -> {
int idx = newV.intValue();
boolean noSelection = idx == -1;
up.setDisable(noSelection || idx == 0);
down.setDisable(noSelection || idx == stepList.size() - 1);
edit.setDisable(noSelection);
remove.setDisable(noSelection);
});
}
private Button createUpButton() {
Button up = createButton("\u25B4", "Move step up");
up.setOnAction(evt -> {
int idx = stepListView.getSelectionModel().getSelectedIndex();
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
stepList.remove(idx);
stepList.add(idx - 1, selectedItem);
stepListView.getSelectionModel().select(idx - 1);
});
return up;
}
private Button createDownButton() {
Button down = createButton("\u25BE", "Move step down");
down.setOnAction(evt -> {
int idx = stepListView.getSelectionModel().getSelectedIndex();
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
stepList.remove(idx);
stepList.add(idx + 1, selectedItem);
stepListView.getSelectionModel().select(idx + 1);
});
return down;
}
private Button createAddButton() {
Button add = createButton("+", "Add a new step");
add.setDisable(false);
add.setOnAction(evt -> {
PostProcessor[] options = createOptions();
ChoiceDialog<PostProcessor> choice = new ChoiceDialog<>(options[0], options);
choice.setTitle("New Post-Processing Step");
choice.setHeaderText("Select the new step type");
choice.setResizable(true);
choice.setWidth(600);
choice.getDialogPane().setMinWidth(400);
Stage stage = (Stage) choice.getDialogPane().getScene().getWindow();
stage.getScene().getStylesheets().addAll(getScene().getStylesheets());
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
stage.getIcons().add(new Image(icon));
Optional<PostProcessor> result = choice.showAndWait();
result.ifPresent(pp -> PostProcessingDialogFactory.openNewDialog(pp, config, getScene(), stepList));
saveConfig();
});
return add;
}
private void saveConfig() {
try {
config.save();
} catch (IOException e) {
Dialogs.showError("Post-Processing", "Couldn't save post-processing step", e);
}
}
private PostProcessor[] createOptions() {
try {
PostProcessor[] options = new PostProcessor[POST_PROCESSOR_CLASSES.length];
for (int i = 0; i < POST_PROCESSOR_CLASSES.length; i++) {
Class<?> cls = POST_PROCESSOR_CLASSES[i];
PostProcessor pp;
pp = (PostProcessor) cls.getDeclaredConstructor().newInstance();
options[i] = pp;
}
return options;
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException e) {
Dialogs.showError(getScene(), "Create post-processor selection", "Error while reaing in post-processing options", e);
return new PostProcessor[0];
}
}
private Button createRemoveButton() {
Button remove = createButton("-", "Remove selected step");
remove.setOnAction(evt -> {
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
stepList.remove(selectedItem);
}
});
return remove;
}
private Button createEditButton() {
Button edit = createButton("\u270E", "Edit selected step");
edit.setOnAction(evt -> {
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
PostProcessingDialogFactory.openEditDialog(selectedItem, config, getScene(), stepList);
stepListView.refresh();
saveConfig();
});
return edit;
}
private Button createButton(String text, String tooltip) {
Button b = new Button(text);
b.setTooltip(new Tooltip(tooltip));
b.setDisable(true);
b.setPrefSize(32, 32);
return b;
}
}