Playlists added
UI changed
Code refactored
master
Dmitry Isaenko 2018-11-25 18:13:09 +03:00
parent fa31999daf
commit a17b54c87b
19 changed files with 663 additions and 217 deletions

View File

@ -2,20 +2,27 @@ package mplayer4anime.About;
import javafx.application.HostServices;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class AboutController {
public class AboutController implements Initializable {
private HostServices hostServices;
public void setHostServices(HostServices hs){
void setHostServices(HostServices hs){
this.hostServices = hs;
}
@FXML
private Button buttonOk;
@FXML
private TextArea GSONLicense;
@FXML
private void buttonClickOk(){
@ -38,6 +45,29 @@ public class AboutController {
e.printStackTrace();
}
}
@FXML
private void libGSON(){
try {
hostServices.showDocument("https://github.com/google/gson");
} catch (Exception e){
e.printStackTrace();
}
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
GSONLicense.setText("Copyright 2008 Google Inc.\n" +
"\n" +
"Licensed under the Apache License, Version 2.0 (the \"License\");\n" +
"you may not use this file except in compliance with the License.\n" +
"You may obtain a copy of the License at\n" +
"\n" +
" http://www.apache.org/licenses/LICENSE-2.0\n" +
"\n" +
"Unless required by applicable law or agreed to in writing, software\n" +
"distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
"See the License for the specific language governing permissions and\n" +
"limitations under the License.");
}
}

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@ public class AboutWindow {
Stage stageAbout = new Stage();
stageAbout.setMinWidth(500);
stageAbout.setMinHeight(230);
stageAbout.setMinHeight(450);
FXMLLoader loaderAbout = new FXMLLoader(getClass().getResource("AboutLayout.fxml"));
ResourceBundle resourceBundle;
@ -42,7 +42,7 @@ public class AboutWindow {
new Image(Main.class.getResourceAsStream("/mplayer4anime/res/app_icon64x64.png")),
new Image(Main.class.getResourceAsStream("/mplayer4anime/res/app_icon128x128.png"))
); // TODO: change to something reliable
stageAbout.setScene(new Scene(parentAbout, 500, 230));
stageAbout.setScene(new Scene(parentAbout, 500, 450));
stageAbout.show();

View File

@ -19,9 +19,10 @@ public class AppPreferences {
return preferences.get("PATH", "mplayer");
}
/* Return subtitles priority to show
* TRUE - Subtitles tab opens first
* FALSE - Subtitles tab opens as usual
/** Return subtitles priority to show
* @return
* TRUE - Subtitles tab opens first
* FALSE - Subtitles tab opens as usual
*/
public boolean getSubtilesFirst(){
return preferences.getBoolean("SUBS_TAB_FIRST", false);
@ -40,9 +41,10 @@ public class AppPreferences {
return preferences.getBoolean("LOAD_LISTS_ON_START", false); // Don't populate lists by-default
}
/** Convert strings array to singls string. Used in:
* setSubsExtensionsList
* setSubsCodepageList
/** Convert strings array to singls string.
* Used in:
* setSubsExtensionsList
* setSubsEncodingList
*/
private void storeSingleStringList(String whichList, String[] strArr){
StringBuilder collect = new StringBuilder();
@ -58,45 +60,49 @@ public class AppPreferences {
public void setSubsExtensionsList(String[] subsList){ storeSingleStringList("SUBS_EXTENSIONS_LIST", subsList); }
public String[] getSubsExtensionsList(){ return preferences.get("SUBS_EXTENSIONS_LIST", ".ass@@@.crt@@@").split("@@@"); }
/** Handle lists of the subtitles codepage selector */
public void setSubsCodepageList(String[] subsCodepageList){ storeSingleStringList("SUBS_CODEPAGE_LIST", subsCodepageList); }
public String[] getSubsCodepageList(){ return preferences.get("SUBS_CODEPAGE_LIST", "default@@@utf8@@@cp1251@@@koi8-r").split("@@@"); }
/** Handle lists of the subtitles encodings selector */
public void setSubsEncodingList(String[] subsEncodingList){ storeSingleStringList("SUBS_ENCODINGS_LIST", subsEncodingList); }
public String[] getSubsEncodingList(){ return preferences.get("SUBS_ENCODINGS_LIST", "default@@@utf8@@@cp1251@@@koi8-r").split("@@@"); }
// Save & recover selected by user Subtitles format
/** Save & recover selected by user Subtitles format */
public void setLastTimeUsedSusExt(String selected){ preferences.put("SUBS_EXT_LAST_TIME_SELECTED", selected); }
public String getLastTimeUsedSubsExt(){ return preferences.get("SUBS_EXT_LAST_TIME_SELECTED", ""); }
// Save & recover selected by user Subtitles codepage
public void setLastTimeUsedSubsCodepage(String selected){ preferences.put("SUBS_CODEPAGE_LAST_TIME_SELECTED", selected); }
public String getLastTimeUsedSubsCodepage(){ return preferences.get("SUBS_CODEPAGE_LAST_TIME_SELECTED", ""); }
/** Save & recover selected by user Subtitles encoding */
public void setLastTimeUsedSubsEncoding(String selected){ preferences.put("SUBS_ENCODING_LAST_TIME_SELECTED", selected); }
public String getLastTimeUsedSubsEncoding(){ return preferences.get("SUBS_ENCODING_LAST_TIME_SELECTED", ""); }
// Save & recover Full Screen checkbox, if selected
/** Save & recover Full Screen checkbox, if selected */
public boolean getFullScreenSelected(){
return preferences.getBoolean("FULL_SCREEN_SELECTED", false);
}
public void setFullScreenSelected(boolean set){ preferences.putBoolean("FULL_SCREEN_SELECTED", set); }
// Save & recover Subtitles checkbox, if selected
/** Save & recover Subtitles checkbox, if selected */
public boolean getSubtitlesHideSelected(){
return preferences.getBoolean("FULL_SUBTITLES_HIDE_SELECTED", false);
}
public void setSubtitlesHideSelected(boolean set){ preferences.putBoolean("FULL_SUBTITLES_HIDE_SELECTED", set); }
/** Lists managment */
// Return lists itself of the latest opened folders (used only in Controller.class)
private String getList(String whichList){
return preferences.get(whichList, "");
/** Return recently opened elements */
public String[] getRecentPlaylists(){
String[] recentPlaylists = new String[10];
for (int i=0; i<10; i++)
recentPlaylists[i] = preferences.get("RECENT_PLS_" + i, "");
return recentPlaylists;
}
// Save lists itself of the latest opened folders (used only in Controller.class)
private void setList(String whichList, String value){
preferences.put(whichList, value);
/** Store recently opened elements */
public void setRecentPlaylists(String[] recentPlaylists){
if (recentPlaylists != null && recentPlaylists.length > 0) {
int i;
for (i = 0; i < recentPlaylists.length && !(i > 10); i++)
if (recentPlaylists[i] != null && !recentPlaylists[i].isEmpty())
preferences.put("RECENT_PLS_" + i, recentPlaylists[i]);
else
preferences.put("RECENT_PLS_" + i, "");
for (;i<10;i++) // Not needed. Logic may handle recieved String to be less or greater then String[10], but it never happened.
preferences.put("RECENT_PLS_" + i, "");
}
}
public String getListMKV(){ return getList("MKV"); }
public String getListMKA(){ return getList("MKA"); }
public String getListSUB(){ return getList("SUB"); }
public void setListMKV(String value){setList("MKV", value);}
public void setListMKA(String value){setList("MKA", value);}
public void setListSUB(String value){setList("SUB", value);}
}

View File

@ -2,11 +2,16 @@ package mplayer4anime;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.collections.FXCollections;
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.ControllerMKA;
import mplayer4anime.appPanes.ControllerMKV;
@ -14,6 +19,7 @@ import mplayer4anime.appPanes.ControllerSUB;
import java.io.*;
import java.net.URL;
import java.util.ListIterator;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@ -23,7 +29,10 @@ public class Controller implements Initializable {
private ControllerSUB subPaneController;
@FXML
private ControllerMKA mkaPaneController;
@FXML
private Label statusLbl;
@FXML
private Menu recentlyOpenedMenu;
// Get preferences
private AppPreferences appPreferences = new AppPreferences();
@ -41,6 +50,7 @@ public class Controller implements Initializable {
@FXML
private CheckMenuItem subsHide;
private String currentPlaylistLocation = null; //TODO: move to the constructor?
@Override
public void initialize(URL url, ResourceBundle rb) {
// Register this controller in mediator
@ -49,49 +59,30 @@ public class Controller implements Initializable {
resourceBundle = rb;
// Set default extension of the subtitles files:
subPaneController.subtExtList = FXCollections.observableArrayList( appPreferences.getSubsExtensionsList() ); // Receive list from storage
subPaneController.subtExt.setItems(subPaneController.subtExtList);
if (appPreferences.getLastTimeUsedSubsExt().isEmpty()) // not sure that it's possible
subPaneController.subtExt.setValue(subPaneController.subtExtList.get(0));
else
subPaneController.subtExt.setValue(appPreferences.getLastTimeUsedSubsExt());
subPaneController.setSubtExt(appPreferences.getSubsExtensionsList(), appPreferences.getLastTimeUsedSubsExt());// Receive list from storage & set selected value
// Set default list of codepages of the subtitles files:
subPaneController.subtCodepageList = FXCollections.observableArrayList(appPreferences.getSubsCodepageList());
subPaneController.subtCodepage.setItems(subPaneController.subtCodepageList);
if (appPreferences.getLastTimeUsedSubsCodepage().isEmpty())
subPaneController.subtCodepage.setValue(subPaneController.subtCodepageList.get(0));
else
subPaneController.subtCodepage.setValue(appPreferences.getLastTimeUsedSubsCodepage());
// 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
}
/* Populating settings from the previous run /*/
// Populating lists
if (appPreferences.getLoadListsOnStart()){ // TODO: probably should be dedicated method in abstract class defined
if (!appPreferences.getListMKV().isEmpty()){
mkvPaneController.getFilesFromFolder(new File(appPreferences.getListMKV()), ".mkv");
}
if (!appPreferences.getListMKA().isEmpty()){
mkaPaneController.getFilesFromFolder(new File(appPreferences.getListMKA()), ".mka");
}
if (!appPreferences.getListSUB().isEmpty()){
subPaneController.getFilesFromFolder(new File(appPreferences.getListSUB()), appPreferences.getLastTimeUsedSubsExt());
}
}
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 */
/* PLAYER COMMANDS */
private boolean playerSingleCommand(String command){
if (player != null && player.isAlive()) {
playerIn.print(command);
@ -103,27 +94,26 @@ public class Controller implements Initializable {
@FXML
private void subsTriggerBtn(){
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;
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");
}
}
catch (IOException e) {
System.out.println("Can't determine if subtitles enabled/disabled");
}
if (returnedInt == 1)
playerSingleCommand("sub_visibility 0");
else
playerSingleCommand("sub_visibility 1");
if (returnedInt == 1)
playerSingleCommand("sub_visibility 0");
else
playerSingleCommand("sub_visibility 1");
}
}
@FXML
private void fullscreenBtn(){ playerSingleCommand("vo_fullscreen"); }
@ -136,9 +126,9 @@ public class Controller implements Initializable {
while (player.isAlive()); // TODO: remove crutch, implement bike
}
int index;
index = mkvPaneController.paneListView.getSelectionModel().getSelectedIndex();
index = mkvPaneController.getElementSelectedIndex();
if (index > 0) {
mkvPaneController.paneListView.getSelectionModel().select(index-1);
mkvPaneController.setElementSelectedByIndex(index-1); // .selectNext / .selectPrevious
playBtn();
}
}
@ -149,9 +139,9 @@ public class Controller implements Initializable {
while (player.isAlive()); // TODO: remove crutch, implement bike
}
int index;
index = mkvPaneController.paneListView.getSelectionModel().getSelectedIndex();
if (index+1 < mkvPaneController.paneFileList.size() ) {
mkvPaneController.paneListView.getSelectionModel().select(index+1);
index = mkvPaneController.getElementSelectedIndex();
if (index+1 < mkvPaneController.getElementsCount() ) {
mkvPaneController.setElementSelectedByIndex(index+1);
playBtn();
}
}
@ -162,10 +152,10 @@ public class Controller implements Initializable {
@FXML
private void playBtn(){
if (mkvPaneController.paneListView.getSelectionModel().getSelectedItem() != null) {
boolean Audio = !mkaPaneController.paneFileList.isEmpty() && mkvPaneController.paneListView.getSelectionModel().getSelectedIndex() < mkaPaneController.paneFileList.size();
boolean Subtitles = !subPaneController.paneFileList.isEmpty() && mkvPaneController.paneListView.getSelectionModel().getSelectedIndex() < subPaneController.paneFileList.size();
boolean SubCodepageDefault = subPaneController.subtCodepage.getValue().equals("default");
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()) {
@ -173,15 +163,15 @@ public class Controller implements Initializable {
appPreferences.getPath(), // It's a chance for Windows ;)
"-slave",
Audio?"-audiofile":"",
Audio? mkaPaneController.paneFileList.get(mkvPaneController.paneListView.getSelectionModel().getSelectedIndex()).toPath().toString():"",
Audio? mkaPaneController.getElementSelected():"",
"-quiet",
fullScreen.isSelected() ? "-fs" : "",
mkvPaneController.paneFileList.get(mkvPaneController.paneListView.getSelectionModel().getSelectedIndex()).toPath().toString(),
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.paneFileList.get(mkvPaneController.paneListView.getSelectionModel().getSelectedIndex()).toPath().toString():"",
Subtitles?SubCodepageDefault?"":"-subcp":"", // Use subtitles -> YES -> Check if we need codepage
Subtitles?SubCodepageDefault?"": subPaneController.subtCodepage.getValue():""
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);
@ -200,19 +190,13 @@ public class Controller implements Initializable {
*/
if (subsHide.isSelected())
playerSingleCommand("sub_visibility 0");
} else {
playerIn.print("pause");
playerIn.print("\n");
playerIn.flush();
}
} catch (IOException e) {
// e.printStackTrace(); // No need
Alert alertBox = new Alert(Alert.AlertType.ERROR);
alertBox.setTitle(resourceBundle.getString("Error"));
alertBox.setHeaderText(null);
alertBox.setContentText(resourceBundle.getString("unableToStartMplayerError"));
alertBox.show();
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorUnableToStartMplayer"));
}
} else { System.out.println("File not selected"); }
}
@ -224,69 +208,140 @@ public class Controller implements Initializable {
@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
public void shutdown(){
// If we should save/restore lists ...
if (appPreferences.getLoadListsOnStart()) {
if (mkvPaneController.paneFileList.isEmpty())
appPreferences.setListMKV("");
else
appPreferences.setListMKV(mkvPaneController.paneFileList.get(0).getParent());
if (mkaPaneController.paneFileList.isEmpty())
appPreferences.setListMKA("");
else
appPreferences.setListMKA(mkaPaneController.paneFileList.get(0).getParent());
if (subPaneController.paneFileList.isEmpty())
appPreferences.setListSUB("");
else
appPreferences.setListSUB(subPaneController.paneFileList.get(0).getParent());
}
appPreferences.setLastTimeUsedSusExt(subPaneController.subtExt.getValue());
appPreferences.setLastTimeUsedSubsCodepage(subPaneController.subtCodepage.getValue());
void shutdown(){
appPreferences.setLastTimeUsedSusExt(subPaneController.getSelectedExt());
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 infoBnt(){ new AboutWindow(this.hostServices); } // TODO: fix this shit with hostSerivces that doesn't work @ linux
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.
public void updateAfterSettingsChanged(){
/** update list of extensions */
void updateAfterSettingsChanged(){
/* update list of extensions */
// Clear and update list
String extensionPrevSelected = subPaneController.subtExt.getValue();
subPaneController.subtExtList.clear();
subPaneController.subtExtList.setAll(appPreferences.getSubsExtensionsList());
// Try to restore previously selected element
if (subPaneController.subtExtList.contains(extensionPrevSelected))
subPaneController.subtExt.setValue(extensionPrevSelected);
else
subPaneController.subtExt.setValue(subPaneController.subtExtList.get(0));
subPaneController.setSubtExt(appPreferences.getSubsExtensionsList(), null);
// In case of application failure should be better to save this immediately
appPreferences.setLastTimeUsedSusExt(subPaneController.subtExt.getValue());
appPreferences.setLastTimeUsedSusExt(subPaneController.getSelectedEncoding());
/** update list of codepage */
String codepagePrevSelected = subPaneController.subtCodepage.getValue();
subPaneController.subtCodepageList.clear();
subPaneController.subtCodepageList.setAll(appPreferences.getSubsCodepageList());
// Try to restore previously selected element
if (subPaneController.subtCodepageList.contains(codepagePrevSelected))
subPaneController.subtCodepage.setValue(codepagePrevSelected);
else
subPaneController.subtCodepage.setValue(subPaneController.subtCodepageList.get(0));
/* update list of encoding */
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), null);
// In case of application failure should be better to save this immediately
appPreferences.setLastTimeUsedSubsCodepage(subPaneController.subtCodepage.getValue());
appPreferences.setLastTimeUsedSubsEncoding(subPaneController.getSelectedEncoding());
}
@FXML
private void openBtn() {
JsonStorage jsonStorage = Playlists.Read(resourceBundle);
if (jsonStorage != null) {
mkvPaneController.setFilesFromList(jsonStorage.getVideo());
mkaPaneController.setFilesFromList(jsonStorage.getAudio());
subPaneController.setFilesFromList(jsonStorage.getSubs());
subPaneController.selectEncodingValue(jsonStorage.getSubEncoding(), appPreferences);
this.currentPlaylistLocation = Playlists.getPlaylistLocation(); // TODO: Implement listener? mmm...
this.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));
if (jsonStorage != null) {
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);
}
}
});
// 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);
}
}

View File

@ -1,12 +1,12 @@
package mplayer4anime;
/***********************************************
* Name: mplayer4anime *
* Author: Dmitry Isaenko *
* License: GNU GPL v.3 *
* Version: 0.9 *
* Site: https://developersu.blogspot.com/ *
* 2018, Russia *
***********************************************/
/**
Name: mplayer4anime
@author Dmitry Isaenko
License: GNU GPL v.3
@version 0.10
@see https://developersu.blogspot.com/
2018, Russia
*/
import javafx.application.Application;
import javafx.fxml.FXMLLoader;

View File

@ -0,0 +1,28 @@
package mplayer4anime.Playlists;
public class JsonStorage {
private final String Ver;
private final String[] Video;
private final String[] Audio;
private final String[] Subtitles;
private final String SubEncoding;
public String getVer() {return Ver; }
public String[] getVideo() {return Video; }
public String[] getAudio() {return Audio; }
public String[] getSubs() {return Subtitles; }
public String getSubEncoding() {return SubEncoding; }
public JsonStorage(String[] videoArr, String[] audioArr, String[] subsArr, String subEncoding){
Ver = "1";
Video = videoArr;
Audio = audioArr;
Subtitles = subsArr;
if (subsArr != null && subsArr.length != 0)
this.SubEncoding = subEncoding;
else
this.SubEncoding = "";
}
}

119
Playlists/Playlists.java Normal file
View File

@ -0,0 +1,119 @@
package mplayer4anime.Playlists;
import com.google.gson.*;
import javafx.stage.FileChooser;
import mplayer4anime.ServiceWindow;
import java.io.*;
import java.util.ResourceBundle;
public class Playlists {
private static String playlistLocation;
//TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
/**
* Interface for Save As functionality
* */
public static boolean SaveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
File playlistFile;
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("SelectFile"));
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
fileChooser.setInitialFileName("MyPlaylist.alpr");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
playlistFile = fileChooser.showSaveDialog(null);
return writeFile(resourceBundle, playlistFile, jStorage);
}
/**
* Interface for Save functionality
* */
public static boolean SaveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
if (playlistLocation == null || playlistLocation.equals("")){
return Playlists.SaveAs(resourceBundle, jStorage);
}
else {
return writeFile(resourceBundle, new File(playlistLocation), jStorage);
}
}
// Working with file itself
private static boolean writeFile(ResourceBundle resourceBundle, File playlistFile, JsonStorage jStorage){
// TODO: Add 'Override pop-up notification!'
if (playlistFile != null) {
if (!playlistFile.getAbsolutePath().endsWith(".alpr")) {
playlistFile = new File(playlistFile.getAbsolutePath() + ".alpr");
}
try (Writer writer = new OutputStreamWriter(new FileOutputStream(playlistFile.getAbsolutePath()), "UTF-8"))
{
Gson jsonObject = new GsonBuilder().setPrettyPrinting().create();
jsonObject.toJson(jStorage, writer);
writer.close();
playlistLocation = playlistFile.getAbsolutePath();
// Return success notification
return true;
} catch (java.io.FileNotFoundException e){
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorFileNotFound"));
} catch (java.io.UnsupportedEncodingException e){
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnSaveIncorrectEncoding"));
} catch (java.io.IOException e){
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnSaveIOProblem"));
}
return false;
}
else {
System.out.println("Unable to save: File not selected");
return false;
}
}
/**
* Interface for Opening playlists via FileChooser
* */
public static JsonStorage Read(ResourceBundle resourceBundle){
File playlistFile;
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("SelectFile"));
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
fileChooser.setInitialFileName("MyPlaylist.alpr");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
playlistFile = fileChooser.showOpenDialog(null);
return ReadByPath(resourceBundle, playlistFile);
}
/**
* Interface for Opening playlists using file itself
* */
public static JsonStorage ReadByPath(ResourceBundle resourceBundle, File playlistFile){
if (playlistFile != null) {
try (Reader reader = new InputStreamReader(new FileInputStream(playlistFile))) {
JsonStorage jStorage = new Gson().fromJson(reader, JsonStorage.class);
if (jStorage != null){
playlistLocation = playlistFile.getAbsolutePath();
return jStorage;
}
else
return null;
} catch (java.io.FileNotFoundException e){
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorFileNotFound"));
} catch (com.google.gson.JsonSyntaxException e){
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnOpenIncorrectFormatOfFile"));
} catch (java.io.IOException e){
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"), resourceBundle.getString("ErrorOnOpenIOProblem"));
}
return null;
}
else {
System.out.println("Playlist file not selected");
return null;
}
}
/** Return path to file opened */
public static String getPlaylistLocation(){
return playlistLocation;
}
}

16
ServiceWindow.java Normal file
View File

@ -0,0 +1,16 @@
package mplayer4anime;
import javafx.scene.control.Alert;
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);
alertBox.setHeaderText(null);
alertBox.setContentText(body);
alertBox.show();
}
}

