fb51e2c469
Bug fixes. A lot of things added <3
336 lines
14 KiB
Java
336 lines
14 KiB
Java
package mplayer4anime;
|
|
|
|
import javafx.application.HostServices;
|
|
import javafx.application.Platform;
|
|
import javafx.event.ActionEvent;
|
|
import javafx.event.EventHandler;
|
|
import javafx.fxml.FXML;
|
|
import javafx.fxml.Initializable;
|
|
import javafx.scene.control.*;
|
|
|
|
import javafx.stage.Stage;
|
|
import mplayer4anime.About.AboutWindow;
|
|
import mplayer4anime.Playlists.JsonStorage;
|
|
import mplayer4anime.Playlists.Playlists;
|
|
import mplayer4anime.Settings.SettingsWindow;
|
|
import mplayer4anime.appPanes.ControllerPane;
|
|
import mplayer4anime.appPanes.ControllerSUB;
|
|
|
|
import java.io.*;
|
|
import java.net.URL;
|
|
import java.util.ListIterator;
|
|
import java.util.ResourceBundle;
|
|
|
|
public class Controller implements Initializable {
|
|
@FXML
|
|
private ControllerPane mkvPaneController;
|
|
@FXML
|
|
private ControllerPane mkaPaneController;
|
|
@FXML
|
|
private ControllerSUB subPaneController;
|
|
@FXML
|
|
private Label statusLbl;
|
|
@FXML
|
|
private Menu recentlyOpenedMenu;
|
|
// Get preferences
|
|
private AppPreferences appPreferences = new AppPreferences();
|
|
|
|
private ResourceBundle resourceBundle;
|
|
|
|
@FXML
|
|
private CheckMenuItem fullScreen;
|
|
|
|
// Get host services for opening URLs etc.
|
|
private HostServices hostServices;
|
|
|
|
@FXML
|
|
private TabPane tabPane;
|
|
|
|
@FXML
|
|
private CheckMenuItem subsHide;
|
|
|
|
private String currentPlaylistLocation = null; //TODO: move to the constructor?
|
|
@Override
|
|
public void initialize(URL url, ResourceBundle rb) {
|
|
mkvPaneController.setPaneType("Video");
|
|
mkaPaneController.setPaneType("Audio");
|
|
subPaneController.setPaneType("Subtitles");
|
|
// Register this controller in mediator
|
|
MediatorControl.getInstance().registerMainController(this);
|
|
|
|
resourceBundle = rb;
|
|
|
|
// Set default list of encodings of the subtitles files:
|
|
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), appPreferences.getLastTimeUsedSubsEncoding());
|
|
|
|
// If subtitles should be opened first, per user's settings let's show it first
|
|
if (appPreferences.getSubtilesFirst()){
|
|
tabPane.getSelectionModel().select(1); // 0 is mka 1 is subs
|
|
}
|
|
|
|
fullScreen.setSelected(appPreferences.getFullScreenSelected());
|
|
subsHide.setSelected(appPreferences.getSubtitlesHideSelected());
|
|
|
|
String[] recentPlaylists = appPreferences.getRecentPlaylists();
|
|
for (int i = recentPlaylists.length-1; i >= 0; i--)
|
|
if (!recentPlaylists[i].isEmpty())
|
|
addRecentlyOpened(recentPlaylists[i]);
|
|
}
|
|
|
|
public void setHostServices(HostServices hostServices) {
|
|
this.hostServices = hostServices;
|
|
}
|
|
|
|
/* PLAYER COMMANDS */
|
|
private boolean playerSingleCommand(String command){
|
|
if (player != null && player.isAlive()) {
|
|
playerIn.print(command);
|
|
playerIn.print("\n");
|
|
playerIn.flush();
|
|
return true;
|
|
} else { return false; }
|
|
}
|
|
|
|
@FXML
|
|
private void subsTriggerBtn(){
|
|
if (playerSingleCommand("get_sub_visibility")) {
|
|
String returnedStr;
|
|
int returnedInt = 1;
|
|
try {
|
|
while ((returnedStr = playerOutErr.readLine()) != null) {
|
|
//System.out.println(returnedStr);
|
|
if (returnedStr.startsWith("ANS_SUB_VISIBILITY=")) {
|
|
returnedInt = Integer.parseInt(returnedStr.substring("ANS_SUB_VISIBILITY=".length()));
|
|
break;
|
|
}
|
|
}
|
|
} catch (IOException e) {
|
|
System.out.println("Can't determine whether subtitles enabled or disabled");
|
|
}
|
|
|
|
if (returnedInt == 1)
|
|
playerSingleCommand("sub_visibility 0");
|
|
else
|
|
playerSingleCommand("sub_visibility 1");
|
|
}
|
|
}
|
|
@FXML
|
|
private void fullscreenBtn(){ playerSingleCommand("vo_fullscreen"); }
|
|
@FXML
|
|
private void muteBtn(){ playerSingleCommand("mute"); }
|
|
@FXML
|
|
private void playPrevTrackBtn(){
|
|
if (player != null && player.isAlive()) {
|
|
playerSingleCommand("quit");
|
|
while (player.isAlive()); // TODO: remove crutch, implement bike
|
|
}
|
|
int index;
|
|
index = mkvPaneController.getElementSelectedIndex();
|
|
if (index > 0) {
|
|
mkvPaneController.setElementSelectedByIndex(index-1); // .selectNext / .selectPrevious
|
|
playBtn();
|
|
}
|
|
}
|
|
@FXML
|
|
private void playNextTrackBtn(){
|
|
if (player != null && player.isAlive()) {
|
|
playerSingleCommand("quit");
|
|
while (player.isAlive()); // TODO: remove crutch, implement bike
|
|
}
|
|
int index;
|
|
index = mkvPaneController.getElementSelectedIndex();
|
|
if (index+1 < mkvPaneController.getElementsCount() ) {
|
|
mkvPaneController.setElementSelectedByIndex(index+1);
|
|
playBtn();
|
|
}
|
|
}
|
|
|
|
private Process player;
|
|
private PrintStream playerIn;
|
|
private BufferedReader playerOutErr;
|
|
|
|
@FXML
|
|
private void playBtn(){
|
|
if (mkvPaneController.getElementSelected() != null) {
|
|
boolean Audio = !mkaPaneController.isElementsListEmpty() && mkvPaneController.getElementSelectedIndex() < mkaPaneController.getElementsCount();
|
|
boolean Subtitles = !subPaneController.isElementsListEmpty() && mkvPaneController.getElementSelectedIndex() < subPaneController.getElementsCount();
|
|
boolean SubEncodingDefault = subPaneController.getSelectedEncoding().equals("default");
|
|
|
|
try {
|
|
if (player == null || !player.isAlive()) {
|
|
player = new ProcessBuilder( // FUCKING MAGIC! DON'T CHANGE SEQUENCE
|
|
appPreferences.getPath(), // It's a chance for Windows ;)
|
|
"-slave",
|
|
Audio?"-audiofile":"",
|
|
Audio? mkaPaneController.getElementSelected():"",
|
|
"-quiet",
|
|
fullScreen.isSelected() ? "-fs" : "",
|
|
mkvPaneController.getElementSelected(),
|
|
subsHide.isSelected()||Subtitles?"-nosub":"", // Turn off subtitles embedded into MKV file (and replace by localy-stored subs file if needed)
|
|
Subtitles?"-sub":"",
|
|
Subtitles? subPaneController.getElementSelected():"",
|
|
Subtitles?SubEncodingDefault?"":"-subcp":"", // Use subtitles -> YES -> Check if we need encoding
|
|
Subtitles?SubEncodingDefault?"": subPaneController.getSelectedEncoding():""
|
|
).start();
|
|
|
|
PipedInputStream readFrom = new PipedInputStream(256 * 1024);
|
|
PipedOutputStream writeTo = new PipedOutputStream(readFrom);
|
|
|
|
playerOutErr = new BufferedReader(new InputStreamReader(readFrom));
|
|
|
|
new LineRedirecter(player.getInputStream(), writeTo).start();
|
|
new LineRedirecter(player.getErrorStream(), writeTo).start();
|
|
|
|
playerIn = new PrintStream(player.getOutputStream());
|
|
|
|
/* If user desired to disable subtitles but populated the list in the SUB pane, then load them and disable visibility.
|
|
* It's should be done this way because if we won't pass them to mplayer during start them user won't be able to enable them later on.
|
|
* There is another bike could be implemented such as passing input file during load but it's far more dumb idea then current implementation.
|
|
*/
|
|
if (subsHide.isSelected())
|
|
playerSingleCommand("sub_visibility 0");
|
|
} else {
|
|
playerIn.print("pause");
|
|
playerIn.print("\n");
|
|
playerIn.flush();
|
|
}
|
|
} catch (IOException e) {
|
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToStartMplayer"));
|
|
}
|
|
} else { System.out.println("File not selected"); }
|
|
}
|
|
|
|
@FXML
|
|
private void stopBtn(){playerSingleCommand("stop"); }
|
|
@FXML
|
|
private void volumeUpBtn(){ playerSingleCommand("volume +1 0"); }
|
|
@FXML
|
|
private void volumeDownBtn(){ playerSingleCommand("volume -1 0"); }
|
|
|
|
@FXML
|
|
private void closeBtn() {
|
|
Stage currentStage = (Stage) tabPane.getScene().getWindow();
|
|
currentStage.close();
|
|
}
|
|
|
|
// Will be used to store lists previously opened.
|
|
// Linkage established by ohHidden in Main.java class
|
|
void shutdown(){
|
|
appPreferences.setLastTimeUsedSubsEncoding(subPaneController.getSelectedEncoding());
|
|
appPreferences.setFullScreenSelected(fullScreen.isSelected());
|
|
appPreferences.setSubtitlesHideSelected(subsHide.isSelected());
|
|
|
|
String[] storeRecentArr = new String[10];
|
|
for (int i =0; i < recentlyOpenedMenu.getItems().size() - 2 && !(i > 9); i++) { // Don't take separator and Clean button
|
|
storeRecentArr[i] = (String) recentlyOpenedMenu.getItems().get(i).getUserData();
|
|
}
|
|
appPreferences.setRecentPlaylists(storeRecentArr);
|
|
|
|
Platform.exit();
|
|
}
|
|
|
|
@FXML
|
|
private void infoBtn(){ new AboutWindow(this.hostServices); } // TODO: fix this shit with hostSerivces that doesn't work @ linux
|
|
|
|
/** SETTINGS HANDLE */
|
|
@FXML
|
|
private void settingsBtn(){ new SettingsWindow(); }
|
|
// Get event that notify application in case some settings has been changed
|
|
// This function called from MediatorControl after mediator receives request form SettingsController indicating that user updated some required fields.
|
|
void updateAfterSettingsChanged(){
|
|
/* update list of encoding */
|
|
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), null);
|
|
// In case of application failure should be better to save this immediately
|
|
appPreferences.setLastTimeUsedSubsEncoding(subPaneController.getSelectedEncoding());
|
|
}
|
|
|
|
@FXML
|
|
private void openBtn() {
|
|
JsonStorage jsonStorage = Playlists.Read(resourceBundle);
|
|
setAllLists(jsonStorage);
|
|
}
|
|
private void setAllLists(JsonStorage jsonStorage){
|
|
if (jsonStorage != null) {
|
|
mkvPaneController.cleanList();
|
|
mkaPaneController.cleanList();
|
|
subPaneController.cleanList();
|
|
mkvPaneController.setFilesFromList(jsonStorage.getVideo());
|
|
mkaPaneController.setFilesFromList(jsonStorage.getAudio());
|
|
subPaneController.setFilesFromList(jsonStorage.getSubs());
|
|
subPaneController.selectEncodingValue(jsonStorage.getSubEncoding(), appPreferences);
|
|
|
|
currentPlaylistLocation = Playlists.getPlaylistLocation(); // TODO: Implement listener? mmm...
|
|
statusLbl.setText(currentPlaylistLocation);
|
|
addRecentlyOpened(currentPlaylistLocation);
|
|
}
|
|
}
|
|
@FXML
|
|
private void saveBtn() {
|
|
if (mkvPaneController.getElementsCount() == 0)
|
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToSaveEmptyPlaylist"));
|
|
else {
|
|
JsonStorage jsonStorage = new JsonStorage(mkvPaneController.getElementsAll(), mkaPaneController.getElementsAll(), subPaneController.getElementsAll(), subPaneController.getSelectedEncoding());
|
|
if (Playlists.SaveCurrent(resourceBundle, jsonStorage)) {
|
|
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
|
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
|
addRecentlyOpened(currentPlaylistLocation);
|
|
}
|
|
}
|
|
}
|
|
@FXML
|
|
private void saveAsBtn() {
|
|
if (mkvPaneController.getElementsCount() == 0)
|
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToSaveEmptyPlaylist"));
|
|
else {
|
|
JsonStorage jsonStorage = new JsonStorage(mkvPaneController.getElementsAll(), mkaPaneController.getElementsAll(), subPaneController.getElementsAll(), subPaneController.getSelectedEncoding());
|
|
if (Playlists.SaveAs(resourceBundle, jsonStorage)) {
|
|
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
|
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
|
addRecentlyOpened(currentPlaylistLocation);
|
|
}
|
|
}
|
|
}
|
|
@FXML
|
|
private void cleanAllRecentlyOpened(){
|
|
recentlyOpenedMenu.getItems().remove(0,recentlyOpenedMenu.getItems().size() - 2);
|
|
}
|
|
|
|
private void addRecentlyOpened(String playlistPath){
|
|
ListIterator<MenuItem> iteratorItem = recentlyOpenedMenu.getItems().listIterator();
|
|
while (iteratorItem.hasNext()) {
|
|
MenuItem mi = iteratorItem.next();
|
|
if (mi.getUserData() != null && mi.getUserData().equals(playlistPath)) {
|
|
recentlyOpenedMenu.getItems().remove(mi);
|
|
recentlyOpenedMenu.getItems().add(0, mi);
|
|
return;
|
|
}
|
|
}
|
|
|
|
MenuItem menuItem = new MenuItem();
|
|
String fileNameOnly;
|
|
if (playlistPath.contains("/")) { // Unix
|
|
fileNameOnly = playlistPath.substring(playlistPath.lastIndexOf("/") + 1, playlistPath.length());
|
|
menuItem.setText(fileNameOnly);
|
|
}
|
|
else if (playlistPath.contains("\\")) { // Windows
|
|
fileNameOnly = playlistPath.substring(playlistPath.lastIndexOf("\\") + 1, playlistPath.length());
|
|
menuItem.setText(fileNameOnly);
|
|
}
|
|
else { // Other o_0
|
|
menuItem.setText(playlistPath);
|
|
}
|
|
menuItem.setUserData(playlistPath);
|
|
menuItem.setOnAction(new EventHandler<ActionEvent>() {
|
|
@Override
|
|
public void handle(ActionEvent actionEvent) {
|
|
JsonStorage jsonStorage = Playlists.ReadByPath(resourceBundle, new File(playlistPath));
|
|
setAllLists(jsonStorage);
|
|
}
|
|
});
|
|
// Limit list to 13 elements (2 in the end are separator and clear button)
|
|
if (recentlyOpenedMenu.getItems().size() >= 11)
|
|
recentlyOpenedMenu.getItems().remove(9, recentlyOpenedMenu.getItems().size() - 2);
|
|
recentlyOpenedMenu.getItems().add(0, menuItem);
|
|
}
|
|
}
|
|
|