Adds context menu for subtitles table

This commit is contained in:
Guillaume Tâche
2024-09-26 21:41:02 +02:00
parent c59619da2d
commit 0a2f9e0c31
9 changed files with 130 additions and 197 deletions

View File

@@ -4,4 +4,5 @@ parameters.extraction.model.label=Mod\u00E8le utilis\u00E9 pour l'extraction des
parameters.subtitles.font.family=Police par d\u00E9faut pour les sous-titres
parameters.subtitles.font.size=Taille de la police par d\u00E9faut pour les sous-titres
parameters.subtitles.max.length.label=Taille maximale d'une ligne de sous-titres (caract\u00E8res)
parameters.subtitles.max.lines.label=Nombre de lignes maximum pour les sous-titres
parameters.subtitles.output.format=Format de sortie pour les sous-titres

View File

@@ -7,6 +7,9 @@ subtitles.export.error.title=Error exporting
subtitles.language.label=Video language
subtitles.load.error.label=Error loading subtitles : {0}
subtitles.load.error.title=Error loading
subtitles.menu.add.label=Add
subtitles.menu.delete.label=Delete
subtitles.menu.duplicate.label=Duplicate
subtitles.save.error.label=Error saving subtitles : {0}
subtitles.save.error.title=Error saving
subtitles.table.column.from.label=From

View File

@@ -7,6 +7,9 @@ subtitles.export.error.title=Erreur d'export
subtitles.language.label=Langage de la vid\u00E9o
subtitles.load.error.label=Erreur de chargement des sous-titres : {0}
subtitles.load.error.title=Erreur de chargement
subtitles.menu.add.label=Ajouter
subtitles.menu.delete.label=Supprimer
subtitles.menu.duplicate.label=Dupliquer
subtitles.save.error.label=Erreur de sauvegarde des sous-titres : {0}
subtitles.save.error.title=Erreur lors de la sauvegarde
subtitles.table.column.from.label=De

View File

@@ -19,12 +19,15 @@ import javafx.collections.MapChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.KeyCode;
import javafx.stage.FileChooser;
import javafx.stage.Window;
@@ -131,38 +134,44 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
}
});
translationsCombobox.setOnAction(e -> {
final var value = translationsCombobox.getValue();
if (value != null && !model.collections().containsKey(value)) {
model.setTranslating(true);
CompletableFuture.supplyAsync(() -> {
final var mainCollection = model.collections().get(model.videoLanguage());
try {
if (mainCollection == null) {
return translator.translate(model.selectedCollection(), value);
} else {
return translator.translate(mainCollection, value);
}
} catch (final TranslationException ex) {
throw new CompletionException(ex);
}
}).whenCompleteAsync((r, t) -> {
if (t == null) {
loadCollection(r);
model.setSelectedCollection(model.collections().get(value));
} else {
logger.error("Error while translating to {}", value, t);
final var newCollection = new ObservableSubtitleCollectionImpl();
loadCollection(newCollection);
model.setSelectedCollection(newCollection);
}
model.setTranslating(false);
}, Platform::runLater);
}
});
translationsCombobox.setOnAction(e -> translateToNewLanguage());
binder.createBindings();
}
private void translateToNewLanguage() {
final var value = translationsCombobox.getValue();
if (value != null && !model.collections().containsKey(value)) {
model.setTranslating(true);
CompletableFuture.supplyAsync(() -> {
final var mainCollection = model.collections().get(model.videoLanguage());
try {
if (mainCollection == null) {
if (model.selectedCollection() == null) {
return null;
} else {
return translator.translate(model.selectedCollection(), value);
}
} else {
return translator.translate(mainCollection, value);
}
} catch (final TranslationException ex) {
throw new CompletionException(ex);
}
}).whenCompleteAsync((r, t) -> {
if (r == null) {
logger.error("Error while translating to {}", value, t);
final var newCollection = new ObservableSubtitleCollectionImpl();
loadCollection(newCollection);
model.setSelectedCollection(newCollection);
} else {
loadCollection(r);
model.setSelectedCollection(model.collections().get(value));
}
model.setTranslating(false);
}, Platform::runLater);
}
}
private void bindTable() {
subtitlesTable.setItems(model.selectedSubtitles());
subtitlesTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
@@ -182,9 +191,7 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
e.consume();
}
});
subtitlesTable.setOnContextMenuRequested(e -> {
//TODO menu with copy, delete
});
subtitlesTable.setOnContextMenuRequested(this::showContextMenu);
startColumn.setCellFactory(TextFieldTableCell.forTableColumn(new TimeStringConverter(timeFormatter)));
startColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue() == null ? null : param.getValue().start()));
startColumn.setOnEditCommit(e -> {
@@ -214,6 +221,30 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
}
private void showContextMenu(final ContextMenuEvent e) {
if (model.selectedCollection() != null) {
final var deleteMenuItem = new MenuItem(resources.getString("subtitles.menu.delete.label"));
deleteMenuItem.setOnAction(ignored -> deleteSelectedSubtitles());
final var addMenuItem = new MenuItem(resources.getString("subtitles.menu.add.label"));
addMenuItem.setOnAction(ignored -> addNewSubtitle());
final var duplicateMenuItem = new MenuItem(resources.getString("subtitles.menu.duplicate.label"));
duplicateMenuItem.setOnAction(ignored -> duplicateSelectedSubtitles());
final var menu = new ContextMenu(addMenuItem);
if (!model.selectedSubtitles().isEmpty()) {
menu.getItems().addAll(duplicateMenuItem, deleteMenuItem);
}
menu.show(subtitlesTable, e.getScreenX(), e.getScreenY());
}
}
private void duplicateSelectedSubtitles() {
final var selected = model.selectedSubtitles();
if (!selected.isEmpty()) {
model.selectedCollection().observableSubtitles().addAll(selected.stream().map(ObservableSubtitleImpl::new).toList());
model.selectedCollection().observableSubtitles().sort(Comparator.comparingLong(ObservableSubtitleImpl::start));
}
}
private void manageTabs() {
final var toRemove = new ArrayList<Tab>();
final var toAdd = new ArrayList<Tab>();
@@ -247,7 +278,13 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
@FXML
private void addPressed() {
model.selectedCollection().subtitles().add(new ObservableSubtitleImpl(resources.getString("subtitles.add.prompt.label")));
addNewSubtitle();
}
private void addNewSubtitle() {
if (model.selectedCollection() != null) {
model.selectedCollection().subtitles().add(new ObservableSubtitleImpl(resources.getString("subtitles.add.prompt.label")));
}
}
@FXML