View File

@ -147,7 +147,7 @@ public class SettingsController implements Initializable {
subsExtListView.setItems(subsExtObservableList);
//---------------------------------------------------------
// Populate list of avaliable codepages
subsCodepageObservableList = FXCollections.observableArrayList(appPreferences.getSubsCodepageList());
subsCodepageObservableList = FXCollections.observableArrayList(appPreferences.getSubsEncodingList());
subsCodepageListView.setItems(subsCodepageObservableList);
}
@ -191,7 +191,7 @@ public class SettingsController implements Initializable {
appPreferences.setSubtilesFirst(subtitlesFirstCheckBox.isSelected());
appPreferences.setLoadListsOnStart(listsLoadOnStartCheckBox.isSelected());
appPreferences.setSubsExtensionsList(Arrays.copyOf(subsExtObservableList.toArray(), subsExtObservableList.toArray().length, String[].class));
appPreferences.setSubsCodepageList(Arrays.copyOf(subsCodepageObservableList.toArray(), subsCodepageObservableList.toArray().length, String[].class));
appPreferences.setSubsEncodingList(Arrays.copyOf(subsCodepageObservableList.toArray(), subsCodepageObservableList.toArray().length, String[].class));
MediatorControl.getInstance().sentUpdates(); // TODO: implement list to track what should be updated

View File

@ -80,7 +80,7 @@
<HBox spacing="5.0" VBox.vgrow="NEVER">
<children>
<TextField fx:id="subsExtNewRecordText" HBox.hgrow="ALWAYS" />
<Button fx:id="subsExtNewRecordBtn" mnemonicParsing="false" onAction="#subsExtAddNewRecord">
<Button mnemonicParsing="false" onAction="#subsExtAddNewRecord">
<graphic>
<SVGPath content="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" fill="#007f08" />
</graphic>

View File

@ -23,8 +23,8 @@ public abstract class ControllerPane implements Initializable {
private static String folderToOpen;
@FXML
public ListView<File> paneListView;
public ObservableList<File> paneFileList = FXCollections.observableArrayList();
private ListView<File> paneListView;
private ObservableList<File> paneFileList = FXCollections.observableArrayList();
@Override
public void initialize(URL url, ResourceBundle resBundle) {
@ -32,6 +32,41 @@ public abstract class ControllerPane implements Initializable {
resourceBundle = resBundle;
}
/** Get index of the selected in pane element */
public int getElementSelectedIndex(){
return this.paneListView.getSelectionModel().getSelectedIndex();
}
/** 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;
}
}
/** Select element in pane using index recieved */
public void setElementSelectedByIndex(int index){
this.paneListView.getSelectionModel().select(index);
}
/** Get number of elements loaded into the pane */
public int getElementsCount(){
return this.paneFileList.size();
}
/** Check if there are any elements loaded */
public boolean isElementsListEmpty(){
return paneFileList.isEmpty();
}
/** Get all elements
* Used in Json playlist writer only */
public String[] getElementsAll(){
String[] elementsArray = new String[this.getElementsCount()];
for (int i = 0; i < elementsArray.length; i++){
elementsArray[i] = paneFileList.get(i).toString();
}
return elementsArray;
}
private void SetCellFactory(ListView<File> lv) {
lv.setCellFactory(new Callback<ListView<File>, ListCell<File>>() {
@Override
@ -56,8 +91,10 @@ public abstract class ControllerPane implements Initializable {
}
});
}
protected void openFileChooser (String key){
/**
* Open file selector (Open folder button in UI).
* */
void openFileChooser (String key){
File directoryReceived; // Store files (folder) received from selector
DirectoryChooser dirSelect;
@ -68,17 +105,17 @@ public abstract class ControllerPane implements Initializable {
dirSelect.setInitialDirectory(new File(System.getProperty("user.home")));
else
dirSelect.setInitialDirectory(new File(folderToOpen));
directoryReceived = dirSelect.showDialog(null); // TODO: Clarify how the fuck is it works
directoryReceived = dirSelect.showDialog(paneListView.getScene().getWindow());
// GET LIST OF MKV/MKA FILES within directory
// GET LIST OF FILES from directory
if (directoryReceived != null) {
getFilesFromFolder(directoryReceived, key);
setFilesFromFolder(directoryReceived, key);
} else {
System.out.println("\tNo folder selected");
}
}
public void getFilesFromFolder(File directoryReceived, String key){
private void setFilesFromFolder(File directoryReceived, String key) {
File[] files; // Store files mkv/mka
files = directoryReceived.listFiles(new FilenameFilter() {
@ -95,17 +132,33 @@ public abstract class ControllerPane implements Initializable {
}
});
displayFiles(files);
}
/**
* Set files using lists. Used if playlist loaded
* */
public void setFilesFromList(String[] fileLocations){
if (fileLocations != null && fileLocations.length != 0) {
File[] files = new File[fileLocations.length];
for (int i=0; i < fileLocations.length; i++)
files[i] = new File(fileLocations[i]);
displayFiles(files);
}
}
private void displayFiles(File[] files){
if (files != null && files.length > 0) {
// spiced java magic
Arrays.sort(files);
// DEBUG START
/* DEBUG START
for (File eachFile : files)
System.out.println(eachFile.getAbsoluteFile());
// DEBUG END
DEBUG END */
// 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);
//System.out.println(folderToOpen);
paneListView.getItems().clear(); // wipe elements from ListView
paneFileList.addAll(files);
@ -147,4 +200,4 @@ public abstract class ControllerPane implements Initializable {
// TO IMPLEMENT IN REAL CLASS
@FXML
protected abstract void openAction();
}
}

View File

@ -1,20 +1,90 @@
package mplayer4anime.appPanes;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ChoiceBox;
import mplayer4anime.AppPreferences;
import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;
public class ControllerSUB extends ControllerPane {
// TODO: Move file extension filtering options to the OS-selector and remove drop-down with file ext. filtering options
@FXML
public ChoiceBox<String> subtExt;
private ChoiceBox<String> subtExt;
// Observable list of the content subtExt
public ObservableList<String> subtExtList;
private ObservableList<String> subtExtList;
@FXML
public ChoiceBox<String> subtCodepage;
// Observable list of the content subtCodepage
public ObservableList<String> subtCodepageList;
private ChoiceBox<String> subtEncoding;
// Observable list of the content subtEncoding
private ObservableList<String> subEncodingList;
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
this.subtExtList = FXCollections.observableArrayList();
this.subEncodingList = FXCollections.observableArrayList();
}
@Override
protected void openAction() { openFileChooser(subtExt.getValue()); } // TODO: check if non-empty and show error if needed
}
protected void openAction() { openFileChooser(subtExt.getValue());} // TODO: check if non-empty and show error if needed
/** Return selected file extension */
// Walking on the thin ice..
public String getSelectedExt(){
return subtExt.getSelectionModel().getSelectedItem();
}
/** Return selected file encoding */
public String getSelectedEncoding(){
return subtEncoding.getSelectionModel().getSelectedItem();
}
/**
* Set Files extensions list and select element
* */
public void setSubtExt(String[] list, String selection){
setMenuElements(subtExt, subtExtList, list, selection);
}
/**
* Set encoding list and select element
* */
public void setEncoding(String[] list, String selection){
setMenuElements(subtEncoding, subEncodingList, list, selection);
}
/* Encoding and Extension common setter */
private void setMenuElements(ChoiceBox<String> menu, ObservableList<String> obsList, String[] list, String selection){
String currentlySelectedValue = menu.getValue();
obsList.clear();
obsList.setAll(list);
menu.setItems(obsList);
if (selection == null || selection.isEmpty())
// Try to restore previously selected value if it existed before and exists in the new list
if (currentlySelectedValue !=null && !currentlySelectedValue.isEmpty() && obsList.contains(currentlySelectedValue))
menu.getSelectionModel().select(currentlySelectedValue);
else
menu.setValue(obsList.get(0));
else {
if (obsList.contains(selection))
menu.getSelectionModel().select(selection);
else
menu.setValue(obsList.get(0));
}
}
/**
* Select encoding and adds it into the drop-down if it's not in the list
* Updates stored lists/selection of encoding
* */
public void selectEncodingValue(String encodingValue, AppPreferences preferences){
if (encodingValue != null && !encodingValue.isEmpty()) {
if (!subEncodingList.contains(encodingValue)) {
subEncodingList.add(encodingValue);
preferences.setSubsEncodingList(Arrays.copyOf(subEncodingList.toArray(), subEncodingList.toArray().length, String[].class));
}
if (!subtEncoding.getValue().equals(encodingValue)) {
subtEncoding.getSelectionModel().select(encodingValue);
preferences.setLastTimeUsedSubsEncoding(encodingValue);
}
}
}
}

View File

@ -22,7 +22,7 @@
</graphic>
</Button>
<ChoiceBox fx:id="subtExt" prefWidth="60.0" />
<ChoiceBox fx:id="subtCodepage" prefWidth="100.0" />
<ChoiceBox fx:id="subtEncoding" prefWidth="100.0" />
<Pane HBox.hgrow="ALWAYS" />
<Button mnemonicParsing="false" onAction="#Up">
<graphic>

View File

@ -3,6 +3,11 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckMenuItem?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.control.SplitMenuButton?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.Tab?>
@ -18,6 +23,42 @@
<children>
<VBox prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="%menu_File">
<items>
<MenuItem mnemonicParsing="false" onAction="#openBtn" text="%menu_File_Open" />
<Menu fx:id="recentlyOpenedMenu" mnemonicParsing="false" text="%menu_File_Recent">
<items>
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#cleanAllRecentlyOpened" text="%menu_File_Recent_CleanAll" />
</items>
</Menu>
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#saveBtn" text="%menu_File_Save" />
<MenuItem mnemonicParsing="false" onAction="#saveAsBtn" text="%menu_File_SaveAs" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" onAction="#closeBtn" text="%menu_File_Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="%menu_Tools">
<items>
<MenuItem mnemonicParsing="false" onAction="#settingsBtn" text="%menu_Tools_Settings">
<graphic>
<SVGPath content="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" fill="#686868" />
</graphic></MenuItem>
</items>
</Menu>
<Menu mnemonicParsing="false" text="%menu_Help">
<items>
<MenuItem mnemonicParsing="false" onAction="#infoBtn" text="%menu_Help_AboutApp">
<graphic>
<SVGPath content="M13.5,4A1.5,1.5 0 0,0 12,5.5A1.5,1.5 0 0,0 13.5,7A1.5,1.5 0 0,0 15,5.5A1.5,1.5 0 0,0 13.5,4M13.14,8.77C11.95,8.87 8.7,11.46 8.7,11.46C8.5,11.61 8.56,11.6 8.72,11.88C8.88,12.15 8.86,12.17 9.05,12.04C9.25,11.91 9.58,11.7 10.13,11.36C12.25,10 10.47,13.14 9.56,18.43C9.2,21.05 11.56,19.7 12.17,19.3C12.77,18.91 14.38,17.8 14.54,17.69C14.76,17.54 14.6,17.42 14.43,17.17C14.31,17 14.19,17.12 14.19,17.12C13.54,17.55 12.35,18.45 12.19,17.88C12,17.31 13.22,13.4 13.89,10.71C14,10.07 14.3,8.67 13.14,8.77Z" fill="#686868f7" />
</graphic></MenuItem>
</items>
</Menu>
</menus>
</MenuBar>
<ToolBar prefHeight="40.0" prefWidth="200.0" styleClass="topToolBar" stylesheets="@res/landing.css">
<items>
<HBox>
@ -103,21 +144,11 @@
</TabPane>
</items>
</SplitPane>
<HBox VBox.vgrow="NEVER">
<children>
<Pane HBox.hgrow="ALWAYS" />
<Button mnemonicParsing="false" onAction="#settingsBtn" styleClass="transparentBtn" stylesheets="@res/landing.css">
<graphic>
<SVGPath content="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" fill="#686868" />
</graphic>
</Button>
<Button mnemonicParsing="false" onAction="#infoBnt" styleClass="transparentBtn" stylesheets="@res/landing.css">
<graphic>
<SVGPath content="M13.5,4A1.5,1.5 0 0,0 12,5.5A1.5,1.5 0 0,0 13.5,7A1.5,1.5 0 0,0 15,5.5A1.5,1.5 0 0,0 13.5,4M13.14,8.77C11.95,8.87 8.7,11.46 8.7,11.46C8.5,11.61 8.56,11.6 8.72,11.88C8.88,12.15 8.86,12.17 9.05,12.04C9.25,11.91 9.58,11.7 10.13,11.36C12.25,10 10.47,13.14 9.56,18.43C9.2,21.05 11.56,19.7 12.17,19.3C12.77,18.91 14.38,17.8 14.54,17.69C14.76,17.54 14.6,17.42 14.43,17.17C14.31,17 14.19,17.12 14.19,17.12C13.54,17.55 12.35,18.45 12.19,17.88C12,17.31 13.22,13.4 13.89,10.71C14,10.07 14.3,8.67 13.14,8.77Z" fill="#686868f7" />
</graphic>
</Button>
</children>
</HBox>
<Pane VBox.vgrow="NEVER">
<children>
<Label fx:id="statusLbl" />
</children>
</Pane>
</children>
</VBox>
</children>

BIN
lib/gson-2.8.5.jar Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
about_line1=mplayer4amine distributes under GNU GPLv3 license.
about_line2=Release: v0.9
about_line2=Release: v0.10
about_line3=Development & maintenance by Dmitry Isaenko.
about_AboutName=About
main_tab_audio=Audio
@ -14,7 +14,7 @@ SaveBtn=Save
settings_SettingsName=Settings
main_tab_subtitles=Subtitles
settings_SubtitlesTabFirst=Show 'Subutitles' tab first after application starts:
unableToStartMplayerError=Unable to execute 'mplayer'.\n\
ErrorUnableToStartMplayer=Unable to execute 'mplayer'.\n\
1. Make sure it's installed.\n\
2. Check application settings.
settings_unixOsInformation=Unix-like OS uses system $PATH to find mplayer location.\n\
@ -25,4 +25,28 @@ settings_subsExtensionList=Avaliable subtitles extensions:
settings_subsCodepageList=Avaliable codepages for subtitles:
settings_fieldContainSpacesTabs=Spaces and tab symbols are not allowed.
subsShow_option=Don't show subtitles.
menu_File=File
menu_Tools=Tools
menu_Help=Help
menu_Help_AboutApp=About
menu_File_Close=Close
menu_Tools_Settings=Settings
menu_File_Open=Open playlist...
menu_File_Save=Save playlist
menu_File_SaveAs=Save playlist as...
SelectFile=Select file
menu_File_Recent=Recently opened...
menu_File_Recent_CleanAll=Clean
ErrorFileNotFound=File not found.
ErrorOnOpenIncorrectFormatOfFile=Unable to open file:\n\
Incorrect playlist format.
ErrorOnOpenIOProblem=Unable to open file:\n\
I/O error.
ErrorOnSaveIOProblem=Unable to save file:\n\
I/O error.
ErrorOnSaveIncorrectEncoding=Unable to save file:\n\
Internal problem: unsupported encoding.
ErrorUnableToSaveEmptyPlaylist=Unable to save playlist with no videos files.
AboutUsedLibraries=Used libraries:

View File

@ -1,5 +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.9
about_line2=\u0420\u0435\u043B\u0438\u0437: v0.10
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
@ -14,7 +15,7 @@ SaveBtn=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
settings_SettingsName=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
main_tab_subtitles=\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044B
settings_SubtitlesTabFirst=\u041F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435 \u0441\u043F\u0435\u0440\u0432\u0430 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0432\u043A\u043B\u0430\u0434\u043A\u0443 "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044B":
unableToStartMplayerError=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C mplayer.\n\
ErrorUnableToStartMplayer=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C mplayer.\n\
1. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044C, \u0447\u0442\u043E \u043E\u043D \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D.\n\
2. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A.
settings_unixOsInformation=Unix-\u043F\u043E\u0434\u043E\u0431\u043D\u044B\u0435 \u041E\u0421 \u0441\u0438\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0443\u0442\u0438, \u0447\u0442\u043E\u0431\u044B \u043D\u0430\u0439\u0442\u0438 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435 mplayer.\n\
@ -25,3 +26,25 @@ settings_subsExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u043
settings_subsCodepageList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0438 \u0434\u043B\u044F \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043E\u0432:
settings_fieldContainSpacesTabs=\u041F\u0440\u043E\u0431\u0435\u043B\u044B \u0438 \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u0442\u0430\u0431\u0443\u043B\u044F\u0446\u0438\u0438 \u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B.
subsShow_option=\u041D\u0435 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B.
menu_File=\u0424\u0430\u0439\u043B
menu_Tools=\u0418\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B
menu_Help=\u0421\u043F\u0440\u0430\u0432\u043A\u0430
menu_Help_AboutApp=\u041E \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438
menu_File_Close=\u0417\u0430\u043A\u0440\u044B\u0442\u044C
menu_Tools_Settings=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
menu_File_Open=\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442...
menu_File_Save=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442
menu_File_SaveAs=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442 \u043A\u0430\u043A...
SelectFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B
menu_File_Recent_CleanAll=\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C
ErrorFileNotFound=\u0424\u0430\u0439\u043B \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.
ErrorOnOpenIncorrectFormatOfFile=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043E\u0442\u043A\u0440\u044B\u0442\u044C \u0444\u0430\u0439\u043B:\n\
\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442\u0430.
ErrorOnOpenIOProblem=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043E\u0442\u043A\u0440\u044B\u0442\u044C \u0444\u0430\u0439\u043B:\n\
\u041E\u0448\u0438\u0431\u043A\u0430 \u0432\u0432\u043E\u0434\u0430/\u0432\u044B\u0432\u043E\u0434\u0430.
ErrorOnSaveIOProblem=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0444\u0430\u0439\u043B:\n\
\u041E\u0448\u0438\u0431\u043A\u0430 \u0432\u0432\u043E\u0434\u0430/\u0432\u044B\u0432\u043E\u0434\u0430.
ErrorOnSaveIncorrectEncoding=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0444\u0430\u0439\u043B:\n\
\u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u043E\u0448\u0438\u0431\u043A\u0430: \u043A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0430 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F.
ErrorUnableToSaveEmptyPlaylist=\u041D\u0435\u043B\u044C\u0437\u044F \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442 \u0431\u0435\u0437 \u0432\u0438\u0434\u0435\u043E \u0444\u0430\u0439\u043B\u043E\u0432.
AboutUsedLibraries=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438:

View File

@ -87,23 +87,4 @@
/* END */
.topToolBar{
-fx-background-color: #4f6f8f;
}
.transparentBtn {
-fx-background-color: none;
}
.transparentBtn:hover {
-fx-background-color: #e5e5e5;
}
.transparentBtn:pressed {
-fx-background-color: #d4d4d4;
}
/*
.tabPane .tab:selected {
-fx-background-color: #f1f1f1;
}
.tabPane .tab-header-background{
-fx-background-color: #b9b9b9;
}
*/
}