Update image, add save-window-size-on-close feature, start separating mplayer controls out of the in-app controller-class that should make application architecture more solid in future and give a chance to add other back ends support. Start code refactoring, adding copyleft banners.
This commit is contained in:
parent
2fbdbc805f
commit
08aef521fe
16 changed files with 563 additions and 291 deletions
4
pom.xml
4
pom.xml
|
@ -8,7 +8,7 @@
|
|||
<name>mplayer4anime</name>
|
||||
|
||||
<artifactId>mplayer4anime</artifactId>
|
||||
<version>0.14.1-SNAPSHOT</version>
|
||||
<version>0.15-SNAPSHOT</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
<description>
|
||||
mplayer front end to play content pairs that are mostly used for anime (mka+mkv, mp4+ac3, mkv+srt)
|
||||
</description>
|
||||
<inceptionYear>2018-2019</inceptionYear>
|
||||
<inceptionYear>2018</inceptionYear>
|
||||
<organization>
|
||||
<name>Dmitry Isaenko</name>
|
||||
<url>https://developersu.blogspot.com/search/label/mplayer4anime</url>
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
// Rule application settings
|
||||
public class AppPreferences {
|
||||
private static AppPreferences INSTANCE = new AppPreferences();
|
||||
private Preferences preferences = Preferences.userRoot().node("mplayer4anime");
|
||||
|
||||
private Preferences preferences;
|
||||
private AppPreferences(){}
|
||||
|
||||
public AppPreferences(){
|
||||
preferences = Preferences.userRoot().node("mplayer4anime");
|
||||
public static AppPreferences getINSTANCE() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void setPath(String path){
|
||||
|
@ -96,5 +116,10 @@ public class AppPreferences {
|
|||
preferences.put("RECENT_PLS_" + i, "");
|
||||
}
|
||||
}
|
||||
// Window size
|
||||
public double getSceneWidth(){ return preferences.getDouble("window_width", 1200.0); }
|
||||
public void setSceneWidth(double value){ preferences.putDouble("window_width", value); }
|
||||
|
||||
public double getSceneHeight(){ return preferences.getDouble("window_height", 800.0); }
|
||||
public void setSceneHeight(double value){ preferences.putDouble("window_height", value); }
|
||||
}
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
|
@ -18,38 +35,33 @@ 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;
|
||||
private ControllerPane mkvPaneController, 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?
|
||||
private final AppPreferences appPreferences = AppPreferences.getINSTANCE();
|
||||
|
||||
private ResourceBundle resourceBundle;
|
||||
// Get host services for opening URLs etc.
|
||||
private HostServices hostServices;
|
||||
|
||||
private String currentPlaylistLocation;
|
||||
|
||||
private MplayerSlave mplayer;
|
||||
|
||||
// If application started with playlist passed as an argument, then we'll try to load it (if it's valid).
|
||||
public void setPlaylistAsArgument(String playlist) {
|
||||
|
@ -79,150 +91,19 @@ public class Controller implements Initializable {
|
|||
subsHide.setSelected(appPreferences.getSubtitlesHideSelected());
|
||||
|
||||
String[] recentPlaylists = appPreferences.getRecentPlaylists();
|
||||
for (int i = recentPlaylists.length-1; i >= 0; i--)
|
||||
if (!recentPlaylists[i].isEmpty())
|
||||
addRecentlyOpened(recentPlaylists[i]);
|
||||
for (int i = recentPlaylists.length-1; i >= 0; i--) {
|
||||
if (recentPlaylists[i].isEmpty())
|
||||
continue;
|
||||
addRecentlyOpened(recentPlaylists[i]);
|
||||
}
|
||||
|
||||
mplayer = new MplayerSlave(resourceBundle);
|
||||
}
|
||||
|
||||
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();
|
||||
// TODO: add 'link' button
|
||||
if (index+1 < mkvPaneController.getElementsCount() ) {
|
||||
mkvPaneController.setElementSelectedByIndex(index+1);
|
||||
}
|
||||
index = mkaPaneController.getElementSelectedIndex();
|
||||
if (index+1 < mkaPaneController.getElementsCount() ) {
|
||||
mkaPaneController.setElementSelectedByIndex(index+1);
|
||||
}
|
||||
index = subPaneController.getElementSelectedIndex();
|
||||
if (index+1 < subPaneController.getElementsCount() ) {
|
||||
subPaneController.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();
|
||||
|
@ -312,21 +193,21 @@ public class Controller implements Initializable {
|
|||
}
|
||||
|
||||
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);
|
||||
ObservableList<MenuItem> items = recentlyOpenedMenu.getItems();
|
||||
for (MenuItem item : items) {
|
||||
if (item.getUserData() != null && item.getUserData().equals(playlistPath)) {
|
||||
items.remove(item);
|
||||
items.add(0, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem menuItem = new MenuItem();
|
||||
String fileNameOnly;
|
||||
String playListName;
|
||||
|
||||
fileNameOnly = playlistPath.substring(playlistPath.lastIndexOf(File.separator) + 1);
|
||||
menuItem.setText(fileNameOnly);
|
||||
playListName = playlistPath.substring(
|
||||
playlistPath.lastIndexOf(File.separator) + 1, playlistPath.lastIndexOf("."));
|
||||
menuItem.setText(playListName);
|
||||
|
||||
menuItem.setUserData(playlistPath);
|
||||
menuItem.setOnAction(actionEvent -> {
|
||||
|
@ -334,9 +215,90 @@ public class Controller implements Initializable {
|
|||
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);
|
||||
if (items.size() >= 11)
|
||||
items.remove(9, recentlyOpenedMenu.getItems().size() - 2);
|
||||
items.add(0, menuItem);
|
||||
}
|
||||
|
||||
/* PLAYER */
|
||||
@FXML
|
||||
private void subsTriggerBtn(){
|
||||
mplayer.subtitlesSwitch();
|
||||
}
|
||||
@FXML
|
||||
private void fullscreenBtn(){
|
||||
mplayer.fullscreenSwitch();
|
||||
}
|
||||
@FXML
|
||||
private void muteBtn(){
|
||||
mplayer.mute();
|
||||
}
|
||||
@FXML
|
||||
private void playPrevTrackBtn(){
|
||||
int index = mkvPaneController.getElementSelectedIndex();
|
||||
if (index <= 0)
|
||||
return;
|
||||
|
||||
mkvPaneController.setElementSelectedByIndex(index-1);
|
||||
mplayer.forcePlay(appPreferences.getPath(),
|
||||
mkvPaneController.getElementSelected(),
|
||||
mkaPaneController.getElementSelected(),
|
||||
subPaneController.getElementSelected(),
|
||||
subPaneController.getSelectedEncoding(),
|
||||
subsHide.isSelected(),
|
||||
fullScreen.isSelected()
|
||||
);
|
||||
}
|
||||
@FXML
|
||||
private void playNextTrackBtn(){
|
||||
int index = mkvPaneController.getElementSelectedIndex();
|
||||
|
||||
if (index + 1 < mkvPaneController.getElementsCount()) {
|
||||
mkvPaneController.setElementSelectedByIndex(index + 1);
|
||||
}
|
||||
index = mkaPaneController.getElementSelectedIndex();
|
||||
if (index + 1 < mkaPaneController.getElementsCount()) {
|
||||
mkaPaneController.setElementSelectedByIndex(index + 1);
|
||||
}
|
||||
index = subPaneController.getElementSelectedIndex();
|
||||
if (index + 1 < subPaneController.getElementsCount()) {
|
||||
subPaneController.setElementSelectedByIndex(index + 1);
|
||||
}
|
||||
|
||||
mplayer.forcePlay(appPreferences.getPath(),
|
||||
mkvPaneController.getElementSelected(),
|
||||
mkaPaneController.getElementSelected(),
|
||||
subPaneController.getElementSelected(),
|
||||
subPaneController.getSelectedEncoding(),
|
||||
subsHide.isSelected(),
|
||||
fullScreen.isSelected()
|
||||
);
|
||||
}
|
||||
@FXML
|
||||
private void playBtn(){
|
||||
if (mkvPaneController.getElementSelected() == null)
|
||||
return;
|
||||
|
||||
mplayer.playPause(appPreferences.getPath(),
|
||||
mkvPaneController.getElementSelected(),
|
||||
mkaPaneController.getElementSelected(),
|
||||
subPaneController.getElementSelected(),
|
||||
subPaneController.getSelectedEncoding(),
|
||||
subsHide.isSelected(),
|
||||
fullScreen.isSelected()
|
||||
);
|
||||
}
|
||||
@FXML
|
||||
private void stopBtn(){
|
||||
mplayer.stop();
|
||||
}
|
||||
@FXML
|
||||
private void volumeUpBtn(){
|
||||
mplayer.volumeUp();
|
||||
}
|
||||
@FXML
|
||||
private void volumeDownBtn(){
|
||||
mplayer.volumeDown();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
src/main/java/mplayer4anime/ISlaveModeAppOrchestration.java
Normal file
23
src/main/java/mplayer4anime/ISlaveModeAppOrchestration.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
|
||||
public interface ISlaveModeAppOrchestration {
|
||||
// TODO: implement unified interface for mplayer and mpv
|
||||
}
|
|
@ -1,27 +1,44 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class LineRedirecter extends Thread {
|
||||
private InputStream inStr;
|
||||
private OutputStream outStr;
|
||||
private final InputStream inStream;
|
||||
private final OutputStream outStream;
|
||||
|
||||
LineRedirecter(InputStream in, OutputStream out){
|
||||
this.inStr = in;
|
||||
this.outStr = out;
|
||||
LineRedirecter(InputStream inStream, OutputStream outStream){
|
||||
this.inStream = inStream;
|
||||
this.outStream = outStream;
|
||||
}
|
||||
|
||||
public void run(){
|
||||
try {
|
||||
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inStr));
|
||||
PrintStream printStream = new PrintStream(outStr);
|
||||
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inStream));
|
||||
PrintStream printStream = new PrintStream(outStream);
|
||||
String playerOutput;
|
||||
|
||||
while ((playerOutput = bufferReader.readLine()) != null) {
|
||||
printStream.println(playerOutput);
|
||||
}
|
||||
|
||||
}catch (IOException e){
|
||||
}
|
||||
catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
/**
|
||||
Name: mplayer4anime
|
||||
@author Dmitry Isaenko
|
||||
License: GNU GPL v.3
|
||||
@version 0.12
|
||||
@see https://developersu.blogspot.com/search/label/mplayer4anime
|
||||
@see https://github.com/developersu/mplayer4anime
|
||||
2018-2019, Russia
|
||||
*/
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -55,17 +64,22 @@ public class MainFX extends Application {
|
|||
Runtime.getRuntime().addShutdownHook(new Thread(() -> tsih.interrupt()));
|
||||
|
||||
primaryStage.getIcons().addAll(
|
||||
new Image(MainFX.class.getResourceAsStream("/res/app_icon32x32.png")),
|
||||
new Image(MainFX.class.getResourceAsStream("/res/app_icon48x48.png")),
|
||||
new Image(MainFX.class.getResourceAsStream("/res/app_icon64x64.png")),
|
||||
new Image(MainFX.class.getResourceAsStream("/res/app_icon128x128.png"))
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon32x32.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon48x48.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon64x64.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon128x128.png"))
|
||||
);
|
||||
primaryStage.setTitle("mplayer4anime");
|
||||
primaryStage.setMinWidth(500);
|
||||
primaryStage.setMinHeight(375);
|
||||
primaryStage.setScene(new Scene(root, 1200, 800));
|
||||
Scene scene = new Scene(root,
|
||||
AppPreferences.getINSTANCE().getSceneWidth(),
|
||||
AppPreferences.getINSTANCE().getSceneHeight());
|
||||
primaryStage.setScene(scene);
|
||||
// Make linkage to controller method to handle exit() event in there.
|
||||
primaryStage.setOnHidden(e -> {
|
||||
AppPreferences.getINSTANCE().setSceneHeight(scene.getHeight());
|
||||
AppPreferences.getINSTANCE().setSceneWidth(scene.getWidth());
|
||||
tsih.interrupt();
|
||||
controller.shutdown();
|
||||
});
|
||||
|
|
170
src/main/java/mplayer4anime/MplayerSlave.java
Normal file
170
src/main/java/mplayer4anime/MplayerSlave.java
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||
private Process player;
|
||||
private PrintStream playerIn;
|
||||
private BufferedReader playerOutErr;
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
public MplayerSlave(ResourceBundle resourceBundle){
|
||||
this.resourceBundle = resourceBundle;
|
||||
}
|
||||
|
||||
private boolean playerSingleCommand(String command){
|
||||
if (player != null && player.isAlive()) {
|
||||
playerIn.print(command);
|
||||
playerIn.print("\n");
|
||||
playerIn.flush();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void subtitlesSwitch(){
|
||||
if (! playerSingleCommand("get_sub_visibility"))
|
||||
return;
|
||||
|
||||
try {
|
||||
String returnedStr;
|
||||
int returnedInt = 1;
|
||||
while ((returnedStr = playerOutErr.readLine()) != null) {
|
||||
if (returnedStr.startsWith("ANS_SUB_VISIBILITY=")) {
|
||||
returnedInt = Integer.parseInt(returnedStr.substring("ANS_SUB_VISIBILITY=".length()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (returnedInt == 1)
|
||||
playerSingleCommand("sub_visibility 0");
|
||||
else
|
||||
playerSingleCommand("sub_visibility 1");
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("Can't determine whether subtitles enabled or disabled");
|
||||
}
|
||||
}
|
||||
|
||||
public void fullscreenSwitch(){
|
||||
playerSingleCommand("vo_fullscreen");
|
||||
}
|
||||
|
||||
public void mute(){
|
||||
playerSingleCommand("mute");
|
||||
}
|
||||
|
||||
public void forcePlay(String mplayerPath,
|
||||
String VideoFile,
|
||||
String AudioFile,
|
||||
String SubtitlesFile,
|
||||
String subtitlesEncoding,
|
||||
boolean subtitlesHidden,
|
||||
boolean isFullscreen){
|
||||
try {
|
||||
if (player != null && player.isAlive()){
|
||||
playerSingleCommand("quit");
|
||||
player.waitFor(500, TimeUnit.MILLISECONDS);
|
||||
player.destroyForcibly();
|
||||
}
|
||||
playPause(mplayerPath, VideoFile, AudioFile, SubtitlesFile, subtitlesEncoding, subtitlesHidden, isFullscreen);
|
||||
}
|
||||
catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean pause(){
|
||||
if (player == null || !player.isAlive())
|
||||
return false;
|
||||
playerIn.print("pause");
|
||||
playerIn.print("\n");
|
||||
playerIn.flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void playPause(String mplayerPath,
|
||||
String VideoFile,
|
||||
String AudioFile,
|
||||
String SubtitlesFile,
|
||||
String subtitlesEncoding,
|
||||
boolean subtitlesHidden,
|
||||
boolean isFullscreen){
|
||||
if (pause())
|
||||
return;
|
||||
|
||||
boolean isAudio = AudioFile != null;
|
||||
boolean isSubtitles = SubtitlesFile != null;
|
||||
boolean SubEncodingDefault = subtitlesEncoding.equals("default");
|
||||
|
||||
try {
|
||||
player = new ProcessBuilder( // FUCKING MAGIC! DON'T CHANGE SEQUENCE
|
||||
mplayerPath, // It's a chance for Windows ;)
|
||||
"-slave",
|
||||
isAudio?"-audiofile":"",
|
||||
isAudio?AudioFile:"",
|
||||
"-quiet",
|
||||
isFullscreen ? "-fs" : "",
|
||||
VideoFile,
|
||||
subtitlesHidden||isSubtitles?"-nosub":"", // Turn off subtitles embedded into MKV file (and replace by localy-stored subs file if needed)
|
||||
isSubtitles?"-sub":"",
|
||||
isSubtitles? SubtitlesFile:"",
|
||||
isSubtitles?SubEncodingDefault?"":"-subcp":"", // Use subtitles -> YES -> Check if we need encoding
|
||||
isSubtitles?SubEncodingDefault?"": subtitlesEncoding:""
|
||||
).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 should be done this way because if we didn't pass them to mplayer during start then 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 than current implementation.
|
||||
*/
|
||||
if (subtitlesHidden)
|
||||
playerSingleCommand("sub_visibility 0");
|
||||
}
|
||||
catch (IOException e) {
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToStartMplayer"));
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
playerSingleCommand("stop");
|
||||
}
|
||||
|
||||
public void volumeUp(){
|
||||
playerSingleCommand("volume +1 0");
|
||||
}
|
||||
|
||||
public void volumeDown(){
|
||||
playerSingleCommand("volume -1 0");
|
||||
}
|
||||
}
|
|
@ -1,12 +1,30 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
/**
|
||||
* Creates window with notification
|
||||
* */
|
||||
public class ServiceWindow {
|
||||
/**
|
||||
* Create window with notification
|
||||
* */
|
||||
public static void getErrorNotification(String title, String body){
|
||||
Alert alertBox = new Alert(Alert.AlertType.ERROR);
|
||||
alertBox.setTitle(title);
|
||||
|
|
|
@ -1,32 +1,42 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime.Settings;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TextFormatter;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class ControllerListsSelector implements Initializable {
|
||||
public class ControllerListsSelector{
|
||||
@FXML
|
||||
private ListView<String> listView;
|
||||
@FXML
|
||||
private TextField newRecordText;
|
||||
private ObservableList<String> observableList;
|
||||
private ResourceBundle resourceBundle;
|
||||
|
||||
private boolean isListOfExtensions;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
resourceBundle = rb;
|
||||
}
|
||||
/**
|
||||
* Must be run on start
|
||||
* Set list content
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime.Settings;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -14,16 +32,12 @@ import java.util.ResourceBundle;
|
|||
import mplayer4anime.MediatorControl;
|
||||
|
||||
public class SettingsController implements Initializable {
|
||||
|
||||
private AppPreferences appPreferences;
|
||||
@FXML
|
||||
private ControllerListsSelector subExtensionListController;
|
||||
@FXML
|
||||
private ControllerListsSelector subEncodingListController;
|
||||
@FXML
|
||||
private ControllerListsSelector videoExtensionListController;
|
||||
@FXML
|
||||
private ControllerListsSelector audioExtensionListController;
|
||||
private ControllerListsSelector subExtensionListController,
|
||||
subEncodingListController,
|
||||
videoExtensionListController,
|
||||
audioExtensionListController;
|
||||
@FXML
|
||||
private Label pathToMplayerLbl;
|
||||
@FXML
|
||||
|
@ -31,7 +45,7 @@ public class SettingsController implements Initializable {
|
|||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resBundle) {
|
||||
appPreferences = new AppPreferences();
|
||||
appPreferences = AppPreferences.getINSTANCE();
|
||||
pathToMplayerLbl.setText(appPreferences.getPath());
|
||||
|
||||
// Subtitles should be shown first? If TRUE, then set checkbox.
|
||||
|
@ -72,16 +86,15 @@ public class SettingsController implements Initializable {
|
|||
|
||||
@FXML
|
||||
private void Cancel(){
|
||||
Stage thisStage = (Stage) pathToMplayerLbl.getScene().getWindow(); // TODO: consider refactoring. Non-urgent.
|
||||
thisStage.close();
|
||||
close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void Ok(){
|
||||
this.Apply();
|
||||
Stage thisStage = (Stage) pathToMplayerLbl.getScene().getWindow(); // TODO: consider refactoring. Non-urgent.
|
||||
thisStage.close();
|
||||
Apply();
|
||||
close();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void Apply(){
|
||||
appPreferences.setPath(pathToMplayerLbl.getText());
|
||||
|
@ -93,4 +106,9 @@ public class SettingsController implements Initializable {
|
|||
|
||||
MediatorControl.getInstance().sentUpdates(); // TODO: implement list to track what should be updated
|
||||
}
|
||||
|
||||
private void close(){
|
||||
Stage currentWindowStage = (Stage) pathToMplayerLbl.getScene().getWindow();
|
||||
currentWindowStage.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime.Settings;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -5,7 +23,6 @@ import javafx.scene.Parent;
|
|||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
import mplayer4anime.MainFX;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
@ -29,15 +46,14 @@ public class SettingsWindow {
|
|||
|
||||
try {
|
||||
Parent parentAbout = loaderSettings.load();
|
||||
//SettingsController settingsController = loaderSettings.getController();
|
||||
|
||||
stageAbout.setTitle(resourceBundle.getString("settings_SettingsName"));
|
||||
stageAbout.getIcons().addAll(
|
||||
new Image(MainFX.class.getResourceAsStream("/res/settings_icon32x32.png")),
|
||||
new Image(MainFX.class.getResourceAsStream("/res/settings_icon48x48.png")),
|
||||
new Image(MainFX.class.getResourceAsStream("/res/settings_icon64x64.png")),
|
||||
new Image(MainFX.class.getResourceAsStream("/res/settings_icon128x128.png"))
|
||||
); // TODO: change to something reliable
|
||||
new Image("/res/settings_icon32x32.png"),
|
||||
new Image("/res/settings_icon32x32.png"),
|
||||
new Image("/res/settings_icon48x48.png"),
|
||||
new Image("/res/settings_icon64x64.png"),
|
||||
new Image("/res/settings_icon128x128.png"));
|
||||
stageAbout.setScene(new Scene(parentAbout, 570, 500));
|
||||
stageAbout.show();
|
||||
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/*
|
||||
Copyright 2018-2021 Dmitry Isaenko
|
||||
|
||||
This file is part of mplayer4anime.
|
||||
|
||||
mplayer4anime is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
mplayer4anime is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package mplayer4anime.appPanes;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -10,28 +28,23 @@ import javafx.scene.control.ListView;
|
|||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.util.Callback;
|
||||
import mplayer4anime.AppPreferences;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class ControllerPane implements Initializable {
|
||||
|
||||
public class ControllerPane implements Initializable {
|
||||
private ResourceBundle resourceBundle;
|
||||
// use folderToOpen same variable in all panes
|
||||
private static String folderToOpen;
|
||||
|
||||
private AppPreferences appPreferences;
|
||||
|
||||
@FXML
|
||||
private ListView<File> paneListView;
|
||||
private ObservableList<File> paneFileList = FXCollections.observableArrayList();
|
||||
private final ObservableList<File> paneFileList = FXCollections.observableArrayList();
|
||||
|
||||
@FXML
|
||||
private Label paneLbl;
|
||||
|
@ -42,8 +55,9 @@ public class ControllerPane implements Initializable {
|
|||
public void initialize(URL url, ResourceBundle resBundle) {
|
||||
SetCellFactory(paneListView);
|
||||
resourceBundle = resBundle;
|
||||
appPreferences = new AppPreferences();
|
||||
appPreferences = AppPreferences.getINSTANCE();
|
||||
}
|
||||
|
||||
public void setPaneType(String paneType){
|
||||
this.paneType = paneType;
|
||||
|
||||
|
@ -69,12 +83,11 @@ public class ControllerPane implements Initializable {
|
|||
}
|
||||
/** Select element name (full path) using index recieved */
|
||||
public String getElementSelected(){
|
||||
if (this.paneListView.getSelectionModel().getSelectedItem() != null) {
|
||||
return this.paneFileList.get(this.getElementSelectedIndex()).toPath().toString();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
File item = paneListView.getSelectionModel().getSelectedItem();
|
||||
if (item != null) {
|
||||
return item.getAbsolutePath();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/** Select element in pane using index recieved */
|
||||
public void setElementSelectedByIndex(int index){
|
||||
|
@ -98,33 +111,23 @@ public class ControllerPane implements Initializable {
|
|||
return elementsArray;
|
||||
}
|
||||
|
||||
private void SetCellFactory(ListView<File> lv) {
|
||||
lv.setCellFactory(new Callback<ListView<File>, ListCell<File>>() {
|
||||
@Override
|
||||
public ListCell<File> call(ListView<File> fileListView) {
|
||||
return new ListCell<File>(){
|
||||
private void SetCellFactory(ListView<File> listView) {
|
||||
listView.setCellFactory(cb -> new ListCell<File>() {
|
||||
@Override
|
||||
public void updateItem(File item, boolean empty){
|
||||
public void updateItem(File item, boolean empty) {
|
||||
// have to call super here
|
||||
super.updateItem(item, empty);
|
||||
|
||||
String trimmedName;
|
||||
|
||||
if (item == null || empty){
|
||||
if (item == null || empty) {
|
||||
setText(null);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
trimmedName = item.getName();
|
||||
setText(trimmedName);
|
||||
}
|
||||
setText(item.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Open file selector (Open folder button in UI).
|
||||
* */
|
||||
|
||||
/** Open file selector (Open folder button in UI) */
|
||||
@FXML
|
||||
void openDirChooser(){
|
||||
String[] filesExtensionTmp;
|
||||
|
@ -166,30 +169,25 @@ public class ControllerPane implements Initializable {
|
|||
if (directoryReceived != null) {
|
||||
File[] files; // Store files mkv/mka
|
||||
|
||||
files = directoryReceived.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File file, String Name) {
|
||||
if (Name.lastIndexOf('.') > 0) {
|
||||
int lastindex = Name.lastIndexOf('.');
|
||||
String ext = Name.substring(lastindex);
|
||||
for (String key : filesExtension){ // TODO: add toLowerCase and validate whatever registry extension noted
|
||||
if (ext.equals(key.substring(1)))
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
return false;
|
||||
files = directoryReceived.listFiles((file, Name) -> {
|
||||
int lastIndexOfDot = Name.lastIndexOf('.');
|
||||
if (lastIndexOfDot > 0) {
|
||||
String ext = Name.substring(lastIndexOfDot);
|
||||
for (String key : filesExtension){ // TODO: add toLowerCase and validate whatever registry extension noted
|
||||
if (ext.equals(key.substring(1)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
displayFiles(files);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
System.out.println("No folder selected");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Open file selector (Open files button in UI).
|
||||
* */
|
||||
/** Open file selector (Open files button in UI) */
|
||||
@FXML
|
||||
void openFilesChooser(){
|
||||
String[] filesExtension;
|
||||
|
@ -213,9 +211,8 @@ public class ControllerPane implements Initializable {
|
|||
lowerAndUpperExts.add(s);
|
||||
lowerAndUpperExts.add(s.toUpperCase());
|
||||
}
|
||||
filesExtension = lowerAndUpperExts.toArray(new String[lowerAndUpperExts.size()]);
|
||||
|
||||
List<File> filesRecievedList;
|
||||
List<File> filesReceivedList;
|
||||
|
||||
FileChooser fc = new FileChooser();
|
||||
fc.setTitle(resourceBundle.getString("SelectFile"));
|
||||
|
@ -223,16 +220,19 @@ public class ControllerPane implements Initializable {
|
|||
fc.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||
else
|
||||
fc.setInitialDirectory(new File(folderToOpen));
|
||||
fc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter(paneType, filesExtension));
|
||||
|
||||
filesRecievedList = fc.showOpenMultipleDialog(paneListView.getScene().getWindow());
|
||||
if (filesRecievedList != null){ // TODO: and !filesRecieved.isEmpty()
|
||||
File[] filesRecieved = new File[filesRecievedList.size()];
|
||||
filesRecievedList.toArray(filesRecieved);
|
||||
displayFiles(filesRecieved);
|
||||
} else {
|
||||
fc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter(paneType,
|
||||
lowerAndUpperExts.toArray(new String[0])));
|
||||
|
||||
filesReceivedList = fc.showOpenMultipleDialog(paneListView.getScene().getWindow());
|
||||
if (filesReceivedList == null) {
|
||||
System.out.println("No files selected");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] filesReceived = new File[filesReceivedList.size()];
|
||||
filesReceivedList.toArray(filesReceived);
|
||||
displayFiles(filesReceived);
|
||||
}
|
||||
/**
|
||||
* Set files using lists. Used if playlist loaded
|
||||
|
@ -250,7 +250,6 @@ public class ControllerPane implements Initializable {
|
|||
if (files != null && files.length > 0) {
|
||||
// spiced java magic
|
||||
Arrays.sort(files);
|
||||
|
||||
// Remember the folder used for MKV and reuse it when user opens MKA/subs folder (as new default path instead of user.home)
|
||||
folderToOpen = files[0].getParent();
|
||||
//System.out.println(folderToOpen);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
about_line1=mplayer4amine distributes under GNU GPLv3 license.
|
||||
about_line2=Release: v0.14.1
|
||||
about_line2=Release: v0.15
|
||||
about_line3=Development & maintenance by Dmitry Isaenko.
|
||||
about_AboutName=About
|
||||
main_tab_audio=Audio
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
menu_File_Recent=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 \u0444\u0430\u0439\u043B\u044B...
|
||||
about_line1=mplayer4amine \u0440\u0430\u0441\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u044F\u0435\u0442\u0441\u044F \u043F\u043E \u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0438 GNU GPLv3.
|
||||
about_line2=\u0420\u0435\u043B\u0438\u0437: v0.14.1
|
||||
about_line2=\u0420\u0435\u043B\u0438\u0437: v0.15
|
||||
about_line3=\u0420\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0438 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F \u0414\u043C\u0438\u0442\u0440\u0438\u0435\u043C \u0418\u0441\u0430\u0435\u043D\u043A\u043E.
|
||||
about_AboutName=\u041E \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438
|
||||
main_tab_audio=\u0410\u0443\u0434\u0438\u043E
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
-fx-fill: #000000;
|
||||
}
|
||||
.tab-paneSettings .tab:selected SVGPath{
|
||||
-fx-fill: #f90000;
|
||||
-fx-fill: #c30000;
|
||||
}
|
||||
.tab-paneSettings .tab{
|
||||
-fx-background-color: #ffffff;
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
Loading…
Reference in a new issue