Allows choosing and managing each tool
This commit is contained in:
@@ -1,69 +1,39 @@
|
||||
package com.github.gtache.autosubtitle.gui.setup;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
|
||||
/**
|
||||
* Controller for the setup view
|
||||
*/
|
||||
public interface SetupController {
|
||||
|
||||
/**
|
||||
* Installs the video converter
|
||||
* Installs the tool given by the tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
*/
|
||||
void installVideoConverter();
|
||||
void install(ToolType type);
|
||||
|
||||
/**
|
||||
* Uninstalls the video converter
|
||||
* Uninstalls the tool given by the tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
*/
|
||||
void uninstallVideoConverter();
|
||||
void uninstall(ToolType type);
|
||||
|
||||
/**
|
||||
* Updates the video converter
|
||||
* Updates the tool given by the tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
*/
|
||||
void updateVideoConverter();
|
||||
void update(ToolType type);
|
||||
|
||||
/**
|
||||
* Reinstalls the video converter
|
||||
* Reinstalls the tool given by the tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
*/
|
||||
void reinstallVideoConverter();
|
||||
|
||||
/**
|
||||
* Installs the subtitle extractor
|
||||
*/
|
||||
void installSubtitleExtractor();
|
||||
|
||||
/**
|
||||
* Uninstalls the subtitle extractor
|
||||
*/
|
||||
void uninstallSubtitleExtractor();
|
||||
|
||||
/**
|
||||
* Updates the subtitle extractor
|
||||
*/
|
||||
void updateSubtitleExtractor();
|
||||
|
||||
/**
|
||||
* Reinstalls the subtitle extractor
|
||||
*/
|
||||
void reinstallSubtitleExtractor();
|
||||
|
||||
/**
|
||||
* Installs the translator
|
||||
*/
|
||||
void installTranslator();
|
||||
|
||||
/**
|
||||
* Uninstalls the translator
|
||||
*/
|
||||
void uninstallTranslator();
|
||||
|
||||
/**
|
||||
* Updates the translator
|
||||
*/
|
||||
void updateTranslator();
|
||||
|
||||
/**
|
||||
* Reinstalls the translator
|
||||
*/
|
||||
void reinstallTranslator();
|
||||
void reinstall(ToolType type);
|
||||
|
||||
/**
|
||||
* @return the model
|
||||
|
||||
@@ -1,117 +1,101 @@
|
||||
package com.github.gtache.autosubtitle.gui.setup;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Model for the setup view
|
||||
*/
|
||||
public interface SetupModel {
|
||||
|
||||
/**
|
||||
* @return the status of the subtitle extractor
|
||||
* Returns the list of available setup managers for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @return The list of managers
|
||||
*/
|
||||
SetupStatus subtitleExtractorStatus();
|
||||
List<SetupManager> availableSetupManagers(ToolType type);
|
||||
|
||||
/**
|
||||
* Sets the status of the subtitle extractor
|
||||
* Returns the selected setup manager for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @return The manager
|
||||
*/
|
||||
SetupManager selectedSetupManager(ToolType type);
|
||||
|
||||
/**
|
||||
* Sets the selected setup manager for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @param manager the new subtitle extractor
|
||||
*/
|
||||
void setSelectedSetupManager(ToolType type, SetupManager manager);
|
||||
|
||||
/**
|
||||
* Returns the selected tool for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @return the selected tool
|
||||
*/
|
||||
String selectedTool(ToolType type);
|
||||
|
||||
/**
|
||||
* Returns the status of the setup manager for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @return the status of the setup manager
|
||||
*/
|
||||
SetupStatus managerStatus(ToolType type);
|
||||
|
||||
/**
|
||||
* Sets the status of the setup manager for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @param status the new status
|
||||
*/
|
||||
void setSubtitleExtractorStatus(SetupStatus status);
|
||||
void setManagerStatus(ToolType type, SetupStatus status);
|
||||
|
||||
/**
|
||||
* @return the progress of the subtitle extractor setup
|
||||
*/
|
||||
double subtitleExtractorSetupProgress();
|
||||
|
||||
/**
|
||||
* Sets the progress of the subtitle extractor setup
|
||||
* Returns the progress of the tool setup for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @return the progress of the tool setup
|
||||
*/
|
||||
double setupProgress(ToolType type);
|
||||
|
||||
/**
|
||||
* Sets the progress of the tool setup for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @param progress the new progress
|
||||
*/
|
||||
void setSubtitleExtractorSetupProgress(double progress);
|
||||
void setSetupProgress(ToolType type, double progress);
|
||||
|
||||
/**
|
||||
* @return the text of the subtitle extractor setup progress
|
||||
*/
|
||||
String subtitleExtractorSetupProgressLabel();
|
||||
|
||||
/**
|
||||
* Sets the text of the subtitle extractor setup progress
|
||||
* Returns the text of the setup progress for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @return the text of the setup progress label
|
||||
*/
|
||||
String setupProgressLabel(ToolType type);
|
||||
|
||||
/**
|
||||
* Sets the text of the setup progress for the given tool type
|
||||
*
|
||||
* @param type The tool type
|
||||
* @param label the new text
|
||||
*/
|
||||
void setSubtitleExtractorSetupProgressLabel(String label);
|
||||
void setSetupProgressLabel(ToolType type, String label);
|
||||
|
||||
/**
|
||||
* @return the status of the video converter
|
||||
*/
|
||||
SetupStatus videoConverterStatus();
|
||||
|
||||
/**
|
||||
* Sets the status of the video converter
|
||||
* Returns true if the setup is editable
|
||||
*
|
||||
* @param status the new status
|
||||
* @param type The tool type
|
||||
* @return true if the setup is editable
|
||||
*/
|
||||
void setVideoConverterStatus(SetupStatus status);
|
||||
|
||||
/**
|
||||
* @return the progress of the video converter setup
|
||||
*/
|
||||
double videoConverterSetupProgress();
|
||||
|
||||
/**
|
||||
* Sets the progress of the video converter setup
|
||||
*
|
||||
* @param progress the new progress
|
||||
*/
|
||||
void setVideoConverterSetupProgress(double progress);
|
||||
|
||||
/**
|
||||
* @return the text of the video converter setup progress
|
||||
*/
|
||||
String videoConverterSetupProgressLabel();
|
||||
|
||||
/**
|
||||
* Sets the text of the video converter setup progress
|
||||
*
|
||||
* @param label the new text
|
||||
*/
|
||||
void setVideoConverterSetupProgressLabel(String label);
|
||||
|
||||
/**
|
||||
* @return the status of the translator
|
||||
*/
|
||||
SetupStatus translatorStatus();
|
||||
|
||||
/**
|
||||
* Sets the status of the translator
|
||||
*
|
||||
* @param status the new status
|
||||
*/
|
||||
void setTranslatorStatus(SetupStatus status);
|
||||
|
||||
/**
|
||||
* @return the progress of the translator setup
|
||||
*/
|
||||
double translatorSetupProgress();
|
||||
|
||||
/**
|
||||
* Sets the progress of the translator setup
|
||||
*
|
||||
* @param progress the new progress
|
||||
*/
|
||||
void setTranslatorSetupProgress(double progress);
|
||||
|
||||
/**
|
||||
* @return the text of the translator setup progress
|
||||
*/
|
||||
String translatorSetupProgressLabel();
|
||||
|
||||
/**
|
||||
* Sets the text of the translator setup progress
|
||||
*
|
||||
* @param label the new text
|
||||
*/
|
||||
void setTranslatorSetupProgressLabel(String label);
|
||||
boolean isSetupInProgress(ToolType type);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ setup.status.installed.label=is installed.
|
||||
setup.status.not_installed.label=is not installed.
|
||||
setup.status.system_installed.label=is installed (system).
|
||||
setup.status.update_available.label=has an available update.
|
||||
setup.subtitle_extractor.choice.label=Subtitle extractor
|
||||
setup.subtitle_translator.choice.label=Subtitle translator
|
||||
setup.uninstall.error.label=An error occurred while uninstalling : {0}
|
||||
setup.uninstall.error.title=Error uninstalling
|
||||
setup.update.error.label=An error occurred while updating : {0}
|
||||
setup.update.error.title=Error updating
|
||||
setup.update.error.title=Error updating
|
||||
setup.video_converter.choice.label=Video Converter
|
||||
@@ -1,3 +1,4 @@
|
||||
setup.converter.choice.label=Convertisseur vid\u00E9o
|
||||
setup.description.label=Statut des outils utilis\u00E9s par l'application
|
||||
setup.event.check.end.label=Contr\u00F4le de {0} termin\u00E9
|
||||
setup.event.check.start.label=Contr\u00F4le de {0} en cours
|
||||
@@ -11,6 +12,7 @@ setup.event.uninstall.end.label=D\u00E9sinstallation de {0} termin\u00E9e
|
||||
setup.event.uninstall.start.label=D\u00E9sinstallation de {0} en cours
|
||||
setup.event.update.end.label=Mise \u00E0 jour de {0} termin\u00E9e
|
||||
setup.event.update.start.label=Mise \u00E0 jour de {0} en cours
|
||||
setup.extractor.choice.label=Extracteur de sous-titres
|
||||
setup.install.error.label=Une erreur s''est produite lors de l''installation: {0}
|
||||
setup.install.error.title=Erreur d'installation
|
||||
setup.menu.install.label=Installer
|
||||
@@ -26,7 +28,11 @@ setup.status.installed.label=est install\u00E9.
|
||||
setup.status.not_installed.label=n'est pas install\u00E9.
|
||||
setup.status.system_installed.label=est install\u00E9 (syst\u00E8me).
|
||||
setup.status.update_available.label=a une mise \u00E0 jour disponible.
|
||||
setup.subtitle_extractor.choice.label=Extracteur de sous-titres
|
||||
setup.subtitle_translator.choice.label=Traducteur de sous-titres
|
||||
setup.translator.choice.label=Traducteur de sous-titres
|
||||
setup.uninstall.error.label=Une erreur s''est produite lors de la d\u00E9sinstallation : {0}
|
||||
setup.uninstall.error.title=Erreur de d\u00E9sinstallation
|
||||
setup.update.error.label=Une erreur s''est produite lors de la mise \u00E0 jour : {0}
|
||||
setup.update.error.title=Erreur de mise \u00E0 jour
|
||||
setup.update.error.title=Erreur de mise \u00E0 jour
|
||||
setup.video_converter.choice.label=Convertisseur de vid\u00E9o
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<properties>
|
||||
<controlsfx.version>11.2.1</controlsfx.version>
|
||||
<javafx.version>22.0.2</javafx.version>
|
||||
<javafx.version>23</javafx.version>
|
||||
<testfx.version>4.0.18</testfx.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ public class FXMediaController implements MediaController {
|
||||
private Label volumeValueLabel;
|
||||
|
||||
private final FXMediaModel model;
|
||||
private final FXMediaBinder binder;
|
||||
private final TimeFormatter timeFormatter;
|
||||
private final Image playImage;
|
||||
private final Image pauseImage;
|
||||
@@ -71,10 +70,10 @@ public class FXMediaController implements MediaController {
|
||||
FXMediaController(final FXMediaModel model, final FXMediaBinder binder, final TimeFormatter timeFormatter,
|
||||
@Play final Image playImage, @Pause final Image pauseImage) {
|
||||
this.model = requireNonNull(model);
|
||||
this.binder = requireNonNull(binder);
|
||||
this.timeFormatter = requireNonNull(timeFormatter);
|
||||
this.playImage = requireNonNull(playImage);
|
||||
this.pauseImage = requireNonNull(pauseImage);
|
||||
binder.createBindings();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -116,7 +115,6 @@ public class FXMediaController implements MediaController {
|
||||
|
||||
stackPane.widthProperty().addListener((observable, oldValue, newValue) -> resizeMediaView());
|
||||
stackPane.heightProperty().addListener((observable, oldValue, newValue) -> resizeMediaView());
|
||||
binder.createBindings();
|
||||
}
|
||||
|
||||
private void resizeMediaView() {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.github.gtache.autosubtitle.gui.parameters.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.gui.fx.FXBinder;
|
||||
import com.github.gtache.autosubtitle.gui.setup.fx.FXSetupModel;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Binds the subtitles model
|
||||
*/
|
||||
@Singleton
|
||||
public class FXParametersBinder implements FXBinder {
|
||||
|
||||
private final FXParametersModel parametersModel;
|
||||
private final FXSetupModel setupModel;
|
||||
|
||||
@Inject
|
||||
FXParametersBinder(final FXParametersModel parametersModel, final FXSetupModel setupModel) {
|
||||
this.parametersModel = requireNonNull(parametersModel);
|
||||
this.setupModel = requireNonNull(setupModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBindings() {
|
||||
setupModel.selectedToolProperty(ToolType.SUBTITLE_EXTRACTOR).addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
parametersModel.extractionModelProviderProperty().set(parametersModel.availableExtractionModelProviders().get(newValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.github.gtache.autosubtitle.gui.fx.AbstractFXController;
|
||||
import com.github.gtache.autosubtitle.gui.parameters.ParametersController;
|
||||
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TextFormatter;
|
||||
@@ -47,13 +47,12 @@ public class FXParametersController extends AbstractFXController implements Para
|
||||
|
||||
private final FXParametersModel model;
|
||||
private final Preferences preferences;
|
||||
private final ExtractionModelProvider extractionModelProvider;
|
||||
|
||||
@Inject
|
||||
FXParametersController(final FXParametersModel model, final Preferences preferences, final ExtractionModelProvider extractionModelProvider) {
|
||||
FXParametersController(final FXParametersModel model, final FXParametersBinder binder, final Preferences preferences) {
|
||||
this.model = requireNonNull(model);
|
||||
this.preferences = requireNonNull(preferences);
|
||||
this.extractionModelProvider = requireNonNull(extractionModelProvider);
|
||||
binder.createBindings();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -83,17 +82,31 @@ public class FXParametersController extends AbstractFXController implements Para
|
||||
maxLinesField.textProperty().bindBidirectional(model.maxLinesProperty(), new NumberStringConverter());
|
||||
|
||||
loadPreferences();
|
||||
|
||||
model.extractionModelProviderProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
final var name = newValue.getClass().getSimpleName();
|
||||
Platform.runLater(() -> {
|
||||
final var modelName = preferences.get(name + ".extractionModel", model.extractionModel().name());
|
||||
final var loadedModel = newValue.getExtractionModel(modelName);
|
||||
model.setExtractionModel(loadedModel);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadPreferences() {
|
||||
final var extractionModel = preferences.get("extractionModel", model.extractionModel().name());
|
||||
final var outputFormat = preferences.get("outputFormat", model.outputFormat().name());
|
||||
final var fontFamily = preferences.get("fontName", model.fontName());
|
||||
final var fontSize = preferences.getInt("fontSize", model.fontSize());
|
||||
final var maxLineLength = preferences.getInt("maxLineLength", model.maxLineLength());
|
||||
final var maxLines = preferences.getInt("maxLines", model.maxLines());
|
||||
|
||||
model.setExtractionModel(extractionModelProvider.getExtractionModel(extractionModel));
|
||||
final var extractionModelProvider = model.extractionModelProviderProperty().get();
|
||||
final var name = extractionModelProvider.getClass().getSimpleName();
|
||||
final var modelName = preferences.get(name + ".extractionModel", model.extractionModel().name());
|
||||
|
||||
model.setExtractionModel(extractionModelProvider.getExtractionModel(modelName));
|
||||
model.setOutputFormat(OutputFormat.valueOf(outputFormat));
|
||||
model.setFontName(fontFamily);
|
||||
model.setFontSize(fontSize);
|
||||
@@ -106,7 +119,7 @@ public class FXParametersController extends AbstractFXController implements Para
|
||||
@Override
|
||||
public void save() {
|
||||
logger.info("Saving preferences");
|
||||
preferences.put("extractionModel", model.extractionModel().name());
|
||||
preferences.put(model.extractionModelProviderProperty().get().getClass().getSimpleName() + ".extractionModel", model.extractionModel().name());
|
||||
preferences.put("outputFormat", model.outputFormat().name());
|
||||
preferences.put("fontName", model.fontName());
|
||||
preferences.putInt("fontSize", model.fontSize());
|
||||
|
||||
@@ -21,9 +21,11 @@ import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FX implementation of {@link ParametersModel}
|
||||
@@ -31,6 +33,8 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class FXParametersModel implements ParametersModel {
|
||||
|
||||
private final ObservableMap<String, ExtractionModelProvider> availableExtractionModelProviders;
|
||||
private final ObjectProperty<ExtractionModelProvider> extractionModelProvider;
|
||||
private final ObservableList<ExtractionModel> availableExtractionModels;
|
||||
private final ObjectProperty<ExtractionModel> extractionModel;
|
||||
private final ObservableList<OutputFormat> availableOutputFormats;
|
||||
@@ -43,10 +47,12 @@ public class FXParametersModel implements ParametersModel {
|
||||
private final IntegerProperty maxLines;
|
||||
|
||||
@Inject
|
||||
FXParametersModel(final ExtractionModelProvider extractionModelProvider, @FontName final String defaultFontFamily,
|
||||
FXParametersModel(final Map<String, ExtractionModelProvider> extractionModelProviders, final ExtractionModelProvider defaultProvider, @FontName final String defaultFontFamily,
|
||||
@FontSize final int defaultFontSize, @MaxLineLength final int defaultMaxLineLength, @MaxLines final int defaultMaxLines) {
|
||||
this.availableExtractionModels = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList(extractionModelProvider.getAvailableExtractionModels()));
|
||||
this.extractionModel = new SimpleObjectProperty<>(extractionModelProvider.getDefaultExtractionModel());
|
||||
this.availableExtractionModelProviders = FXCollections.unmodifiableObservableMap(FXCollections.observableMap(extractionModelProviders));
|
||||
this.extractionModelProvider = new SimpleObjectProperty<>(defaultProvider);
|
||||
this.availableExtractionModels = FXCollections.observableArrayList(defaultProvider.getAvailableExtractionModels());
|
||||
this.extractionModel = new SimpleObjectProperty<>(defaultProvider.getDefaultExtractionModel());
|
||||
this.availableOutputFormats = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList(OutputFormat.SRT));
|
||||
this.outputFormat = new SimpleObjectProperty<>(OutputFormat.SRT);
|
||||
this.availableFontFamilies = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList("Arial"));
|
||||
@@ -57,6 +63,12 @@ public class FXParametersModel implements ParametersModel {
|
||||
this.maxLines = new SimpleIntegerProperty(defaultMaxLines);
|
||||
|
||||
font.bind(Bindings.createObjectBinding(() -> new FontImpl(fontName(), fontSize()), fontName, fontSize));
|
||||
extractionModelProvider.addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
availableExtractionModels.setAll(newValue.getAvailableExtractionModels());
|
||||
extractionModel.set(newValue.getDefaultExtractionModel());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,4 +178,12 @@ public class FXParametersModel implements ParametersModel {
|
||||
public IntegerProperty maxLinesProperty() {
|
||||
return maxLines;
|
||||
}
|
||||
|
||||
ObservableMap<String, ExtractionModelProvider> availableExtractionModelProviders() {
|
||||
return availableExtractionModelProviders;
|
||||
}
|
||||
|
||||
ObjectProperty<ExtractionModelProvider> extractionModelProviderProperty() {
|
||||
return extractionModelProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.github.gtache.autosubtitle.gui.setup.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.gui.fx.AbstractFXController;
|
||||
import com.github.gtache.autosubtitle.gui.setup.SetupController;
|
||||
import com.github.gtache.autosubtitle.modules.setup.impl.SubtitleExtractorSetup;
|
||||
import com.github.gtache.autosubtitle.modules.setup.impl.TranslatorSetup;
|
||||
import com.github.gtache.autosubtitle.modules.setup.impl.VideoConverterSetup;
|
||||
import com.github.gtache.autosubtitle.setup.SetupEvent;
|
||||
import com.github.gtache.autosubtitle.setup.SetupException;
|
||||
import com.github.gtache.autosubtitle.setup.SetupListener;
|
||||
@@ -12,26 +10,29 @@ import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuButton;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.RowConstraints;
|
||||
import javafx.stage.Window;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.controlsfx.control.PrefixSelectionComboBox;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Arrays;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* FX implementation of {@link SetupController}
|
||||
@@ -41,233 +42,81 @@ public class FXSetupController extends AbstractFXController implements SetupCont
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(FXSetupController.class);
|
||||
|
||||
@FXML
|
||||
private GridPane setupGrid;
|
||||
@FXML
|
||||
private ResourceBundle resources;
|
||||
@FXML
|
||||
private Label converterNameLabel;
|
||||
@FXML
|
||||
private Label converterStatusLabel;
|
||||
@FXML
|
||||
private Label extractorNameLabel;
|
||||
@FXML
|
||||
private Label extractorStatusLabel;
|
||||
@FXML
|
||||
private Label translatorNameLabel;
|
||||
@FXML
|
||||
private Label translatorStatusLabel;
|
||||
@FXML
|
||||
private MenuButton converterButton;
|
||||
@FXML
|
||||
private MenuButton extractorButton;
|
||||
@FXML
|
||||
private MenuButton translatorButton;
|
||||
@FXML
|
||||
private ProgressBar converterProgress;
|
||||
@FXML
|
||||
private ProgressBar extractorProgress;
|
||||
@FXML
|
||||
private ProgressBar translatorProgress;
|
||||
@FXML
|
||||
private Label converterProgressLabel;
|
||||
@FXML
|
||||
private Label extractorProgressLabel;
|
||||
@FXML
|
||||
private Label translatorProgressLabel;
|
||||
|
||||
private final FXSetupModel model;
|
||||
private final SetupManager converterManager;
|
||||
private final SetupManager extractorManager;
|
||||
private final SetupManager translatorManager;
|
||||
|
||||
private final Map<SetupManager, ObjectProperty<SetupStatus>> statusMap;
|
||||
private final Map<SetupManager, StringProperty> setupProgressMessageMap;
|
||||
private final Map<SetupManager, DoubleProperty> setupProgressMap;
|
||||
private final Preferences preferences;
|
||||
|
||||
@Inject
|
||||
FXSetupController(final FXSetupModel model,
|
||||
@VideoConverterSetup final SetupManager converterManager,
|
||||
@SubtitleExtractorSetup final SetupManager extractorManager,
|
||||
@TranslatorSetup final SetupManager translatorManager) {
|
||||
this.model = Objects.requireNonNull(model);
|
||||
this.converterManager = Objects.requireNonNull(converterManager);
|
||||
this.extractorManager = Objects.requireNonNull(extractorManager);
|
||||
this.translatorManager = Objects.requireNonNull(translatorManager);
|
||||
statusMap = HashMap.newHashMap(3);
|
||||
setupProgressMessageMap = HashMap.newHashMap(3);
|
||||
setupProgressMap = HashMap.newHashMap(3);
|
||||
FXSetupController(final FXSetupModel model, final Preferences preferences) {
|
||||
this.model = requireNonNull(model);
|
||||
this.preferences = requireNonNull(preferences);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void initialize() {
|
||||
statusMap.put(converterManager, model.videoConverterStatusProperty());
|
||||
statusMap.put(extractorManager, model.subtitleExtractorStatusProperty());
|
||||
statusMap.put(translatorManager, model.translatorStatusProperty());
|
||||
setupProgressMessageMap.put(converterManager, model.videoConverterSetupProgressLabelProperty());
|
||||
setupProgressMessageMap.put(extractorManager, model.subtitleExtractorSetupProgressLabelProperty());
|
||||
setupProgressMessageMap.put(translatorManager, model.translatorSetupProgressLabelProperty());
|
||||
setupProgressMap.put(converterManager, model.videoConverterSetupProgressProperty());
|
||||
setupProgressMap.put(extractorManager, model.subtitleExtractorSetupProgressProperty());
|
||||
setupProgressMap.put(translatorManager, model.translatorSetupProgressProperty());
|
||||
|
||||
bindMenu(converterButton, converterManager);
|
||||
bindMenu(extractorButton, extractorManager);
|
||||
bindMenu(translatorButton, translatorManager);
|
||||
|
||||
model.setSubtitleExtractorStatus(extractorManager.status());
|
||||
model.setVideoConverterStatus(converterManager.status());
|
||||
model.setTranslatorStatus(translatorManager.status());
|
||||
|
||||
converterNameLabel.setText(converterManager.name());
|
||||
extractorNameLabel.setText(extractorManager.name());
|
||||
translatorNameLabel.setText(translatorManager.name());
|
||||
bindLabelStatus(converterStatusLabel, model.videoConverterStatusProperty());
|
||||
bindLabelStatus(extractorStatusLabel, model.subtitleExtractorStatusProperty());
|
||||
bindLabelStatus(translatorStatusLabel, model.translatorStatusProperty());
|
||||
|
||||
converterProgress.progressProperty().bindBidirectional(model.videoConverterSetupProgressProperty());
|
||||
extractorProgress.progressProperty().bindBidirectional(model.subtitleExtractorSetupProgressProperty());
|
||||
translatorProgress.progressProperty().bindBidirectional(model.translatorSetupProgressProperty());
|
||||
|
||||
converterProgress.visibleProperty().bind(model.videoConverterSetupProgressProperty().greaterThan(-2));
|
||||
extractorProgress.visibleProperty().bind(model.subtitleExtractorSetupProgressProperty().greaterThan(-2));
|
||||
translatorProgress.visibleProperty().bind(model.translatorSetupProgressProperty().greaterThan(-2));
|
||||
|
||||
converterProgressLabel.textProperty().bind(model.videoConverterSetupProgressLabelProperty());
|
||||
extractorProgressLabel.textProperty().bind(model.subtitleExtractorSetupProgressLabelProperty());
|
||||
translatorProgressLabel.textProperty().bind(model.translatorSetupProgressLabelProperty());
|
||||
|
||||
converterProgressLabel.visibleProperty().bind(converterProgress.visibleProperty());
|
||||
extractorProgressLabel.visibleProperty().bind(extractorProgress.visibleProperty());
|
||||
translatorProgressLabel.visibleProperty().bind(translatorProgress.visibleProperty());
|
||||
createGridRows();
|
||||
Arrays.stream(ToolType.values()).forEach(t -> model.selectedToolProperty(t)
|
||||
.addListener((observable, oldValue, newValue) -> saveSelectedTool(t, newValue)));
|
||||
loadPreferences();
|
||||
}
|
||||
|
||||
private void bindMenu(final MenuButton button, final SetupManager setupManager) {
|
||||
button.disableProperty().bind(Bindings.isEmpty(button.getItems()));
|
||||
statusMap.get(setupManager).addListener((observable, oldValue, newValue) -> {
|
||||
button.getItems().clear();
|
||||
switch (newValue) {
|
||||
case NOT_INSTALLED -> {
|
||||
final var installItem = new MenuItem(resources.getString("setup.menu.install.label"));
|
||||
installItem.setOnAction(e -> tryInstall(setupManager));
|
||||
button.getItems().add(installItem);
|
||||
}
|
||||
case BUNDLE_INSTALLED -> {
|
||||
final var reinstallItem = new MenuItem(resources.getString("setup.menu.reinstall.label"));
|
||||
reinstallItem.setOnAction(e -> tryReinstall(setupManager));
|
||||
final var uninstallItem = new MenuItem(resources.getString("setup.menu.uninstall.label"));
|
||||
uninstallItem.setOnAction(e -> tryUninstall(setupManager));
|
||||
button.getItems().addAll(reinstallItem, uninstallItem);
|
||||
}
|
||||
case UPDATE_AVAILABLE -> {
|
||||
final var updateItem = new MenuItem(resources.getString("setup.menu.update.label"));
|
||||
updateItem.setOnAction(e -> tryUpdate(setupManager));
|
||||
final var reinstallItem = new MenuItem(resources.getString("setup.menu.reinstall.label"));
|
||||
reinstallItem.setOnAction(e -> tryReinstall(setupManager));
|
||||
final var uninstallItem = new MenuItem(resources.getString("setup.menu.uninstall.label"));
|
||||
uninstallItem.setOnAction(e -> tryUninstall(setupManager));
|
||||
button.getItems().addAll(updateItem, reinstallItem, uninstallItem);
|
||||
}
|
||||
case null, default -> {
|
||||
// Do nothing, buttons are cleared
|
||||
}
|
||||
private void saveSelectedTool(final ToolType type, final String value) {
|
||||
if (value != null) {
|
||||
preferences.put(type.name(), value);
|
||||
try {
|
||||
preferences.flush();
|
||||
} catch (final BackingStoreException e) {
|
||||
logger.error("Error saving preferences", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void bindLabelStatus(final Label label, final ObjectProperty<SetupStatus> status) {
|
||||
label.textProperty().bind(Bindings.createStringBinding(() -> resources.getString("setup.status." + status.get().name().toLowerCase() + ".label"), status));
|
||||
private void loadPreferences() {
|
||||
for (final var type : ToolType.values()) {
|
||||
final var value = preferences.get(type.name(), model.selectedTool(type));
|
||||
model.selectedToolProperty(type).set(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installVideoConverter() {
|
||||
tryInstall(converterManager);
|
||||
public void install(final ToolType type) {
|
||||
trySetup(type, SetupManager::install, "install");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallVideoConverter() {
|
||||
tryUninstall(converterManager);
|
||||
public void uninstall(final ToolType type) {
|
||||
trySetup(type, SetupManager::uninstall, "uninstall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVideoConverter() {
|
||||
tryUpdate(converterManager);
|
||||
public void update(final ToolType type) {
|
||||
trySetup(type, SetupManager::update, "update");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reinstallVideoConverter() {
|
||||
tryReinstall(converterManager);
|
||||
public void reinstall(final ToolType type) {
|
||||
trySetup(type, SetupManager::reinstall, "reinstall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installSubtitleExtractor() {
|
||||
tryInstall(extractorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallSubtitleExtractor() {
|
||||
tryUninstall(extractorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSubtitleExtractor() {
|
||||
tryUpdate(extractorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reinstallSubtitleExtractor() {
|
||||
tryReinstall(extractorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installTranslator() {
|
||||
tryInstall(translatorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstallTranslator() {
|
||||
tryUninstall(translatorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTranslator() {
|
||||
tryUpdate(translatorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reinstallTranslator() {
|
||||
tryReinstall(translatorManager);
|
||||
}
|
||||
|
||||
private void tryInstall(final SetupManager manager) {
|
||||
trySetup(manager, SetupManager::install, "install");
|
||||
}
|
||||
|
||||
private void tryUninstall(final SetupManager manager) {
|
||||
trySetup(manager, SetupManager::uninstall, "uninstall");
|
||||
}
|
||||
|
||||
private void tryReinstall(final SetupManager manager) {
|
||||
trySetup(manager, SetupManager::reinstall, "reinstall");
|
||||
}
|
||||
|
||||
private void tryUpdate(final SetupManager manager) {
|
||||
trySetup(manager, SetupManager::update, "update");
|
||||
}
|
||||
|
||||
private void trySetup(final SetupManager manager, final SetupConsumer consumer, final String operation) {
|
||||
private void trySetup(final ToolType type, final SetupConsumer consumer, final String operation) {
|
||||
final var manager = model.selectedSetupManager(type);
|
||||
manager.addListener(this);
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
consumer.accept(manager);
|
||||
Platform.runLater(() -> {
|
||||
statusMap.get(manager).set(manager.status());
|
||||
setupProgressMap.get(manager).set(-2);
|
||||
model.setManagerStatus(type, manager.status());
|
||||
model.setSetupProgress(type, -2);
|
||||
});
|
||||
} catch (final SetupException e) {
|
||||
logger.error("Error {}ing {}", operation, manager.name(), e);
|
||||
Platform.runLater(() -> {
|
||||
statusMap.get(manager).set(SetupStatus.ERRORED);
|
||||
setupProgressMap.get(manager).set(-2);
|
||||
model.setManagerStatus(type, SetupStatus.ERRORED);
|
||||
model.setSetupProgress(type, -2);
|
||||
showErrorDialog(resources.getString("setup." + operation + ".error.title"),
|
||||
MessageFormat.format(resources.getString("setup." + operation + ".error.label"), e.getMessage()));
|
||||
});
|
||||
@@ -300,15 +149,105 @@ public class FXSetupController extends AbstractFXController implements SetupCont
|
||||
|
||||
private void onAction(final SetupEvent event, final String display) {
|
||||
final var manager = event.setupManager();
|
||||
final var property = setupProgressMessageMap.get(manager);
|
||||
final var type = manager.type();
|
||||
final var progress = event.progress();
|
||||
final var progressProperty = setupProgressMap.get(manager);
|
||||
Platform.runLater(() -> {
|
||||
property.set(display);
|
||||
progressProperty.set(progress);
|
||||
model.setSetupProgressLabel(type, display);
|
||||
model.setSetupProgress(type, progress);
|
||||
});
|
||||
}
|
||||
|
||||
private void createGridRows() {
|
||||
for (final var value : ToolType.values()) {
|
||||
createGridRow(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void createGridRow(final ToolType type) {
|
||||
if (!model.availableSetupManagers(type).isEmpty()) {
|
||||
createSelectionRow(type);
|
||||
createProgressRow(type);
|
||||
}
|
||||
}
|
||||
|
||||
private void createSelectionRow(final ToolType type) {
|
||||
final var label = new Label(resources.getString("setup." + type.name().toLowerCase() + ".choice.label"));
|
||||
final var comboBox = new PrefixSelectionComboBox<SetupManager>();
|
||||
comboBox.setItems(model.availableSetupManagers(type));
|
||||
comboBox.setConverter(new SetupManagerStringConverter());
|
||||
comboBox.valueProperty().bindBidirectional(model.selectedSetupManagerProperty(type));
|
||||
comboBox.disableProperty().bind(model.setupInProgressProperty(type));
|
||||
|
||||
final var rowIndex = setupGrid.getRowCount() - 1;
|
||||
final var constraints = new RowConstraints();
|
||||
constraints.setFillHeight(true);
|
||||
constraints.setVgrow(Priority.SOMETIMES);
|
||||
setupGrid.getRowConstraints().add(rowIndex, constraints);
|
||||
setupGrid.add(label, 0, rowIndex);
|
||||
setupGrid.add(comboBox, 1, rowIndex);
|
||||
}
|
||||
|
||||
private void createProgressRow(final ToolType type) {
|
||||
final var statusLabel = new Label();
|
||||
final var installationButton = new MenuButton(resources.getString("setup.menu.label"));
|
||||
final var progressBar = new ProgressBar();
|
||||
final var progressLabel = new Label();
|
||||
statusLabel.textProperty().bind(model.managerStatusProperty(type).map(s -> resources.getString("setup.status." + s.name().toLowerCase() + ".label")));
|
||||
progressLabel.textProperty().bind(model.setupProgressLabelProperty(type));
|
||||
progressLabel.visibleProperty().bind(model.setupInProgressProperty(type));
|
||||
progressBar.progressProperty().bind(model.setupProgressProperty(type));
|
||||
progressBar.visibleProperty().bind(model.setupInProgressProperty(type));
|
||||
installationButton.disableProperty().bind(model.setupInProgressProperty(type).or(Bindings.isEmpty(installationButton.getItems())));
|
||||
bindMenu(installationButton, type);
|
||||
fillMenu(installationButton, type);
|
||||
|
||||
final var rowIndex = setupGrid.getRowCount() - 1;
|
||||
final var constraints = new RowConstraints();
|
||||
constraints.setFillHeight(true);
|
||||
constraints.setVgrow(Priority.SOMETIMES);
|
||||
setupGrid.getRowConstraints().add(rowIndex, constraints);
|
||||
setupGrid.add(statusLabel, 1, rowIndex);
|
||||
setupGrid.add(installationButton, 2, rowIndex);
|
||||
setupGrid.add(progressBar, 3, rowIndex);
|
||||
setupGrid.add(progressLabel, 4, rowIndex);
|
||||
}
|
||||
|
||||
private void bindMenu(final MenuButton button, final ToolType type) {
|
||||
model.managerStatusProperty(type).addListener((observable, oldValue, newValue) -> fillMenu(button, type));
|
||||
}
|
||||
|
||||
private void fillMenu(final MenuButton button, final ToolType type) {
|
||||
final var value = model.managerStatus(type);
|
||||
button.getItems().clear();
|
||||
switch (value) {
|
||||
case NOT_INSTALLED -> {
|
||||
final var installItem = new MenuItem(resources.getString("setup.menu.install.label"));
|
||||
installItem.setOnAction(e -> install(type));
|
||||
button.getItems().add(installItem);
|
||||
}
|
||||
case BUNDLE_INSTALLED -> {
|
||||
final var reinstallItem = new MenuItem(resources.getString("setup.menu.reinstall.label"));
|
||||
reinstallItem.setOnAction(e -> reinstall(type));
|
||||
final var uninstallItem = new MenuItem(resources.getString("setup.menu.uninstall.label"));
|
||||
uninstallItem.setOnAction(e -> uninstall(type));
|
||||
button.getItems().addAll(reinstallItem, uninstallItem);
|
||||
}
|
||||
case UPDATE_AVAILABLE -> {
|
||||
final var updateItem = new MenuItem(resources.getString("setup.menu.update.label"));
|
||||
updateItem.setOnAction(e -> update(type));
|
||||
final var reinstallItem = new MenuItem(resources.getString("setup.menu.reinstall.label"));
|
||||
reinstallItem.setOnAction(e -> reinstall(type));
|
||||
final var uninstallItem = new MenuItem(resources.getString("setup.menu.uninstall.label"));
|
||||
uninstallItem.setOnAction(e -> uninstall(type));
|
||||
button.getItems().addAll(updateItem, reinstallItem, uninstallItem);
|
||||
}
|
||||
case null, default -> {
|
||||
// Do nothing, buttons are cleared
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
private interface SetupConsumer {
|
||||
void accept(SetupManager manager) throws SetupException;
|
||||
@@ -321,6 +260,7 @@ public class FXSetupController extends AbstractFXController implements SetupCont
|
||||
|
||||
@Override
|
||||
public Window window() {
|
||||
return converterNameLabel.getScene().getWindow();
|
||||
return setupGrid.getScene().getWindow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
package com.github.gtache.autosubtitle.gui.setup.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.gui.setup.SetupModel;
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FX implementation of {@link SetupModel}
|
||||
@@ -18,152 +27,146 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class FXSetupModel implements SetupModel {
|
||||
|
||||
private final ObjectProperty<SetupStatus> subtitleExtractorStatus;
|
||||
private final DoubleProperty subtitleExtractorSetupProgress;
|
||||
private final StringProperty subtitleExtractorSetupProgressLabel;
|
||||
private final ObjectProperty<SetupStatus> videoConverterStatus;
|
||||
private final DoubleProperty videoConverterSetupProgress;
|
||||
private final StringProperty videoConverterSetupProgressLabel;
|
||||
private final ObjectProperty<SetupStatus> translatorStatus;
|
||||
private final DoubleProperty translatorSetupProgress;
|
||||
private final StringProperty translatorSetupProgressLabel;
|
||||
private final ObservableMap<ToolType, ObservableList<SetupManager>> availableSetupManagers;
|
||||
private final ObservableMap<ToolType, StringProperty> selectedTools;
|
||||
private final ObservableMap<ToolType, ObjectProperty<SetupManager>> selectedSetupManagers;
|
||||
private final ObservableMap<ToolType, ObjectProperty<SetupStatus>> setupStatuses;
|
||||
private final ObservableMap<ToolType, DoubleProperty> setupProgresses;
|
||||
private final ObservableMap<ToolType, StringProperty> setupProgressLabels;
|
||||
private final ObservableMap<ToolType, ReadOnlyBooleanWrapper> setupInProgress;
|
||||
|
||||
@Inject
|
||||
FXSetupModel() {
|
||||
this.subtitleExtractorStatus = new SimpleObjectProperty<>(SetupStatus.ERRORED);
|
||||
this.subtitleExtractorSetupProgress = new SimpleDoubleProperty(-2);
|
||||
this.subtitleExtractorSetupProgressLabel = new SimpleStringProperty("");
|
||||
this.videoConverterStatus = new SimpleObjectProperty<>(SetupStatus.ERRORED);
|
||||
this.videoConverterSetupProgress = new SimpleDoubleProperty(-2);
|
||||
this.videoConverterSetupProgressLabel = new SimpleStringProperty("");
|
||||
this.translatorStatus = new SimpleObjectProperty<>(SetupStatus.ERRORED);
|
||||
this.translatorSetupProgress = new SimpleDoubleProperty(-2);
|
||||
this.translatorSetupProgressLabel = new SimpleStringProperty("");
|
||||
FXSetupModel(final Map<ToolType, Map<String, SetupManager>> setupManagers,
|
||||
final Map<ToolType, SetupManager> defaultManagers) {
|
||||
final var tmpAvailableSetupManagers = FXCollections.<ToolType, ObservableList<SetupManager>>observableHashMap();
|
||||
final var tmpSelectedTools = FXCollections.<ToolType, StringProperty>observableHashMap();
|
||||
final var tmpSelectedSetupManagers = FXCollections.<ToolType, ObjectProperty<SetupManager>>observableHashMap();
|
||||
final var tmpSetupStatuses = FXCollections.<ToolType, ObjectProperty<SetupStatus>>observableHashMap();
|
||||
final var tmpSetupProgresses = FXCollections.<ToolType, DoubleProperty>observableHashMap();
|
||||
final var tmpSetupProgressLabels = FXCollections.<ToolType, StringProperty>observableHashMap();
|
||||
final var tmpSetupEditables = FXCollections.<ToolType, ReadOnlyBooleanWrapper>observableHashMap();
|
||||
setupManagers.forEach((type, managers) -> {
|
||||
tmpAvailableSetupManagers.put(type, getUnmodifiableObservableList(managers.values()));
|
||||
tmpSelectedTools.put(type, new SimpleStringProperty(getKeyForValue(managers, defaultManagers.get(type))));
|
||||
tmpSelectedSetupManagers.put(type, new SimpleObjectProperty<>());
|
||||
tmpSetupStatuses.put(type, new SimpleObjectProperty<>(SetupStatus.ERRORED));
|
||||
tmpSetupProgresses.put(type, new SimpleDoubleProperty(-2));
|
||||
tmpSetupProgressLabels.put(type, new SimpleStringProperty(""));
|
||||
tmpSetupEditables.put(type, new ReadOnlyBooleanWrapper(false));
|
||||
});
|
||||
this.availableSetupManagers = FXCollections.unmodifiableObservableMap(tmpAvailableSetupManagers);
|
||||
this.selectedTools = FXCollections.unmodifiableObservableMap(tmpSelectedTools);
|
||||
this.selectedSetupManagers = FXCollections.unmodifiableObservableMap(tmpSelectedSetupManagers);
|
||||
this.setupStatuses = FXCollections.unmodifiableObservableMap(tmpSetupStatuses);
|
||||
this.setupProgresses = FXCollections.unmodifiableObservableMap(tmpSetupProgresses);
|
||||
this.setupProgressLabels = FXCollections.unmodifiableObservableMap(tmpSetupProgressLabels);
|
||||
this.setupInProgress = FXCollections.unmodifiableObservableMap(tmpSetupEditables);
|
||||
|
||||
selectedSetupManagers.forEach((type, value) -> value.addListener((observable, oldValue, newValue) ->
|
||||
{
|
||||
setupStatuses.get(type).set(newValue == null ? SetupStatus.ERRORED : newValue.status());
|
||||
selectedTools.get(type).set(newValue == null ?
|
||||
getKeyForValue(setupManagers.get(type), defaultManagers.get(type)) :
|
||||
getKeyForValue(setupManagers.get(type), newValue));
|
||||
}));
|
||||
selectedTools.forEach((type, value) -> value.addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
final var manager = setupManagers.get(type).get(newValue);
|
||||
if (manager != null) {
|
||||
setSelectedSetupManager(type, manager);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
setupInProgress.forEach((type, value) -> value.bind(setupProgresses.get(type).greaterThan(-2)));
|
||||
|
||||
defaultManagers.forEach(this::setSelectedSetupManager);
|
||||
}
|
||||
|
||||
private static String getKeyForValue(final Map<String, ? extends SetupManager> managers, final SetupManager manager) {
|
||||
return managers.entrySet().stream().filter(e -> e.getValue() == manager).findFirst().orElseThrow().getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetupStatus subtitleExtractorStatus() {
|
||||
return subtitleExtractorStatus.get();
|
||||
public ObservableList<SetupManager> availableSetupManagers(final ToolType type) {
|
||||
return this.availableSetupManagers.getOrDefault(type, FXCollections.emptyObservableList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubtitleExtractorStatus(final SetupStatus status) {
|
||||
subtitleExtractorStatus.set(status);
|
||||
}
|
||||
|
||||
ObjectProperty<SetupStatus> subtitleExtractorStatusProperty() {
|
||||
return subtitleExtractorStatus;
|
||||
public SetupManager selectedSetupManager(final ToolType type) {
|
||||
return this.selectedSetupManagers.get(type).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double subtitleExtractorSetupProgress() {
|
||||
return subtitleExtractorSetupProgress.get();
|
||||
public void setSelectedSetupManager(final ToolType type, final SetupManager manager) {
|
||||
this.selectedSetupManagers.get(type).set(manager);
|
||||
}
|
||||
|
||||
ObjectProperty<SetupManager> selectedSetupManagerProperty(final ToolType type) {
|
||||
return this.selectedSetupManagers.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubtitleExtractorSetupProgress(final double progress) {
|
||||
subtitleExtractorSetupProgress.set(progress);
|
||||
public String selectedTool(final ToolType type) {
|
||||
return this.selectedTools.get(type).get();
|
||||
}
|
||||
|
||||
DoubleProperty subtitleExtractorSetupProgressProperty() {
|
||||
return subtitleExtractorSetupProgress;
|
||||
public StringProperty selectedToolProperty(final ToolType type) {
|
||||
return this.selectedTools.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String subtitleExtractorSetupProgressLabel() {
|
||||
return subtitleExtractorSetupProgressLabel.get();
|
||||
public SetupStatus managerStatus(final ToolType type) {
|
||||
return this.setupStatuses.get(type).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubtitleExtractorSetupProgressLabel(final String label) {
|
||||
subtitleExtractorSetupProgressLabel.set(label);
|
||||
public void setManagerStatus(final ToolType type, final SetupStatus status) {
|
||||
this.setupStatuses.get(type).set(status);
|
||||
}
|
||||
|
||||
StringProperty subtitleExtractorSetupProgressLabelProperty() {
|
||||
return subtitleExtractorSetupProgressLabel;
|
||||
ObjectProperty<SetupStatus> managerStatusProperty(final ToolType type) {
|
||||
return this.setupStatuses.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetupStatus videoConverterStatus() {
|
||||
return videoConverterStatus.get();
|
||||
public double setupProgress(final ToolType type) {
|
||||
return this.setupProgresses.get(type).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoConverterStatus(final SetupStatus status) {
|
||||
videoConverterStatus.set(status);
|
||||
public void setSetupProgress(final ToolType type, final double progress) {
|
||||
this.setupProgresses.get(type).set(progress);
|
||||
}
|
||||
|
||||
ObjectProperty<SetupStatus> videoConverterStatusProperty() {
|
||||
return videoConverterStatus;
|
||||
DoubleProperty setupProgressProperty(final ToolType type) {
|
||||
return this.setupProgresses.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double videoConverterSetupProgress() {
|
||||
return videoConverterSetupProgress.get();
|
||||
public String setupProgressLabel(final ToolType type) {
|
||||
return this.setupProgressLabels.get(type).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoConverterSetupProgress(final double progress) {
|
||||
videoConverterSetupProgress.set(progress);
|
||||
public void setSetupProgressLabel(final ToolType type, final String label) {
|
||||
this.setupProgressLabels.get(type).set(label);
|
||||
}
|
||||
|
||||
DoubleProperty videoConverterSetupProgressProperty() {
|
||||
return videoConverterSetupProgress;
|
||||
StringProperty setupProgressLabelProperty(final ToolType type) {
|
||||
return this.setupProgressLabels.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String videoConverterSetupProgressLabel() {
|
||||
return videoConverterSetupProgressLabel.get();
|
||||
public boolean isSetupInProgress(final ToolType type) {
|
||||
return this.setupInProgress.get(type).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoConverterSetupProgressLabel(final String label) {
|
||||
videoConverterSetupProgressLabel.set(label);
|
||||
ReadOnlyBooleanProperty setupInProgressProperty(final ToolType type) {
|
||||
return this.setupInProgress.get(type).getReadOnlyProperty();
|
||||
}
|
||||
|
||||
StringProperty videoConverterSetupProgressLabelProperty() {
|
||||
return videoConverterSetupProgressLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetupStatus translatorStatus() {
|
||||
return translatorStatus.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslatorStatus(final SetupStatus status) {
|
||||
translatorStatus.set(status);
|
||||
}
|
||||
|
||||
ObjectProperty<SetupStatus> translatorStatusProperty() {
|
||||
return translatorStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double translatorSetupProgress() {
|
||||
return translatorSetupProgress.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslatorSetupProgress(final double progress) {
|
||||
translatorSetupProgress.set(progress);
|
||||
}
|
||||
|
||||
DoubleProperty translatorSetupProgressProperty() {
|
||||
return translatorSetupProgress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translatorSetupProgressLabel() {
|
||||
return translatorSetupProgressLabel.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslatorSetupProgressLabel(final String label) {
|
||||
translatorSetupProgressLabel.set(label);
|
||||
}
|
||||
|
||||
StringProperty translatorSetupProgressLabelProperty() {
|
||||
return translatorSetupProgressLabel;
|
||||
private static <T> ObservableList<T> getUnmodifiableObservableList(final Collection<? extends T> collection) {
|
||||
return FXCollections.unmodifiableObservableList(FXCollections.observableArrayList(collection));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.github.gtache.autosubtitle.gui.setup.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
class SetupManagerStringConverter extends StringConverter<SetupManager> {
|
||||
@Override
|
||||
public String toString(final SetupManager object) {
|
||||
return object.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetupManager fromString(final String string) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.github.gtache.autosubtitle.gui.subtitles.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.gui.fx.FXBinder;
|
||||
import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
|
||||
import com.github.gtache.autosubtitle.gui.setup.fx.FXSetupModel;
|
||||
import com.github.gtache.autosubtitle.gui.work.WorkStatus;
|
||||
import com.github.gtache.autosubtitle.gui.work.fx.FXWorkModel;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
|
||||
@@ -14,7 +16,8 @@ import javafx.beans.binding.Bindings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Binds the subtitles model
|
||||
@@ -24,13 +27,15 @@ public class FXSubtitlesBinder implements FXBinder {
|
||||
|
||||
private final FXWorkModel workModel;
|
||||
private final FXParametersModel parametersModel;
|
||||
private final FXSetupModel setupModel;
|
||||
private final FXSubtitlesModel subtitlesModel;
|
||||
|
||||
@Inject
|
||||
FXSubtitlesBinder(final FXWorkModel workModel, final FXParametersModel parametersModel, final FXSubtitlesModel subtitlesModel) {
|
||||
this.workModel = Objects.requireNonNull(workModel);
|
||||
this.parametersModel = Objects.requireNonNull(parametersModel);
|
||||
this.subtitlesModel = Objects.requireNonNull(subtitlesModel);
|
||||
FXSubtitlesBinder(final FXWorkModel workModel, final FXParametersModel parametersModel, final FXSetupModel setupModel, final FXSubtitlesModel subtitlesModel) {
|
||||
this.workModel = requireNonNull(workModel);
|
||||
this.parametersModel = requireNonNull(parametersModel);
|
||||
this.setupModel = requireNonNull(setupModel);
|
||||
this.subtitlesModel = requireNonNull(subtitlesModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,5 +79,12 @@ public class FXSubtitlesBinder implements FXBinder {
|
||||
final var parseOptions = new ParseOptionsImpl(parametersModel.maxLineLength(), parametersModel.maxLines(), parametersModel.font());
|
||||
return new ImportOptionsImpl(parseOptions);
|
||||
}, parametersModel.maxLineLengthProperty(), parametersModel.maxLinesProperty(), parametersModel.fontProperty()));
|
||||
|
||||
|
||||
setupModel.selectedToolProperty(ToolType.TRANSLATOR).addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
subtitlesModel.translatorProperty().set(subtitlesModel.availableTranslators().get(newValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
|
||||
import com.github.gtache.autosubtitle.translation.TranslationException;
|
||||
import com.github.gtache.autosubtitle.translation.Translator;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
@@ -87,21 +86,18 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
|
||||
private TableColumn<ObservableSubtitleImpl, String> textColumn;
|
||||
|
||||
private final FXSubtitlesModel model;
|
||||
private final FXSubtitlesBinder binder;
|
||||
private final SubtitleImporterExporter<?> importerExporter;
|
||||
private final TimeFormatter timeFormatter;
|
||||
private final List<String> subtitleExtensions;
|
||||
private final Translator<?> translator;
|
||||
|
||||
@Inject
|
||||
FXSubtitlesController(final FXSubtitlesModel model, final FXSubtitlesBinder binder, final SubtitleImporterExporter importerExporter, final TimeFormatter timeFormatter,
|
||||
final Translator translator) {
|
||||
FXSubtitlesController(final FXSubtitlesModel model, final FXSubtitlesBinder binder,
|
||||
final SubtitleImporterExporter importerExporter, final TimeFormatter timeFormatter) {
|
||||
this.model = requireNonNull(model);
|
||||
this.binder = requireNonNull(binder);
|
||||
this.importerExporter = requireNonNull(importerExporter);
|
||||
this.timeFormatter = requireNonNull(timeFormatter);
|
||||
this.subtitleExtensions = importerExporter.supportedSingleFileExtensions().stream().map(c -> "*." + c).sorted().toList();
|
||||
this.translator = requireNonNull(translator);
|
||||
binder.createBindings();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -135,7 +131,6 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
|
||||
});
|
||||
|
||||
translationsCombobox.setOnAction(e -> translateToNewLanguage());
|
||||
binder.createBindings();
|
||||
}
|
||||
|
||||
private void translateToNewLanguage() {
|
||||
@@ -149,10 +144,10 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
|
||||
if (model.selectedCollection() == null) {
|
||||
return null;
|
||||
} else {
|
||||
return translator.translate(model.selectedCollection(), value);
|
||||
return model.translatorProperty().get().translate(model.selectedCollection(), value);
|
||||
}
|
||||
} else {
|
||||
return translator.translate(mainCollection, value);
|
||||
return model.translatorProperty().get().translate(mainCollection, value);
|
||||
}
|
||||
} catch (final TranslationException ex) {
|
||||
throw new CompletionException(ex);
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.github.gtache.autosubtitle.subtitle.ExportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
|
||||
import com.github.gtache.autosubtitle.translation.Translator;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@@ -22,6 +23,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FX implementation of {@link SubtitlesModel}
|
||||
@@ -39,6 +41,8 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
|
||||
private final ObjectProperty<ObservableSubtitleCollectionImpl> selectedCollection;
|
||||
private final ObservableList<ObservableSubtitleImpl> selectedSubtitles;
|
||||
private final ObjectProperty<ObservableSubtitleImpl> selectedSubtitle;
|
||||
private final ObservableMap<String, Translator<?>> availableTranslators;
|
||||
private final ObjectProperty<Translator<?>> translator;
|
||||
|
||||
private final BooleanProperty canLoadSubtitles;
|
||||
private final BooleanProperty canAddSubtitle;
|
||||
@@ -50,7 +54,8 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
|
||||
private final ObjectProperty<ImportOptions> importOptions;
|
||||
|
||||
@Inject
|
||||
FXSubtitlesModel() {
|
||||
FXSubtitlesModel(final Map<String, Translator<?>> translators, final Translator defaultTranslator) {
|
||||
this.availableTranslators = FXCollections.unmodifiableObservableMap(FXCollections.observableMap(translators));
|
||||
this.availableVideoLanguages = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList(Arrays.stream(Language.values())
|
||||
.sorted((o1, o2) -> {
|
||||
if (o1 == Language.AUTO) {
|
||||
@@ -78,6 +83,7 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
|
||||
this.isTranslating = new SimpleBooleanProperty(false);
|
||||
this.exportOptions = new SimpleObjectProperty<>();
|
||||
this.importOptions = new SimpleObjectProperty<>();
|
||||
this.translator = new SimpleObjectProperty<>(defaultTranslator);
|
||||
|
||||
canSaveSubtitles.bind(Bindings.isNotEmpty(collections));
|
||||
collections.addListener((MapChangeListener<Language, ObservableSubtitleCollectionImpl>) change ->
|
||||
@@ -275,4 +281,12 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
|
||||
public ObjectProperty<ImportOptions> importOptionsProperty() {
|
||||
return importOptions;
|
||||
}
|
||||
|
||||
public ObservableMap<String, Translator<?>> availableTranslators() {
|
||||
return availableTranslators;
|
||||
}
|
||||
|
||||
public ObjectProperty<Translator<?>> translatorProperty() {
|
||||
return translator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.github.gtache.autosubtitle.gui.work.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.VideoConverter;
|
||||
import com.github.gtache.autosubtitle.VideoLoader;
|
||||
import com.github.gtache.autosubtitle.gui.fx.AbstractFXController;
|
||||
import com.github.gtache.autosubtitle.gui.media.fx.FXMediaController;
|
||||
import com.github.gtache.autosubtitle.gui.work.WorkController;
|
||||
@@ -9,7 +7,6 @@ import com.github.gtache.autosubtitle.gui.work.WorkStatus;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractEvent;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
@@ -52,18 +49,14 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
|
||||
@FXML
|
||||
private TextField fileField;
|
||||
|
||||
@FXML
|
||||
private Button extractButton;
|
||||
|
||||
@FXML
|
||||
private Button exportSoftButton;
|
||||
@FXML
|
||||
private Button exportHardButton;
|
||||
|
||||
@FXML
|
||||
private FXMediaController mediaController;
|
||||
|
||||
@FXML
|
||||
private Label progressLabel;
|
||||
@FXML
|
||||
@@ -74,19 +67,11 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
private ResourceBundle resources;
|
||||
|
||||
private final FXWorkModel model;
|
||||
private final FXWorkBinder binder;
|
||||
private final SubtitleExtractor<?> subtitleExtractor;
|
||||
private final VideoConverter videoConverter;
|
||||
private final VideoLoader videoLoader;
|
||||
|
||||
@Inject
|
||||
FXWorkController(final FXWorkModel model, final FXWorkBinder binder, final SubtitleExtractor subtitleExtractor,
|
||||
final VideoLoader videoLoader, final VideoConverter videoConverter) {
|
||||
FXWorkController(final FXWorkModel model, final FXWorkBinder binder) {
|
||||
this.model = requireNonNull(model);
|
||||
this.binder = requireNonNull(binder);
|
||||
this.subtitleExtractor = requireNonNull(subtitleExtractor);
|
||||
this.videoConverter = requireNonNull(videoConverter);
|
||||
this.videoLoader = requireNonNull(videoLoader);
|
||||
binder.createBindings();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -103,9 +88,11 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
}
|
||||
});
|
||||
|
||||
binder.createBindings();
|
||||
|
||||
subtitleExtractor.addListener(this);
|
||||
model.subtitleExtractorProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
newValue.addListener(FXWorkController.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void bindProgress() {
|
||||
@@ -142,7 +129,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
|
||||
private SubtitleCollection<?> extractAsync() {
|
||||
try {
|
||||
return subtitleExtractor.extract(model.video(), model.extractOptions());
|
||||
return model.subtitleExtractorProperty().get().extract(model.video(), model.extractOptions());
|
||||
} catch (final ExtractException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
@@ -161,7 +148,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
@Override
|
||||
public void loadVideo(final Path file) {
|
||||
try {
|
||||
final var loadedVideo = videoLoader.loadVideo(file);
|
||||
final var loadedVideo = model.videoLoaderProperty().get().loadVideo(file);
|
||||
fileField.setText(file.toAbsolutePath().toString());
|
||||
model.videoProperty().set(loadedVideo);
|
||||
} catch (final IOException e) {
|
||||
@@ -182,7 +169,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
model.setStatus(WorkStatus.EXPORTING);
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
videoConverter.addSoftSubtitles(model.video(), model.collections().values(), model.exportOptions(), file.toPath());
|
||||
model.videoConverterProperty().get().addSoftSubtitles(model.video(), model.collections().values(), model.exportOptions(), file.toPath());
|
||||
} catch (final IOException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
@@ -207,7 +194,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
|
||||
model.setStatus(WorkStatus.EXPORTING);
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
videoConverter.addHardSubtitles(model.video(), model.collections().get(model.extractOptions().language()), model.exportOptions(), file.toPath());
|
||||
model.videoConverterProperty().get().addHardSubtitles(model.video(), model.collections().get(model.extractOptions().language()), model.exportOptions(), file.toPath());
|
||||
} catch (final IOException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package com.github.gtache.autosubtitle.gui.work.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoConverter;
|
||||
import com.github.gtache.autosubtitle.VideoLoader;
|
||||
import com.github.gtache.autosubtitle.gui.work.WorkModel;
|
||||
import com.github.gtache.autosubtitle.gui.work.WorkStatus;
|
||||
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
|
||||
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
@@ -24,6 +27,7 @@ import javafx.collections.ObservableMap;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FX implementation of {@link WorkModel}
|
||||
@@ -31,6 +35,12 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class FXWorkModel implements WorkModel {
|
||||
|
||||
private final ObservableMap<String, SubtitleExtractor<?>> availableSubtitleExtractors;
|
||||
private final ObjectProperty<SubtitleExtractor<?>> subtitleExtractor;
|
||||
private final ObservableMap<String, VideoLoader> availableVideoLoaders;
|
||||
private final ObjectProperty<VideoLoader> videoLoader;
|
||||
private final ObservableMap<String, VideoConverter> availableVideoConverters;
|
||||
private final ObjectProperty<VideoConverter> videoConverter;
|
||||
private final ObjectProperty<Video> video;
|
||||
private final ObjectProperty<WorkStatus> workStatus;
|
||||
private final DoubleProperty progress;
|
||||
@@ -46,7 +56,15 @@ public class FXWorkModel implements WorkModel {
|
||||
private final ObjectProperty<ExtractOptions> extractOptions;
|
||||
|
||||
@Inject
|
||||
FXWorkModel() {
|
||||
FXWorkModel(final Map<String, SubtitleExtractor<?>> subtitleExtractors, final SubtitleExtractor defaultExtractor,
|
||||
final Map<String, VideoLoader> videoLoaders, final VideoLoader defaultVideoLoader,
|
||||
final Map<String, VideoConverter> videoConverters, final VideoConverter defaultVideoConverter) {
|
||||
this.availableSubtitleExtractors = FXCollections.unmodifiableObservableMap(FXCollections.observableMap(subtitleExtractors));
|
||||
this.subtitleExtractor = new SimpleObjectProperty<>(defaultExtractor);
|
||||
this.availableVideoLoaders = FXCollections.unmodifiableObservableMap(FXCollections.observableMap(videoLoaders));
|
||||
this.videoLoader = new SimpleObjectProperty<>(defaultVideoLoader);
|
||||
this.availableVideoConverters = FXCollections.unmodifiableObservableMap(FXCollections.observableMap(videoConverters));
|
||||
this.videoConverter = new SimpleObjectProperty<>(defaultVideoConverter);
|
||||
this.video = new SimpleObjectProperty<>();
|
||||
this.workStatus = new SimpleObjectProperty<>(WorkStatus.IDLE);
|
||||
this.progress = new SimpleDoubleProperty(-1);
|
||||
@@ -175,7 +193,7 @@ public class FXWorkModel implements WorkModel {
|
||||
exportOptions.set(options);
|
||||
}
|
||||
|
||||
public ObjectProperty<ExportOptions> exportOptionsProperty() {
|
||||
ObjectProperty<ExportOptions> exportOptionsProperty() {
|
||||
return exportOptions;
|
||||
}
|
||||
|
||||
@@ -189,7 +207,31 @@ public class FXWorkModel implements WorkModel {
|
||||
extractOptions.set(options);
|
||||
}
|
||||
|
||||
public ObjectProperty<ExtractOptions> extractOptionsProperty() {
|
||||
ObjectProperty<ExtractOptions> extractOptionsProperty() {
|
||||
return extractOptions;
|
||||
}
|
||||
|
||||
ObservableMap<String, SubtitleExtractor<?>> availableSubtitleExtractors() {
|
||||
return availableSubtitleExtractors;
|
||||
}
|
||||
|
||||
ObjectProperty<SubtitleExtractor<?>> subtitleExtractorProperty() {
|
||||
return subtitleExtractor;
|
||||
}
|
||||
|
||||
ObservableMap<String, VideoLoader> availableVideoLoaders() {
|
||||
return availableVideoLoaders;
|
||||
}
|
||||
|
||||
ObjectProperty<VideoLoader> videoLoaderProperty() {
|
||||
return videoLoader;
|
||||
}
|
||||
|
||||
ObservableMap<String, VideoConverter> availableVideoConverters() {
|
||||
return availableVideoConverters;
|
||||
}
|
||||
|
||||
ObjectProperty<VideoConverter> videoConverterProperty() {
|
||||
return videoConverter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.MenuButton?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
|
||||
<GridPane hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
<GridPane fx:id="setupGrid" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/22"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.github.gtache.autosubtitle.gui.setup.fx.FXSetupController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES"/>
|
||||
@@ -18,35 +16,11 @@
|
||||
<ColumnConstraints hgrow="SOMETIMES"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS"/>
|
||||
<RowConstraints vgrow="ALWAYS"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="converterNameLabel" text="Label" GridPane.rowIndex="1"/>
|
||||
<Label fx:id="converterStatusLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||
<Label fx:id="extractorNameLabel" text="Label" GridPane.rowIndex="2"/>
|
||||
<Label fx:id="extractorStatusLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
|
||||
<Label fx:id="translatorNameLabel" text="Label" GridPane.rowIndex="3"/>
|
||||
<Label fx:id="translatorStatusLabel" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
|
||||
<MenuButton fx:id="converterButton" mnemonicParsing="false" text="%setup.menu.label" GridPane.columnIndex="2"
|
||||
GridPane.rowIndex="1"/>
|
||||
<MenuButton fx:id="extractorButton" mnemonicParsing="false" text="%setup.menu.label" GridPane.columnIndex="2"
|
||||
GridPane.rowIndex="2"/>
|
||||
<MenuButton fx:id="translatorButton" mnemonicParsing="false" text="%setup.menu.label" GridPane.columnIndex="2"
|
||||
GridPane.rowIndex="3"/>
|
||||
<Label text="%setup.description.label" GridPane.columnSpan="2147483647"/>
|
||||
<ProgressBar fx:id="converterProgress" prefWidth="200.0" progress="0.0" GridPane.columnIndex="3"
|
||||
GridPane.rowIndex="1"/>
|
||||
<ProgressBar fx:id="extractorProgress" prefWidth="200.0" progress="0.0" GridPane.columnIndex="3"
|
||||
GridPane.rowIndex="2"/>
|
||||
<ProgressBar fx:id="translatorProgress" prefWidth="200.0" progress="0.0" GridPane.columnIndex="3"
|
||||
GridPane.rowIndex="3"/>
|
||||
<Label fx:id="converterProgressLabel" text="Label" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
|
||||
<Label fx:id="extractorProgressLabel" text="Label" GridPane.columnIndex="4" GridPane.rowIndex="2"/>
|
||||
<Label fx:id="translatorProgressLabel" text="Label" GridPane.columnIndex="4" GridPane.rowIndex="3"/>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestFXParametersController extends FxRobot {
|
||||
this.videoConverter = requireNonNull(videoConverter);
|
||||
this.translator = requireNonNull(translator);
|
||||
this.timeFormatter = requireNonNull(timeFormatter);
|
||||
this.model = spy(new FXParametersModel(mock(ExtractionModelProvider.class), "Arial", 12, 40, 1));
|
||||
this.model = spy(new FXParametersModel(Map.of(), mock(ExtractionModelProvider.class), "Arial", 12, 40, 1));
|
||||
this.binder = requireNonNull(binder);
|
||||
this.window = FxToolkit.registerPrimaryStage();
|
||||
this.controller = spy(FXParametersController.class);
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -42,7 +43,7 @@ class TestFXParametersModel {
|
||||
void beforeEach() {
|
||||
when(provider.getDefaultExtractionModel()).thenReturn(defaultExtractionModel);
|
||||
when(provider.getAvailableExtractionModels()).thenReturn(availableExtractionModels);
|
||||
this.model = new FXParametersModel(provider, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_MAX_LINE_LENGTH, DEFAULT_MAX_LINES);
|
||||
this.model = new FXParametersModel(Map.of(), provider, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_MAX_LINE_LENGTH, DEFAULT_MAX_LINES); //TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -33,16 +33,16 @@ class TestFXSetupController extends FxRobot {
|
||||
private final FXSetupModel model;
|
||||
private final FXSetupController controller;
|
||||
private final FXWorkBinder binder;
|
||||
private final SubtitleExtractor extractor;
|
||||
private final SubtitleExtractor<?> extractor;
|
||||
private final Map<String, SubtitleConverter> subtitleConverters;
|
||||
private final VideoLoader videoLoader;
|
||||
private final VideoConverter videoConverter;
|
||||
private final Translator translator;
|
||||
private final Translator<?> translator;
|
||||
private final TimeFormatter timeFormatter;
|
||||
private final Stage window;
|
||||
|
||||
TestFXSetupController(@Mock final SubtitleExtractor extractor, @Mock final SubtitleConverter subtitleConverter, @Mock final VideoLoader videoLoader,
|
||||
@Mock final VideoConverter videoConverter, @Mock final Translator translator, @Mock final TimeFormatter timeFormatter,
|
||||
TestFXSetupController(@Mock final SubtitleExtractor<?> extractor, @Mock final SubtitleConverter<?> subtitleConverter, @Mock final VideoLoader videoLoader,
|
||||
@Mock final VideoConverter videoConverter, @Mock final Translator<?> translator, @Mock final TimeFormatter timeFormatter,
|
||||
@Mock final FXWorkBinder binder) throws TimeoutException {
|
||||
this.extractor = requireNonNull(extractor);
|
||||
this.subtitleConverters = Map.of("srt", requireNonNull(subtitleConverter));
|
||||
@@ -50,7 +50,7 @@ class TestFXSetupController extends FxRobot {
|
||||
this.videoConverter = requireNonNull(videoConverter);
|
||||
this.translator = requireNonNull(translator);
|
||||
this.timeFormatter = requireNonNull(timeFormatter);
|
||||
this.model = spy(new FXSetupModel());
|
||||
this.model = spy(new FXSetupModel(Map.of(), Map.of())); //TODO
|
||||
this.binder = requireNonNull(binder);
|
||||
this.window = FxToolkit.registerPrimaryStage();
|
||||
this.controller = spy(FXSetupController.class);
|
||||
|
||||
@@ -1,97 +1,12 @@
|
||||
package com.github.gtache.autosubtitle.gui.setup.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.github.gtache.autosubtitle.setup.SetupStatus.ERRORED;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.util.Map;
|
||||
|
||||
class TestFXSetupModel {
|
||||
|
||||
private final FXSetupModel model;
|
||||
|
||||
TestFXSetupModel() {
|
||||
this.model = new FXSetupModel();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSubtitleExtractorStatus() {
|
||||
assertEquals(ERRORED, model.subtitleExtractorStatus());
|
||||
assertEquals(ERRORED, model.subtitleExtractorStatusProperty().get());
|
||||
model.setSubtitleExtractorStatus(SetupStatus.SYSTEM_INSTALLED);
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, model.subtitleExtractorStatus());
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, model.subtitleExtractorStatusProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSubtitleExtractorSetupProgress() {
|
||||
assertEquals(-2, model.subtitleExtractorSetupProgress());
|
||||
assertEquals(-2, model.subtitleExtractorSetupProgressProperty().get());
|
||||
model.setSubtitleExtractorSetupProgress(0.5);
|
||||
assertEquals(0.5, model.subtitleExtractorSetupProgress());
|
||||
assertEquals(0.5, model.subtitleExtractorSetupProgressProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSubtitleExtractorSetupProgressLabel() {
|
||||
assertEquals("", model.subtitleExtractorSetupProgressLabel());
|
||||
assertEquals("", model.subtitleExtractorSetupProgressLabelProperty().get());
|
||||
model.setSubtitleExtractorSetupProgressLabel("test");
|
||||
assertEquals("test", model.subtitleExtractorSetupProgressLabel());
|
||||
assertEquals("test", model.subtitleExtractorSetupProgressLabelProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVideoConverterStatus() {
|
||||
assertEquals(ERRORED, model.videoConverterStatus());
|
||||
assertEquals(ERRORED, model.videoConverterStatusProperty().get());
|
||||
model.setVideoConverterStatus(SetupStatus.SYSTEM_INSTALLED);
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, model.videoConverterStatus());
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, model.videoConverterStatusProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVideoConverterSetupProgress() {
|
||||
assertEquals(-2, model.videoConverterSetupProgress());
|
||||
assertEquals(-2, model.videoConverterSetupProgressProperty().get());
|
||||
model.setVideoConverterSetupProgress(0.5);
|
||||
assertEquals(0.5, model.videoConverterSetupProgress());
|
||||
assertEquals(0.5, model.videoConverterSetupProgressProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVideoConverterSetupProgressLabel() {
|
||||
assertEquals("", model.videoConverterSetupProgressLabel());
|
||||
assertEquals("", model.videoConverterSetupProgressLabelProperty().get());
|
||||
model.setVideoConverterSetupProgressLabel("test");
|
||||
assertEquals("test", model.videoConverterSetupProgressLabel());
|
||||
assertEquals("test", model.videoConverterSetupProgressLabelProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTranslatorStatus() {
|
||||
assertEquals(ERRORED, model.translatorStatus());
|
||||
assertEquals(ERRORED, model.translatorStatusProperty().get());
|
||||
model.setTranslatorStatus(SetupStatus.SYSTEM_INSTALLED);
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, model.translatorStatus());
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, model.translatorStatusProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTranslatorSetupProgress() {
|
||||
assertEquals(-2, model.translatorSetupProgress());
|
||||
assertEquals(-2, model.translatorSetupProgressProperty().get());
|
||||
model.setTranslatorSetupProgress(0.5);
|
||||
assertEquals(0.5, model.translatorSetupProgress());
|
||||
assertEquals(0.5, model.translatorSetupProgressProperty().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTranslatorSetupProgressLabel() {
|
||||
assertEquals("", model.translatorSetupProgressLabel());
|
||||
assertEquals("", model.translatorSetupProgressLabelProperty().get());
|
||||
model.setTranslatorSetupProgressLabel("test");
|
||||
assertEquals("test", model.translatorSetupProgressLabel());
|
||||
assertEquals("test", model.translatorSetupProgressLabelProperty().get());
|
||||
this.model = new FXSetupModel(Map.of(), Map.of()); //TODO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.github.gtache.autosubtitle.gui.subtitles.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoInfo;
|
||||
import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
|
||||
import com.github.gtache.autosubtitle.gui.setup.fx.FXSetupModel;
|
||||
import com.github.gtache.autosubtitle.gui.work.WorkStatus;
|
||||
import com.github.gtache.autosubtitle.gui.work.fx.FXWorkModel;
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.impl.ParseOptionsImpl;
|
||||
@@ -15,6 +18,7 @@ import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.ExportOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.ImportOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.translation.Translator;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
@@ -26,6 +30,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
@@ -35,6 +40,14 @@ class TestFXSubtitlesBinder {
|
||||
|
||||
private final FXWorkModel workModel;
|
||||
private final FXSubtitlesModel subtitlesModel;
|
||||
private final Map<ToolType, Map<String, SetupManager>> setupManagers;
|
||||
private final Map<ToolType, SetupManager> defaultManagers;
|
||||
private final Map<String, Translator<?>> translators;
|
||||
private final SetupManager firstManager;
|
||||
private final SetupManager secondManager;
|
||||
private final Translator<?> firstTranslator;
|
||||
private final Translator<?> secondTranslator;
|
||||
private final FXSetupModel setupModel;
|
||||
private final FXParametersModel parametersModel;
|
||||
private final FXSubtitlesBinder binder;
|
||||
private final String defaultFontFamily;
|
||||
@@ -42,7 +55,9 @@ class TestFXSubtitlesBinder {
|
||||
private final int defaultMaxLineLength;
|
||||
private final int defaultMaxLines;
|
||||
|
||||
TestFXSubtitlesBinder(@Mock final ExtractionModelProvider extractionModelProvider) {
|
||||
TestFXSubtitlesBinder(@Mock final ExtractionModelProvider extractionModelProvider, @Mock final SetupManager firstManager,
|
||||
@Mock final SetupManager secondManager, @Mock final Translator<?> firstTranslator,
|
||||
@Mock final Translator<?> secondTranslator) {
|
||||
this.workModel = spy(FXWorkModel.class);
|
||||
this.defaultFontFamily = "Arial";
|
||||
this.defaultFontSize = 12;
|
||||
@@ -50,8 +65,16 @@ class TestFXSubtitlesBinder {
|
||||
this.defaultMaxLines = 2;
|
||||
this.parametersModel = mock(FXParametersModel.class, withSettings().defaultAnswer(CALLS_REAL_METHODS)
|
||||
.useConstructor(extractionModelProvider, defaultFontFamily, defaultFontSize, defaultMaxLineLength, defaultMaxLines));
|
||||
this.subtitlesModel = new FXSubtitlesModel();
|
||||
this.binder = new FXSubtitlesBinder(workModel, parametersModel, subtitlesModel);
|
||||
this.firstManager = Objects.requireNonNull(firstManager);
|
||||
this.secondManager = Objects.requireNonNull(secondManager);
|
||||
this.firstTranslator = Objects.requireNonNull(firstTranslator);
|
||||
this.secondTranslator = Objects.requireNonNull(secondTranslator);
|
||||
this.translators = Map.of("first", firstTranslator, "second", secondTranslator);
|
||||
this.defaultManagers = Map.of(ToolType.TRANSLATOR, firstManager);
|
||||
this.setupManagers = Map.of(ToolType.TRANSLATOR, Map.of("first", firstManager, "second", secondManager));
|
||||
this.setupModel = mock(FXSetupModel.class, withSettings().defaultAnswer(CALLS_REAL_METHODS).useConstructor(setupManagers, defaultManagers));
|
||||
this.subtitlesModel = new FXSubtitlesModel(translators, firstTranslator);
|
||||
this.binder = new FXSubtitlesBinder(workModel, parametersModel, setupModel, subtitlesModel);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
@@ -180,4 +203,13 @@ class TestFXSubtitlesBinder {
|
||||
parametersModel.setMaxLines(4);
|
||||
assertEquals(new ImportOptionsImpl(new ParseOptionsImpl(1, 4, new FontImpl("TT", 14))), subtitlesModel.importOptions());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTranslatorsBinding() {
|
||||
assertEquals(firstTranslator, subtitlesModel.translatorProperty().get());
|
||||
setupModel.setSelectedSetupManager(ToolType.TRANSLATOR, secondManager);
|
||||
assertEquals(secondTranslator, subtitlesModel.translatorProperty().get());
|
||||
setupModel.setSelectedSetupManager(ToolType.TRANSLATOR, null);
|
||||
assertEquals(secondTranslator, subtitlesModel.translatorProperty().get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestFXSubtitlesController extends FxRobot {
|
||||
this.videoConverter = requireNonNull(videoConverter);
|
||||
this.translator = requireNonNull(translator);
|
||||
this.timeFormatter = requireNonNull(timeFormatter);
|
||||
this.model = spy(new FXSubtitlesModel());
|
||||
this.model = spy(new FXSubtitlesModel(Map.of(), translator));
|
||||
this.binder = requireNonNull(binder);
|
||||
this.window = FxToolkit.registerPrimaryStage();
|
||||
this.controller = spy(FXSubtitlesController.class);
|
||||
|
||||
@@ -5,24 +5,36 @@ import com.github.gtache.autosubtitle.subtitle.ExportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
|
||||
import com.github.gtache.autosubtitle.translation.Translator;
|
||||
import javafx.collections.FXCollections;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestFXSubtitlesModel {
|
||||
|
||||
private final FXSubtitlesModel model;
|
||||
private final Map<String, Translator<?>> translators;
|
||||
private final Translator<?> translator1;
|
||||
private final Translator<?> translator2;
|
||||
|
||||
TestFXSubtitlesModel() {
|
||||
this.model = new FXSubtitlesModel();
|
||||
TestFXSubtitlesModel(@Mock final Translator<?> translator1, @Mock final Translator<?> translator2) {
|
||||
this.translator1 = requireNonNull(translator1);
|
||||
this.translator2 = requireNonNull(translator2);
|
||||
this.translators = Map.of("1", translator1, "2", translator2);
|
||||
this.model = new FXSubtitlesModel(translators, translator1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -202,4 +214,16 @@ class TestFXSubtitlesModel {
|
||||
final var options = mock(ImportOptions.class);
|
||||
assertDoesNotThrow(() -> model.importOptionsProperty().set(options));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAvailableTranslators() {
|
||||
assertEquals(translators, model.availableTranslators());
|
||||
assertThrows(UnsupportedOperationException.class, () -> model.availableTranslators().clear());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSelectedTranslator() {
|
||||
assertEquals(translator1, model.translatorProperty().get());
|
||||
assertDoesNotThrow(() -> model.translatorProperty().set(translator2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ package com.github.gtache.autosubtitle.gui.work.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoConverter;
|
||||
import com.github.gtache.autosubtitle.VideoInfo;
|
||||
import com.github.gtache.autosubtitle.VideoLoader;
|
||||
import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
|
||||
import com.github.gtache.autosubtitle.gui.subtitles.fx.FXSubtitlesModel;
|
||||
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
|
||||
@@ -10,6 +12,7 @@ import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.impl.ParseOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.impl.ExtractOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.ExportOptionsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
|
||||
@@ -19,6 +22,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -49,7 +53,7 @@ class TestFXWorkBinder {
|
||||
this.defaultMaxLines = 1;
|
||||
this.parametersModel = mock(FXParametersModel.class, withSettings().defaultAnswer(CALLS_REAL_METHODS).useConstructor(extractionModelProvider, defaultFontFamily, defaultFontSize, defaultMaxLineLength, defaultMaxLines));
|
||||
this.subtitlesModel = spy(FXSubtitlesModel.class);
|
||||
this.workModel = new FXWorkModel();
|
||||
this.workModel = new FXWorkModel(Map.of(), mock(SubtitleExtractor.class), Map.of(), mock(VideoLoader.class), Map.of(), mock(VideoConverter.class)); //TODO
|
||||
this.binder = new FXWorkBinder(workModel, parametersModel, subtitlesModel);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.testfx.util.WaitForAsyncUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@@ -41,10 +42,10 @@ class TestFXWorkController extends FxRobot {
|
||||
this.extractor = requireNonNull(extractor);
|
||||
this.videoLoader = requireNonNull(videoLoader);
|
||||
this.videoConverter = requireNonNull(videoConverter);
|
||||
this.model = spy(new FXWorkModel());
|
||||
this.model = spy(new FXWorkModel(Map.of(), extractor, Map.of(), videoLoader, Map.of(), videoConverter));
|
||||
this.binder = requireNonNull(binder);
|
||||
this.window = FxToolkit.registerPrimaryStage();
|
||||
this.controller = spy(new FXWorkController(model, binder, extractor, videoLoader, videoConverter));
|
||||
this.controller = spy(new FXWorkController(model, binder));
|
||||
|
||||
FxToolkit.setupStage(w -> {
|
||||
final var loader = new FXMLLoader(getClass().getResource("/com/github/gtache/autosubtitle/gui/fx/workView.fxml"));
|
||||
|
||||
@@ -2,11 +2,14 @@ package com.github.gtache.autosubtitle.gui.work.fx;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoConverter;
|
||||
import com.github.gtache.autosubtitle.VideoLoader;
|
||||
import com.github.gtache.autosubtitle.gui.work.WorkStatus;
|
||||
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
|
||||
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -22,7 +25,7 @@ class TestFXWorkModel {
|
||||
private final FXWorkModel model;
|
||||
|
||||
TestFXWorkModel() {
|
||||
this.model = new FXWorkModel();
|
||||
this.model = new FXWorkModel(Map.of(), mock(SubtitleExtractor.class), Map.of(), mock(VideoLoader.class), Map.of(), mock(VideoConverter.class)); //TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
<groupId>com.github.gtache.autosubtitle</groupId>
|
||||
<artifactId>autosubtitle-gui-fx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.gtache.autosubtitle</groupId>
|
||||
<artifactId>autosubtitle-whisper-base</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.gtache.autosubtitle</groupId>
|
||||
<artifactId>autosubtitle-whisperx</artifactId>
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.github.gtache.autosubtitle.modules.ffmpeg.FFmpegModule;
|
||||
import com.github.gtache.autosubtitle.modules.gui.fx.FXModule;
|
||||
import com.github.gtache.autosubtitle.modules.gui.impl.GuiCoreModule;
|
||||
import com.github.gtache.autosubtitle.modules.impl.CoreModule;
|
||||
import com.github.gtache.autosubtitle.modules.whisper.base.WhisperModule;
|
||||
import com.github.gtache.autosubtitle.modules.whisperx.WhisperXModule;
|
||||
import dagger.Component;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
@@ -17,7 +18,7 @@ import javax.inject.Singleton;
|
||||
@FunctionalInterface
|
||||
@Singleton
|
||||
@Component(modules = {CoreModule.class, GuiCoreModule.class, FXModule.class, FFmpegModule.class,
|
||||
WhisperXModule.class, DeepLModule.class})
|
||||
WhisperModule.class, WhisperXModule.class, DeepLModule.class})
|
||||
public interface RunComponent {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ module com.github.gtache.autosubtitle.gui.run {
|
||||
requires com.github.gtache.autosubtitle.deepl;
|
||||
requires com.github.gtache.autosubtitle.ffmpeg;
|
||||
requires com.github.gtache.autosubtitle.gui.fx;
|
||||
requires com.github.gtache.autosubtitle.whisper.base;
|
||||
requires com.github.gtache.autosubtitle.whisperx;
|
||||
requires javafx.fxml;
|
||||
requires javafx.graphics;
|
||||
|
||||
Reference in New Issue
Block a user