Remember last played playlist and positions
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
c01b36b772
commit
f0068ae4c3
15 changed files with 288 additions and 206 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ import java.util.prefs.Preferences;
|
||||||
|
|
||||||
// Rule application settings
|
// Rule application settings
|
||||||
public class AppPreferences {
|
public class AppPreferences {
|
||||||
private static AppPreferences INSTANCE = new AppPreferences();
|
private static final AppPreferences INSTANCE = new AppPreferences();
|
||||||
private Preferences preferences = Preferences.userRoot().node("mplayer4anime");
|
private final Preferences preferences = Preferences.userRoot().node("mplayer4anime");
|
||||||
|
|
||||||
private AppPreferences(){}
|
private AppPreferences(){}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public class AppPreferences {
|
||||||
/** Return recently opened elements */
|
/** Return recently opened elements */
|
||||||
public String[] getRecentPlaylists(){
|
public String[] getRecentPlaylists(){
|
||||||
String[] recentPlaylists = new String[10];
|
String[] recentPlaylists = new String[10];
|
||||||
for (int i=0; i<10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
recentPlaylists[i] = preferences.get("RECENT_PLS_" + i, "");
|
recentPlaylists[i] = preferences.get("RECENT_PLS_" + i, "");
|
||||||
return recentPlaylists;
|
return recentPlaylists;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ public class AppPreferences {
|
||||||
preferences.put("RECENT_PLS_" + i, recentPlaylists[i]);
|
preferences.put("RECENT_PLS_" + i, recentPlaylists[i]);
|
||||||
else
|
else
|
||||||
preferences.put("RECENT_PLS_" + i, "");
|
preferences.put("RECENT_PLS_" + i, "");
|
||||||
for (;i<10;i++) // Not needed. Logic may handle received String to be less or greater then String[10], but it never happened.
|
for (;i < 10; i++) // Not needed. Logic may handle received String to be less or greater then String[10], but it never happened.
|
||||||
preferences.put("RECENT_PLS_" + i, "");
|
preferences.put("RECENT_PLS_" + i, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,4 +125,23 @@ public class AppPreferences {
|
||||||
|
|
||||||
public int getBackendEngineIndexId(){ return preferences.getInt("backend_player", 0); }
|
public int getBackendEngineIndexId(){ return preferences.getInt("backend_player", 0); }
|
||||||
public void setBackendEngineIndexId(int value){ preferences.putInt("backend_player", value); }
|
public void setBackendEngineIndexId(int value){ preferences.putInt("backend_player", value); }
|
||||||
|
|
||||||
|
public String getRecentPlaylist(){
|
||||||
|
return preferences.get("RECENT_PLS_0", "");
|
||||||
|
}
|
||||||
|
public boolean getOpenLatestPlaylistOnStart(){ return preferences.getBoolean("open_latest_playlist", true); }
|
||||||
|
public void setOpenLatestPlaylistOnStart(boolean value){ preferences.putBoolean("open_latest_playlist" , value); }
|
||||||
|
|
||||||
|
public int getLatestPositionVideo(){ return preferences.getInt("latest_video_pos", 1); }
|
||||||
|
public void setLatestPositionVideo(int value){
|
||||||
|
preferences.putInt("latest_video_pos", Math.max(value, 0));
|
||||||
|
}
|
||||||
|
public int getLatestPositionAudio(){ return preferences.getInt("latest_audio_pos", 1); }
|
||||||
|
public void setLatestPositionAudio(int value){
|
||||||
|
preferences.putInt("latest_audio_pos", Math.max(value, 0));
|
||||||
|
}
|
||||||
|
public int getLatestPositionSubs(){ return preferences.getInt("latest_subs_pos", 1); }
|
||||||
|
public void setLatestPositionSubs(int value){
|
||||||
|
preferences.putInt("latest_subs_pos", Math.max(value, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package mplayer4anime;
|
package mplayer4anime;
|
||||||
|
|
||||||
public interface ISlaveModeAppOrchestration {
|
public interface IPlayer {
|
||||||
void subtitlesSwitch();
|
void subtitlesSwitch();
|
||||||
void fullscreenSwitch();
|
void fullscreenSwitch();
|
||||||
void mute();
|
void mute();
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package mplayer4anime.mplayer;
|
package mplayer4anime.mplayer;
|
||||||
|
|
||||||
import mplayer4anime.ISlaveModeAppOrchestration;
|
import mplayer4anime.IPlayer;
|
||||||
import mplayer4anime.ui.ServiceWindow;
|
import mplayer4anime.ui.ServiceWindow;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class MplayerSlave implements ISlaveModeAppOrchestration {
|
public class MplayerSlave implements IPlayer {
|
||||||
private Process player;
|
private Process player;
|
||||||
private PrintStream playerIn;
|
private PrintStream playerIn;
|
||||||
private BufferedReader playerOutErr;
|
private BufferedReader playerOutErr;
|
||||||
|
@ -37,13 +37,13 @@ public class MplayerSlave implements ISlaveModeAppOrchestration {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean playerSingleCommand(String command){
|
private boolean playerSingleCommand(String command){
|
||||||
if (player != null && player.isAlive()) {
|
if (player == null || ! player.isAlive())
|
||||||
playerIn.print(command);
|
return false;
|
||||||
playerIn.print("\n");
|
|
||||||
playerIn.flush();
|
playerIn.print(command);
|
||||||
return true;
|
playerIn.print("\n");
|
||||||
}
|
playerIn.flush();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void subtitlesSwitch(){
|
public void subtitlesSwitch(){
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package mplayer4anime.mpv;
|
package mplayer4anime.mpv;
|
||||||
|
|
||||||
import mplayer4anime.ISlaveModeAppOrchestration;
|
import mplayer4anime.IPlayer;
|
||||||
|
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class MpvSlave implements ISlaveModeAppOrchestration {
|
public class MpvSlave implements IPlayer {
|
||||||
|
|
||||||
public MpvSlave(ResourceBundle resourceBundle){
|
public MpvSlave(ResourceBundle resourceBundle){
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import mplayer4anime.ui.ServiceWindow;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class Playlists {
|
public class Playlists {
|
||||||
|
@ -31,23 +32,22 @@ public class Playlists {
|
||||||
|
|
||||||
//TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
|
//TODO: Show popUp if unable to write! Or nothing to write! Or overwrite!
|
||||||
//TODO: Disable 'Save' button if no files added
|
//TODO: Disable 'Save' button if no files added
|
||||||
public static boolean SaveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
|
public static boolean saveAs(ResourceBundle resourceBundle, JsonStorage jStorage){
|
||||||
File playlistFile;
|
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
|
||||||
fileChooser.setTitle(resourceBundle.getString("SelectFile"));
|
fileChooser.setTitle(resourceBundle.getString("SelectFile"));
|
||||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
fileChooser.setInitialFileName("MyPlaylist.alpr");
|
fileChooser.setInitialFileName("MyPlaylist.alpr");
|
||||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
|
||||||
playlistFile = fileChooser.showSaveDialog(null);
|
File playlistFile = fileChooser.showSaveDialog(null);
|
||||||
|
|
||||||
return writeFile(resourceBundle, playlistFile, jStorage);
|
return writeFile(resourceBundle, playlistFile, jStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean SaveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
|
public static boolean saveCurrent(ResourceBundle resourceBundle, JsonStorage jStorage) {
|
||||||
if (playlistLocation == null || playlistLocation.equals("")){
|
if (playlistLocation == null || playlistLocation.equals(""))
|
||||||
return Playlists.SaveAs(resourceBundle, jStorage);
|
return Playlists.saveAs(resourceBundle, jStorage);
|
||||||
}
|
|
||||||
return writeFile(resourceBundle, new File(playlistLocation), jStorage);
|
return writeFile(resourceBundle, new File(playlistLocation), jStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ public class Playlists {
|
||||||
/**
|
/**
|
||||||
* Interface for Opening playlists via FileChooser
|
* Interface for Opening playlists via FileChooser
|
||||||
**/
|
**/
|
||||||
public static JsonStorage OpenPlaylistFileChooser(ResourceBundle resourceBundle){
|
public static JsonStorage openPlaylistFileChooser(ResourceBundle resourceBundle){
|
||||||
File playlistFile;
|
File playlistFile;
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
|
||||||
|
@ -101,12 +101,12 @@ public class Playlists {
|
||||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Playlists (*.alpr)", "*.alpr"));
|
||||||
playlistFile = fileChooser.showOpenDialog(null);
|
playlistFile = fileChooser.showOpenDialog(null);
|
||||||
|
|
||||||
return ReadByPath(resourceBundle, playlistFile);
|
return readByPath(resourceBundle, playlistFile);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Interface for Opening playlists using file itself
|
* Interface for Opening playlists using file itself
|
||||||
* */
|
* */
|
||||||
public static JsonStorage ReadByPath(ResourceBundle resourceBundle, File playlistFile){
|
public static JsonStorage readByPath(ResourceBundle resourceBundle, File playlistFile){
|
||||||
if (playlistFile == null) {
|
if (playlistFile == null) {
|
||||||
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
ServiceWindow.getErrorNotification(resourceBundle.getString("Error"),
|
||||||
"Playlist file not selected");// TODO: translate
|
"Playlist file not selected");// TODO: translate
|
||||||
|
@ -132,6 +132,17 @@ public class Playlists {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsonStorage readByPathSilent(File playlistFile){
|
||||||
|
try (Reader reader = new InputStreamReader(Files.newInputStream(playlistFile.toPath()))) {
|
||||||
|
JsonStorage jStorage = new Gson().fromJson(reader, JsonStorage.class);
|
||||||
|
if (jStorage != null){
|
||||||
|
playlistLocation = playlistFile.getAbsolutePath();
|
||||||
|
return jStorage;
|
||||||
|
}
|
||||||
|
} catch (Exception ignore){}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return path to file opened */
|
/** Return path to file opened */
|
||||||
public static String getPlaylistLocation(){
|
public static String getPlaylistLocation(){
|
||||||
return playlistLocation;
|
return playlistLocation;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import javafx.scene.control.*;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import mplayer4anime.ui.about.AboutWindow;
|
import mplayer4anime.ui.about.AboutWindow;
|
||||||
import mplayer4anime.AppPreferences;
|
import mplayer4anime.AppPreferences;
|
||||||
import mplayer4anime.ISlaveModeAppOrchestration;
|
import mplayer4anime.IPlayer;
|
||||||
import mplayer4anime.MediatorControl;
|
import mplayer4anime.MediatorControl;
|
||||||
import mplayer4anime.playlists.JsonStorage;
|
import mplayer4anime.playlists.JsonStorage;
|
||||||
import mplayer4anime.playlists.Playlists;
|
import mplayer4anime.playlists.Playlists;
|
||||||
|
@ -45,9 +45,9 @@ import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class LandingController implements Initializable {
|
public class LandingController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
ControllerPane mkvPaneController, mkaPaneController;
|
private ControllerPane mkvPaneController, mkaPaneController;
|
||||||
@FXML
|
@FXML
|
||||||
ControllerPaneSubtitles subPaneController;
|
private ControllerPaneSubtitles subPaneController;
|
||||||
@FXML
|
@FXML
|
||||||
private PlayerToolbarController playerToolbarController;
|
private PlayerToolbarController playerToolbarController;
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -65,16 +65,17 @@ public class LandingController implements Initializable {
|
||||||
private String currentPlaylistLocation;
|
private String currentPlaylistLocation;
|
||||||
private String backend;
|
private String backend;
|
||||||
|
|
||||||
ISlaveModeAppOrchestration player;
|
private IPlayer player;
|
||||||
|
|
||||||
// If application started with playlist passed as an argument, then we'll try to load it (if it's valid).
|
// 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) {
|
public void setPlaylistAsArgument(String playlist) {
|
||||||
JsonStorage jsonStorage = Playlists.ReadByPath(resourceBundle, new File(playlist));
|
JsonStorage jsonStorage = Playlists.readByPath(resourceBundle, new File(playlist));
|
||||||
setAllLists(jsonStorage);
|
setAllLists(jsonStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
this.resourceBundle = resourceBundle;
|
||||||
// Register this controller in mediator
|
// Register this controller in mediator
|
||||||
MediatorControl.getInstance().registerMainController(this);
|
MediatorControl.getInstance().registerMainController(this);
|
||||||
|
|
||||||
|
@ -82,8 +83,6 @@ public class LandingController implements Initializable {
|
||||||
mkaPaneController.setPaneType("Audio");
|
mkaPaneController.setPaneType("Audio");
|
||||||
subPaneController.setPaneType("Subtitles");
|
subPaneController.setPaneType("Subtitles");
|
||||||
|
|
||||||
resourceBundle = rb;
|
|
||||||
|
|
||||||
// Set default list of encodings of the subtitles files:
|
// Set default list of encodings of the subtitles files:
|
||||||
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), appPreferences.getLastTimeUsedSubsEncoding());
|
subPaneController.setEncoding(appPreferences.getSubsEncodingList(), appPreferences.getLastTimeUsedSubsEncoding());
|
||||||
|
|
||||||
|
@ -107,13 +106,27 @@ public class LandingController implements Initializable {
|
||||||
player = new MpvSlave(resourceBundle);
|
player = new MpvSlave(resourceBundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerToolbarController.initializeMainUiController(this);
|
playerToolbarController.initializeMainUiController(player, mkvPaneController, mkaPaneController, subPaneController);
|
||||||
/*
|
|
||||||
Playlists.ReadByPath(resourceBundle, playListFile);
|
if (appPreferences.getOpenLatestPlaylistOnStart())
|
||||||
* */
|
loadLatestPlaylist();
|
||||||
|
}
|
||||||
|
private void loadLatestPlaylist(){
|
||||||
|
try {
|
||||||
|
String recentPlaylist = appPreferences.getRecentPlaylist();
|
||||||
|
if ("".equals(recentPlaylist))
|
||||||
|
return;
|
||||||
|
// TODO: IF video set, if playlist has been opened before
|
||||||
|
JsonStorage jsonStorage = Playlists.readByPathSilent(new File(recentPlaylist));
|
||||||
|
setAllLists(jsonStorage);
|
||||||
|
mkvPaneController.setElementSelectedByIndex(appPreferences.getLatestPositionVideo());
|
||||||
|
mkaPaneController.setElementSelectedByIndex(appPreferences.getLatestPositionAudio());
|
||||||
|
subPaneController.setElementSelectedByIndex(appPreferences.getLatestPositionSubs());
|
||||||
|
}
|
||||||
|
catch (Exception ignore){}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHostServices(HostServices hostServices) {
|
public void setHostServices(HostServices hostServices){
|
||||||
this.hostServices = hostServices;
|
this.hostServices = hostServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,16 +143,21 @@ public class LandingController implements Initializable {
|
||||||
playerToolbarController.shutdown();
|
playerToolbarController.shutdown();
|
||||||
// TODO: remove from here; too sophisticated
|
// TODO: remove from here; too sophisticated
|
||||||
String[] storeRecentArr = new String[10];
|
String[] storeRecentArr = new String[10];
|
||||||
for (int i =0; i < recentlyOpenedMenu.getItems().size() - 2 && !(i > 9); i++) { // Don't take separator and Clean button
|
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();
|
storeRecentArr[i] = (String) recentlyOpenedMenu.getItems().get(i).getUserData();
|
||||||
}
|
}
|
||||||
appPreferences.setRecentPlaylists(storeRecentArr);
|
appPreferences.setRecentPlaylists(storeRecentArr);
|
||||||
|
|
||||||
|
appPreferences.setLatestPositionVideo(mkvPaneController.getElementSelectedIndex());
|
||||||
|
appPreferences.setLatestPositionAudio(mkaPaneController.getElementSelectedIndex());
|
||||||
|
appPreferences.setLatestPositionSubs(subPaneController.getElementSelectedIndex());
|
||||||
|
|
||||||
Platform.exit();
|
Platform.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void infoBtn(){
|
private void infoBtn(){
|
||||||
new AboutWindow(this.hostServices);
|
new AboutWindow(hostServices);
|
||||||
} // TODO: fix this shit with hostSerivces that doesn't work @ linux
|
} // TODO: fix this shit with hostSerivces that doesn't work @ linux
|
||||||
|
|
||||||
/** SETTINGS HANDLE */
|
/** SETTINGS HANDLE */
|
||||||
|
@ -170,7 +188,7 @@ public class LandingController implements Initializable {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void openBtn() {
|
private void openBtn() {
|
||||||
JsonStorage jsonStorage = Playlists.OpenPlaylistFileChooser(resourceBundle);
|
JsonStorage jsonStorage = Playlists.openPlaylistFileChooser(resourceBundle);
|
||||||
setAllLists(jsonStorage);
|
setAllLists(jsonStorage);
|
||||||
}
|
}
|
||||||
private void setAllLists(JsonStorage jsonStorage){
|
private void setAllLists(JsonStorage jsonStorage){
|
||||||
|
@ -197,7 +215,7 @@ public class LandingController implements Initializable {
|
||||||
mkaPaneController.getElementsAll(),
|
mkaPaneController.getElementsAll(),
|
||||||
subPaneController.getElementsAll(),
|
subPaneController.getElementsAll(),
|
||||||
subPaneController.getSelectedEncoding());
|
subPaneController.getSelectedEncoding());
|
||||||
if (Playlists.SaveCurrent(resourceBundle, jsonStorage)) {
|
if (Playlists.saveCurrent(resourceBundle, jsonStorage)) {
|
||||||
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
||||||
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
||||||
addRecentlyOpened(currentPlaylistLocation);
|
addRecentlyOpened(currentPlaylistLocation);
|
||||||
|
@ -216,7 +234,7 @@ public class LandingController implements Initializable {
|
||||||
mkaPaneController.getElementsAll(),
|
mkaPaneController.getElementsAll(),
|
||||||
subPaneController.getElementsAll(),
|
subPaneController.getElementsAll(),
|
||||||
subPaneController.getSelectedEncoding());
|
subPaneController.getSelectedEncoding());
|
||||||
if (Playlists.SaveAs(resourceBundle, jsonStorage)) {
|
if (Playlists.saveAs(resourceBundle, jsonStorage)) {
|
||||||
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
this.currentPlaylistLocation = Playlists.getPlaylistLocation();
|
||||||
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
this.statusLbl.setText(currentPlaylistLocation); //TODO: update header of the application to include this?
|
||||||
addRecentlyOpened(currentPlaylistLocation);
|
addRecentlyOpened(currentPlaylistLocation);
|
||||||
|
@ -246,7 +264,7 @@ public class LandingController implements Initializable {
|
||||||
|
|
||||||
menuItem.setUserData(playlistPath);
|
menuItem.setUserData(playlistPath);
|
||||||
menuItem.setOnAction(actionEvent -> {
|
menuItem.setOnAction(actionEvent -> {
|
||||||
JsonStorage jsonStorage = Playlists.ReadByPath(resourceBundle, new File(playlistPath));
|
JsonStorage jsonStorage = Playlists.readByPath(resourceBundle, new File(playlistPath));
|
||||||
setAllLists(jsonStorage);
|
setAllLists(jsonStorage);
|
||||||
});
|
});
|
||||||
// Limit list to 13 elements (2 in the end are separator and clear button)
|
// Limit list to 13 elements (2 in the end are separator and clear button)
|
||||||
|
|
|
@ -1,27 +1,34 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mcontroller.player.anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
mcontroller.player.anime is free software: you can redistribute it and/or modify
|
mplayer4anime is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
mcontroller.player.anime is distributed in the hope that it will be useful,
|
mplayer4anime is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with mcontroller.player.anime. If not, see <https://www.gnu.org/licenses/>.
|
along with mplayer4anime. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package mplayer4anime.ui.landing;
|
package mplayer4anime.ui.landing;
|
||||||
|
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ButtonBase;
|
||||||
import javafx.scene.control.CheckMenuItem;
|
import javafx.scene.control.CheckMenuItem;
|
||||||
|
import javafx.scene.control.SplitMenuButton;
|
||||||
import mplayer4anime.AppPreferences;
|
import mplayer4anime.AppPreferences;
|
||||||
|
import mplayer4anime.IPlayer;
|
||||||
|
import mplayer4anime.ui.landing.panes.ControllerPane;
|
||||||
|
import mplayer4anime.ui.landing.panes.ControllerPaneSubtitles;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
@ -31,9 +38,15 @@ public class PlayerToolbarController implements Initializable {
|
||||||
private CheckMenuItem fullScreen;
|
private CheckMenuItem fullScreen;
|
||||||
@FXML
|
@FXML
|
||||||
private CheckMenuItem subsHide;
|
private CheckMenuItem subsHide;
|
||||||
|
@FXML
|
||||||
|
private Button muteBtn, playPrevTrackBtn, playNextTrackBtn, playBtn, stopBtn, volumeUpBtn, volumeDownBtn;
|
||||||
|
@FXML
|
||||||
|
private SplitMenuButton subsTriggerBtn, fullscreenBtn;
|
||||||
|
|
||||||
private AppPreferences appPreferences;
|
private AppPreferences appPreferences;
|
||||||
private LandingController landingController;
|
private IPlayer player;
|
||||||
|
private ControllerPane mkvPaneController, mkaPaneController;
|
||||||
|
private ControllerPaneSubtitles subPaneController;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
@ -41,89 +54,111 @@ public class PlayerToolbarController implements Initializable {
|
||||||
|
|
||||||
fullScreen.setSelected(appPreferences.getFullScreenSelected());
|
fullScreen.setSelected(appPreferences.getFullScreenSelected());
|
||||||
subsHide.setSelected(appPreferences.getSubtitlesHideSelected());
|
subsHide.setSelected(appPreferences.getSubtitlesHideSelected());
|
||||||
|
|
||||||
|
stopBtn.setOnAction(event -> player.stop());
|
||||||
|
volumeUpBtn.setOnAction(event -> player.volumeUp());
|
||||||
|
volumeDownBtn.setOnAction(event -> player.volumeDown());
|
||||||
|
muteBtn.setOnAction(event -> player.mute());
|
||||||
|
playBtn.setOnAction(event -> play());
|
||||||
|
playPrevTrackBtn.setOnAction(event -> playPrevTrack());
|
||||||
|
playNextTrackBtn.setOnAction(event -> playNextTrack());
|
||||||
|
subsTriggerBtn.setOnAction(event -> player.subtitlesSwitch());
|
||||||
|
fullscreenBtn.setOnAction(event -> player.fullscreenSwitch());
|
||||||
}
|
}
|
||||||
public void initializeMainUiController(LandingController landingController){
|
public void initializeMainUiController(IPlayer player,
|
||||||
this.landingController = landingController;
|
ControllerPane mkvPaneController,
|
||||||
|
ControllerPane mkaPaneController,
|
||||||
|
ControllerPaneSubtitles subPaneController){
|
||||||
|
this.player = player;
|
||||||
|
this.mkvPaneController = mkvPaneController;
|
||||||
|
this.mkaPaneController = mkaPaneController;
|
||||||
|
this.subPaneController = subPaneController;
|
||||||
|
|
||||||
|
bindButtonToEmptyList(stopBtn);
|
||||||
|
bindButtonToEmptyList(volumeUpBtn);
|
||||||
|
bindButtonToEmptyList(volumeDownBtn);
|
||||||
|
bindButtonToEmptyList(muteBtn);
|
||||||
|
bindButtonToEmptyList(playBtn);
|
||||||
|
bindButtonToEmptyList(subsTriggerBtn);
|
||||||
|
bindButtonToEmptyList(fullscreenBtn);
|
||||||
|
|
||||||
|
playPrevTrackBtn.disableProperty().bind(
|
||||||
|
Bindings.isEmpty(mkvPaneController.getPaneFileList()).or(
|
||||||
|
Bindings.equal(mkvPaneController.getSelectedIndexProperty(), 0)
|
||||||
|
));
|
||||||
|
|
||||||
|
playNextTrackBtn.disableProperty().bind(
|
||||||
|
Bindings.isEmpty(mkvPaneController.getPaneFileList()).or(
|
||||||
|
Bindings.equal(mkvPaneController.getSelectedIndexProperty(),
|
||||||
|
Bindings.subtract(Bindings.size(mkvPaneController.getPaneFileList()), 1))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
private void bindButtonToEmptyList(ButtonBase button){
|
||||||
|
button.disableProperty().bind(Bindings.isEmpty(mkvPaneController.getPaneFileList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
private void play(){
|
||||||
private void subsTriggerBtn(){
|
if (mkvPaneController.getElementSelected() == null)
|
||||||
landingController.player.subtitlesSwitch();
|
|
||||||
}
|
|
||||||
@FXML
|
|
||||||
private void fullscreenBtn(){
|
|
||||||
landingController.player.fullscreenSwitch();
|
|
||||||
}
|
|
||||||
@FXML
|
|
||||||
private void muteBtn(){
|
|
||||||
landingController.player.mute();
|
|
||||||
}
|
|
||||||
@FXML
|
|
||||||
private void playPrevTrackBtn(){
|
|
||||||
int index = landingController.mkvPaneController.getElementSelectedIndex();
|
|
||||||
if (index <= 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
landingController.mkvPaneController.setElementSelectedByIndex(index-1);
|
player.playPause(appPreferences.getPath(),
|
||||||
landingController.player.forcePlay(appPreferences.getPath(),
|
mkvPaneController.getElementSelected(),
|
||||||
landingController.mkvPaneController.getElementSelected(),
|
mkaPaneController.getElementSelected(),
|
||||||
landingController.mkaPaneController.getElementSelected(),
|
subPaneController.getElementSelected(),
|
||||||
landingController.subPaneController.getElementSelected(),
|
subPaneController.getSelectedEncoding(),
|
||||||
landingController.subPaneController.getSelectedEncoding(),
|
|
||||||
subsHide.isSelected(),
|
subsHide.isSelected(),
|
||||||
fullScreen.isSelected()
|
fullScreen.isSelected()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@FXML
|
|
||||||
private void playNextTrackBtn(){
|
|
||||||
int index = landingController.mkvPaneController.getElementSelectedIndex();
|
|
||||||
|
|
||||||
if (index + 1 < landingController.mkvPaneController.getElementsCount()) {
|
private void playPrevTrack(){
|
||||||
landingController.mkvPaneController.setElementSelectedByIndex(index + 1);
|
int index = mkvPaneController.getElementSelectedIndex() - 1;
|
||||||
}
|
if (index < 0)
|
||||||
index = landingController.mkaPaneController.getElementSelectedIndex();
|
|
||||||
if (index + 1 < landingController.mkaPaneController.getElementsCount()) {
|
|
||||||
landingController.mkaPaneController.setElementSelectedByIndex(index + 1);
|
|
||||||
}
|
|
||||||
index = landingController.subPaneController.getElementSelectedIndex();
|
|
||||||
if (index + 1 < landingController.subPaneController.getElementsCount()) {
|
|
||||||
landingController.subPaneController.setElementSelectedByIndex(index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
landingController.player.forcePlay(appPreferences.getPath(),
|
|
||||||
landingController.mkvPaneController.getElementSelected(),
|
|
||||||
landingController.mkaPaneController.getElementSelected(),
|
|
||||||
landingController.subPaneController.getElementSelected(),
|
|
||||||
landingController.subPaneController.getSelectedEncoding(),
|
|
||||||
subsHide.isSelected(),
|
|
||||||
fullScreen.isSelected()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@FXML
|
|
||||||
private void playBtn(){
|
|
||||||
if (landingController.mkvPaneController.getElementSelected() == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
landingController.player.playPause(appPreferences.getPath(),
|
mkvPaneController.setElementSelectedByIndex(index);
|
||||||
landingController.mkvPaneController.getElementSelected(),
|
|
||||||
landingController.mkaPaneController.getElementSelected(),
|
index = mkaPaneController.getElementSelectedIndex();
|
||||||
landingController.subPaneController.getElementSelected(),
|
if (index > 0)
|
||||||
landingController.subPaneController.getSelectedEncoding(),
|
mkaPaneController.setElementSelectedByIndex(index - 1);
|
||||||
|
|
||||||
|
index = subPaneController.getElementSelectedIndex();
|
||||||
|
if (index > 0)
|
||||||
|
subPaneController.setElementSelectedByIndex(index - 1);
|
||||||
|
|
||||||
|
player.forcePlay(appPreferences.getPath(),
|
||||||
|
mkvPaneController.getElementSelected(),
|
||||||
|
mkaPaneController.getElementSelected(),
|
||||||
|
subPaneController.getElementSelected(),
|
||||||
|
subPaneController.getSelectedEncoding(),
|
||||||
subsHide.isSelected(),
|
subsHide.isSelected(),
|
||||||
fullScreen.isSelected()
|
fullScreen.isSelected()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@FXML
|
|
||||||
private void stopBtn(){
|
private void playNextTrack(){
|
||||||
landingController.player.stop();
|
int index = mkvPaneController.getElementSelectedIndex() + 1;
|
||||||
}
|
if (index >= mkvPaneController.getElementsCount())
|
||||||
@FXML
|
return;
|
||||||
private void volumeUpBtn(){
|
|
||||||
landingController.player.volumeUp();
|
mkvPaneController.setElementSelectedByIndex(index);
|
||||||
}
|
|
||||||
@FXML
|
index = mkaPaneController.getElementSelectedIndex() + 1;
|
||||||
private void volumeDownBtn(){
|
if (index < mkaPaneController.getElementsCount())
|
||||||
landingController.player.volumeDown();
|
mkaPaneController.setElementSelectedByIndex(index);
|
||||||
|
|
||||||
|
index = subPaneController.getElementSelectedIndex() + 1;
|
||||||
|
if (index < subPaneController.getElementsCount())
|
||||||
|
subPaneController.setElementSelectedByIndex(index);
|
||||||
|
|
||||||
|
player.forcePlay(appPreferences.getPath(),
|
||||||
|
mkvPaneController.getElementSelected(),
|
||||||
|
mkaPaneController.getElementSelected(),
|
||||||
|
subPaneController.getElementSelected(),
|
||||||
|
subPaneController.getSelectedEncoding(),
|
||||||
|
subsHide.isSelected(),
|
||||||
|
fullScreen.isSelected()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown(){
|
void shutdown(){
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package mplayer4anime.ui.landing.panes;
|
package mplayer4anime.ui.landing.panes;
|
||||||
|
|
||||||
|
import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
@ -50,7 +51,6 @@ public class ControllerPane implements Initializable {
|
||||||
private Label paneLbl;
|
private Label paneLbl;
|
||||||
private String paneType;
|
private String paneType;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle resBundle) {
|
public void initialize(URL url, ResourceBundle resBundle) {
|
||||||
SetCellFactory(paneListView);
|
SetCellFactory(paneListView);
|
||||||
|
@ -58,10 +58,14 @@ public class ControllerPane implements Initializable {
|
||||||
appPreferences = AppPreferences.getINSTANCE();
|
appPreferences = AppPreferences.getINSTANCE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableList<File> getPaneFileList() {
|
||||||
|
return paneFileList;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPaneType(String paneType){
|
public void setPaneType(String paneType){
|
||||||
this.paneType = paneType;
|
this.paneType = paneType;
|
||||||
|
|
||||||
switch (paneType) {
|
switch (paneType){
|
||||||
case "Video":
|
case "Video":
|
||||||
paneLbl.setText(resourceBundle.getString("lbl_VideoPane"));
|
paneLbl.setText(resourceBundle.getString("lbl_VideoPane"));
|
||||||
break;
|
break;
|
||||||
|
@ -73,7 +77,6 @@ public class ControllerPane implements Initializable {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
paneLbl.setText(resourceBundle.getString("?"));
|
paneLbl.setText(resourceBundle.getString("?"));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,23 +94,20 @@ public class ControllerPane implements Initializable {
|
||||||
}
|
}
|
||||||
/** Select element in pane using index recieved */
|
/** Select element in pane using index recieved */
|
||||||
public void setElementSelectedByIndex(int index){
|
public void setElementSelectedByIndex(int index){
|
||||||
this.paneListView.getSelectionModel().select(index);
|
paneListView.getSelectionModel().select(index);
|
||||||
}
|
}
|
||||||
/** Get number of elements loaded into the pane */
|
/** Get number of elements loaded into the pane */
|
||||||
public int getElementsCount(){
|
public int getElementsCount(){
|
||||||
return this.paneFileList.size();
|
return paneFileList.size();
|
||||||
}
|
|
||||||
/** Check if there are any elements loaded */
|
|
||||||
public boolean isElementsListEmpty(){
|
|
||||||
return paneFileList.isEmpty();
|
|
||||||
}
|
}
|
||||||
/** Get all elements
|
/** Get all elements
|
||||||
* Used in Json playlist writer only */
|
* Used in Json playlist writer only */
|
||||||
public String[] getElementsAll(){
|
public String[] getElementsAll(){
|
||||||
String[] elementsArray = new String[this.getElementsCount()];
|
String[] elementsArray = new String[this.getElementsCount()];
|
||||||
for (int i = 0; i < elementsArray.length; i++){
|
|
||||||
|
for (int i = 0; i < elementsArray.length; i++)
|
||||||
elementsArray[i] = paneFileList.get(i).toString();
|
elementsArray[i] = paneFileList.get(i).toString();
|
||||||
}
|
|
||||||
return elementsArray;
|
return elementsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,61 +239,63 @@ public class ControllerPane implements Initializable {
|
||||||
* */
|
* */
|
||||||
public void setFilesFromList(String[] fileLocations){
|
public void setFilesFromList(String[] fileLocations){
|
||||||
cleanList();
|
cleanList();
|
||||||
if (fileLocations != null && fileLocations.length != 0) {
|
|
||||||
File[] files = new File[fileLocations.length];
|
if (fileLocations == null || fileLocations.length == 0)
|
||||||
for (int i=0; i < fileLocations.length; i++)
|
return;
|
||||||
files[i] = new File(fileLocations[i]);
|
|
||||||
displayFiles(files);
|
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){
|
private void displayFiles(File[] files){
|
||||||
if (files != null && files.length > 0) {
|
if (files == null || files.length == 0)
|
||||||
// spiced java magic
|
return;
|
||||||
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);
|
|
||||||
|
|
||||||
paneFileList.addAll(files);
|
Arrays.sort(files);
|
||||||
paneListView.setItems(paneFileList);
|
// Remember the folder used for MKV and reuse it when user opens MKA/subs folder (as new default path instead of user.home)
|
||||||
paneListView.getSelectionModel().select(0);
|
folderToOpen = files[0].getParent();
|
||||||
|
|
||||||
} else {
|
paneFileList.addAll(files);
|
||||||
System.out.println("\tNo files in this folder");
|
paneListView.setItems(paneFileList);
|
||||||
}
|
paneListView.getSelectionModel().select(0);
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
public void cleanList(){
|
public void cleanList(){
|
||||||
paneListView.getItems().clear(); // wipe elements from ListView
|
paneListView.getItems().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void Up(){
|
private void up(){
|
||||||
int index;
|
int index = paneListView.getSelectionModel().getSelectedIndex();
|
||||||
index = paneListView.getSelectionModel().getSelectedIndex();
|
if (index > 0){
|
||||||
if (index >0){
|
paneFileList.add(index - 1, paneListView.getSelectionModel().getSelectedItem());
|
||||||
paneFileList.add(index-1, paneListView.getSelectionModel().getSelectedItem());
|
paneFileList.remove(index + 1);
|
||||||
paneFileList.remove(index+1);
|
paneListView.getSelectionModel().select(index - 1);
|
||||||
paneListView.getSelectionModel().select(index-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void Down(){
|
private void down(){
|
||||||
int index;
|
int index = paneListView.getSelectionModel().getSelectedIndex();
|
||||||
index = paneListView.getSelectionModel().getSelectedIndex();
|
if (index + 1 < paneFileList.size() ){
|
||||||
if (index+1 < paneFileList.size() ){
|
paneFileList.add(index + 2, paneListView.getSelectionModel().getSelectedItem());
|
||||||
paneFileList.add(index+2, paneListView.getSelectionModel().getSelectedItem());
|
|
||||||
paneFileList.remove(index);
|
paneFileList.remove(index);
|
||||||
paneListView.getSelectionModel().select(index+1);
|
paneListView.getSelectionModel().select(index + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@FXML
|
@FXML
|
||||||
private void Del(){ paneFileList.remove(paneListView.getSelectionModel().getSelectedItem()); }
|
private void delete(){
|
||||||
|
paneFileList.remove(paneListView.getSelectionModel().getSelectedItem());
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void KeyPressed(KeyEvent event){
|
private void keyPressed(KeyEvent event){
|
||||||
if (event.getCode().toString().equals("DELETE"))
|
if (event.getCode().toString().equals("DELETE"))
|
||||||
Del();
|
delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadOnlyIntegerProperty getSelectedIndexProperty(){
|
||||||
|
return paneListView.getSelectionModel().selectedIndexProperty();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018-2021 Dmitry Isaenko
|
Copyright 2018-2023 Dmitry Isaenko
|
||||||
|
|
||||||
This file is part of mplayer4anime.
|
This file is part of mplayer4anime.
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public class SettingsController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private Label pathToMplayerLbl;
|
private Label pathToMplayerLbl;
|
||||||
@FXML
|
@FXML
|
||||||
private CheckBox subtitlesFirstCheckBox;
|
private CheckBox subtitlesFirstCheckBox, openLatestPlaylistCheckBox;
|
||||||
@FXML
|
@FXML
|
||||||
private ChoiceBox<String> backEndEngineChoiceBox;
|
private ChoiceBox<String> backEndEngineChoiceBox;
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ public class SettingsController implements Initializable {
|
||||||
audioExtensionListController.setList(appPreferences.getAudioExtensionsList(), true);
|
audioExtensionListController.setList(appPreferences.getAudioExtensionsList(), true);
|
||||||
backEndEngineChoiceBox.getItems().addAll("mplayer", "mpv");
|
backEndEngineChoiceBox.getItems().addAll("mplayer", "mpv");
|
||||||
backEndEngineChoiceBox.getSelectionModel().select(appPreferences.getBackendEngineIndexId());
|
backEndEngineChoiceBox.getSelectionModel().select(appPreferences.getBackendEngineIndexId());
|
||||||
|
openLatestPlaylistCheckBox.setSelected(appPreferences.getOpenLatestPlaylistOnStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -67,17 +68,13 @@ public class SettingsController implements Initializable {
|
||||||
fileChooser.setTitle("mplayer");
|
fileChooser.setTitle("mplayer");
|
||||||
|
|
||||||
// In case we use Windows, limit selectable file to .exe
|
// In case we use Windows, limit selectable file to .exe
|
||||||
if (System.getProperty("os.name").contains("Windows")) {
|
if (System.getProperty("os.name").contains("Windows"))
|
||||||
fileChooser.getExtensionFilters().setAll(
|
fileChooser.getExtensionFilters().setAll(new FileChooser.ExtensionFilter("mplayer", "*.exe"));
|
||||||
new FileChooser.ExtensionFilter("mplayer", "*.exe")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
File mplayerExecutableFile = fileChooser.showOpenDialog(null);
|
File mplayerExecutableFile = fileChooser.showOpenDialog(null);
|
||||||
|
|
||||||
if (mplayerExecutableFile != null) {
|
if (mplayerExecutableFile != null)
|
||||||
pathToMplayerLbl.setText(mplayerExecutableFile.toString());
|
pathToMplayerLbl.setText(mplayerExecutableFile.toString());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -108,6 +105,7 @@ public class SettingsController implements Initializable {
|
||||||
appPreferences.setVideoExtensionsList(videoExtensionListController.getList());
|
appPreferences.setVideoExtensionsList(videoExtensionListController.getList());
|
||||||
appPreferences.setAudioExtensionsList(audioExtensionListController.getList());
|
appPreferences.setAudioExtensionsList(audioExtensionListController.getList());
|
||||||
appPreferences.setBackendEngineIndexId(backEndEngineChoiceBox.getSelectionModel().getSelectedIndex());
|
appPreferences.setBackendEngineIndexId(backEndEngineChoiceBox.getSelectionModel().getSelectedIndex());
|
||||||
|
appPreferences.setOpenLatestPlaylistOnStart(openLatestPlaylistCheckBox.isSelected());
|
||||||
|
|
||||||
MediatorControl.getInstance().updateAfterSettingsChanged(); // TODO: implement list to track what should be updated
|
MediatorControl.getInstance().updateAfterSettingsChanged(); // TODO: implement list to track what should be updated
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,26 +10,26 @@
|
||||||
<?import javafx.scene.layout.Pane?>
|
<?import javafx.scene.layout.Pane?>
|
||||||
<?import javafx.scene.shape.SVGPath?>
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
|
|
||||||
<AnchorPane xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.landing.PlayerToolbarController">
|
<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.landing.PlayerToolbarController">
|
||||||
<ToolBar styleClass="topToolBar" stylesheets="@res/landing.css" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<ToolBar styleClass="topToolBar" stylesheets="@res/landing.css" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<items>
|
<items>
|
||||||
<HBox>
|
<HBox>
|
||||||
<children>
|
<children>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#playPrevTrackBtn" styleClass="btnLeft" stylesheets="@res/landing.css">
|
<Button fx:id="playPrevTrackBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnLeft" stylesheets="@res/landing.css">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M 12,12 3.5,6 12,0 Z M 0,0 V 12 H 2 V 0 Z" fill="#e1e1e1" />
|
<SVGPath content="M 12,12 3.5,6 12,0 Z M 0,0 V 12 H 2 V 0 Z" fill="#e1e1e1" />
|
||||||
</graphic></Button>
|
</graphic></Button>
|
||||||
<Button minHeight="28.0" minWidth="53.0" mnemonicParsing="false" onAction="#playBtn" styleClass="btnCenter" stylesheets="@res/landing.css" textAlignment="CENTER">
|
<Button fx:id="playBtn" minHeight="28.0" minWidth="53.0" mnemonicParsing="false" styleClass="btnCenter" stylesheets="@res/landing.css" textAlignment="CENTER">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M3,5V19L11,12M13,19H16V5H13M18,5V19H21V5" fill="#61dd4e" />
|
<SVGPath content="M3,5V19L11,12M13,19H16V5H13M18,5V19H21V5" fill="#61dd4e" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#stopBtn" styleClass="btnCenter" stylesheets="@res/landing.css">
|
<Button fx:id="stopBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnCenter" stylesheets="@res/landing.css">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M18,18H6V6H18V18Z" fill="#e1e1e1" />
|
<SVGPath content="M18,18H6V6H18V18Z" fill="#e1e1e1" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#playNextTrackBtn" styleClass="btnRight" stylesheets="@res/landing.css">
|
<Button fx:id="playNextTrackBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnRight" stylesheets="@res/landing.css">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M0,12 L8.5,6 L0,0 L0,12 L0,12 Z M10,0 L10,12 L12,12 L12,0 L10,0 L10,0 Z" fill="#e1e1e1" />
|
<SVGPath content="M0,12 L8.5,6 L0,0 L0,12 L0,12 Z M10,0 L10,12 L12,12 L12,0 L10,0 L10,0 Z" fill="#e1e1e1" />
|
||||||
</graphic></Button>
|
</graphic></Button>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<Pane minWidth="20.0" />
|
<Pane minWidth="20.0" />
|
||||||
<HBox>
|
<HBox>
|
||||||
<children>
|
<children>
|
||||||
<Button minHeight="28.0" minWidth="36.0" mnemonicParsing="false" onAction="#volumeDownBtn" styleClass="btnLeft" stylesheets="@res/landing.css">
|
<Button fx:id="volumeDownBtn" minHeight="28.0" minWidth="36.0" mnemonicParsing="false" styleClass="btnLeft" stylesheets="@res/landing.css">
|
||||||
<opaqueInsets>
|
<opaqueInsets>
|
||||||
<Insets />
|
<Insets />
|
||||||
</opaqueInsets>
|
</opaqueInsets>
|
||||||
|
@ -49,20 +49,20 @@
|
||||||
<SVGPath content="M13.5,8 C13.5,6.2 12.5,4.7 11,4 L11,12 C12.5,11.3 13.5,9.8 13.5,8 L13.5,8 Z M0,5 L0,11 L4,11 L9,16 L9,0 L4,5 L0,5 L0,5 Z" fill="#e1e1e1" />
|
<SVGPath content="M13.5,8 C13.5,6.2 12.5,4.7 11,4 L11,12 C12.5,11.3 13.5,9.8 13.5,8 L13.5,8 Z M0,5 L0,11 L4,11 L9,16 L9,0 L4,5 L0,5 L0,5 Z" fill="#e1e1e1" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" minWidth="36.0" mnemonicParsing="false" onAction="#volumeUpBtn" styleClass="btnRight" stylesheets="@res/landing.css">
|
<Button fx:id="volumeUpBtn" minHeight="28.0" minWidth="36.0" mnemonicParsing="false" styleClass="btnRight" stylesheets="@res/landing.css">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M0,6 L0,12 L4,12 L9,17 L9,1 L4,6 L0,6 L0,6 Z M13.5,9 C13.5,7.2 12.5,5.7 11,5 L11,13 C12.5,12.3 13.5,10.8 13.5,9 L13.5,9 Z M11,0.2 L11,2.3 C13.9,3.2 16,5.8 16,9 C16,12.2 13.9,14.8 11,15.7 L11,17.8 C15,16.9 18,13.3 18,9 C18,4.7 15,1.1 11,0.2 L11,0.2 Z" fill="#e1e1e1" />
|
<SVGPath content="M0,6 L0,12 L4,12 L9,17 L9,1 L4,6 L0,6 L0,6 Z M13.5,9 C13.5,7.2 12.5,5.7 11,5 L11,13 C12.5,12.3 13.5,10.8 13.5,9 L13.5,9 Z M11,0.2 L11,2.3 C13.9,3.2 16,5.8 16,9 C16,12.2 13.9,14.8 11,15.7 L11,17.8 C15,16.9 18,13.3 18,9 C18,4.7 15,1.1 11,0.2 L11,0.2 Z" fill="#e1e1e1" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
</children>
|
</children>
|
||||||
</HBox>
|
</HBox>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#muteBtn" styleClass="btnSimple" stylesheets="@res/landing.css">
|
<Button fx:id="muteBtn" minHeight="28.0" mnemonicParsing="false" styleClass="btnSimple" stylesheets="@res/landing.css">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M3,9H7L12,4V20L7,15H3V9M16.59,12L14,9.41L15.41,8L18,10.59L20.59,8L22,9.41L19.41,12L22,14.59L20.59,16L18,13.41L15.41,16L14,14.59L16.59,12Z" fill="#e1e1e1" />
|
<SVGPath content="M3,9H7L12,4V20L7,15H3V9M16.59,12L14,9.41L15.41,8L18,10.59L20.59,8L22,9.41L19.41,12L22,14.59L20.59,16L18,13.41L15.41,16L14,14.59L16.59,12Z" fill="#e1e1e1" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
<SplitMenuButton mnemonicParsing="false" onAction="#subsTriggerBtn" styleClass="splitMenuButton" stylesheets="@res/landing.css">
|
<SplitMenuButton fx:id="subsTriggerBtn" mnemonicParsing="false" styleClass="splitMenuButton" stylesheets="@res/landing.css">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M 4,18 C 2.8954305,18 2,17.104569 2,16 V 4 C 2,2.89 2.9,2 4,2 h 16 c 1.104569,0 2,0.8954305 2,2 v 12 c 0,1.104569 -0.895431,2 -2,2 m -6,-7 v 1 h 5 V 11 M 5,12 h 8 V 11 H 5 m 0,3 v 1 h 14 v -1 z" fill="#e1e1e1" />
|
<SVGPath content="M 4,18 C 2.8954305,18 2,17.104569 2,16 V 4 C 2,2.89 2.9,2 4,2 h 16 c 1.104569,0 2,0.8954305 2,2 v 12 c 0,1.104569 -0.895431,2 -2,2 m -6,-7 v 1 h 5 V 11 M 5,12 h 8 V 11 H 5 m 0,3 v 1 h 14 v -1 z" fill="#e1e1e1" />
|
||||||
</graphic>
|
</graphic>
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
<CheckMenuItem fx:id="subsHide" mnemonicParsing="false" text="%subsShow_option" />
|
<CheckMenuItem fx:id="subsHide" mnemonicParsing="false" text="%subsShow_option" />
|
||||||
</items>
|
</items>
|
||||||
</SplitMenuButton>
|
</SplitMenuButton>
|
||||||
<SplitMenuButton mnemonicParsing="false" onAction="#fullscreenBtn" styleClass="splitMenuButton" stylesheets="@res/landing.css">
|
<SplitMenuButton fx:id="fullscreenBtn" mnemonicParsing="false" styleClass="splitMenuButton" stylesheets="@res/landing.css">
|
||||||
<items>
|
<items>
|
||||||
<CheckMenuItem fx:id="fullScreen" mnemonicParsing="false" text="%fullscreen_option" />
|
<CheckMenuItem fx:id="fullScreen" mnemonicParsing="false" text="%fullscreen_option" />
|
||||||
</items>
|
</items>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<?import javafx.scene.shape.SVGPath?>
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<VBox xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.settings.SettingsController">
|
<VBox xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mplayer4anime.ui.settings.SettingsController">
|
||||||
<children>
|
<children>
|
||||||
<TabPane side="LEFT" styleClass="tab-paneSettings" stylesheets="@../res/landing.css" tabClosingPolicy="UNAVAILABLE" tabMaxHeight="100.0" tabMaxWidth="500.0" tabMinHeight="100.0" tabMinWidth="80.0" VBox.vgrow="ALWAYS">
|
<TabPane side="LEFT" styleClass="tab-paneSettings" stylesheets="@../res/landing.css" tabClosingPolicy="UNAVAILABLE" tabMaxHeight="100.0" tabMaxWidth="500.0" tabMinHeight="100.0" tabMinWidth="80.0" VBox.vgrow="ALWAYS">
|
||||||
<tabs>
|
<tabs>
|
||||||
|
@ -49,11 +49,8 @@
|
||||||
<ChoiceBox fx:id="backEndEngineChoiceBox" prefWidth="150.0" />
|
<ChoiceBox fx:id="backEndEngineChoiceBox" prefWidth="150.0" />
|
||||||
</children>
|
</children>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox alignment="CENTER_LEFT" VBox.vgrow="NEVER">
|
<CheckBox fx:id="subtitlesFirstCheckBox" mnemonicParsing="false" text="%settings_SubtitlesTabFirst" />
|
||||||
<children>
|
<CheckBox fx:id="openLatestPlaylistCheckBox" mnemonicParsing="false" text="%settings_OpenLatestOnStart" />
|
||||||
<CheckBox fx:id="subtitlesFirstCheckBox" mnemonicParsing="false" text="%settings_SubtitlesTabFirst" />
|
|
||||||
</children>
|
|
||||||
</HBox>
|
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||||
|
|
|
@ -34,17 +34,17 @@
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
<Label fx:id="paneLbl" text="%lbl_VideoPane" />
|
<Label fx:id="paneLbl" text="%lbl_VideoPane" />
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#Up">
|
<Button minHeight="28.0" mnemonicParsing="false" onAction="#up">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
|
<SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#Down">
|
<Button minHeight="28.0" mnemonicParsing="false" onAction="#down">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
|
<SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#Del">
|
<Button minHeight="28.0" mnemonicParsing="false" onAction="#delete">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#cc0101" />
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#cc0101" />
|
||||||
</graphic>
|
</graphic>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
<ListView fx:id="paneListView" onKeyPressed="#KeyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
|
<ListView fx:id="paneListView" onKeyPressed="#keyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
|
|
|
@ -37,17 +37,17 @@
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
<Label fx:id="paneLbl" text="%lbl_SubsPane" />
|
<Label fx:id="paneLbl" text="%lbl_SubsPane" />
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#Up">
|
<Button minHeight="28.0" mnemonicParsing="false" onAction="#up">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
|
<SVGPath content="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z" fill="#1a1a1a" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#Down">
|
<Button minHeight="28.0" mnemonicParsing="false" onAction="#down">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
|
<SVGPath content="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" fill="#1a1a1a" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Button minHeight="28.0" mnemonicParsing="false" onAction="#Del">
|
<Button minHeight="28.0" mnemonicParsing="false" onAction="#delete">
|
||||||
<graphic>
|
<graphic>
|
||||||
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#b90505" />
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#b90505" />
|
||||||
</graphic>
|
</graphic>
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</HBox>
|
</HBox>
|
||||||
<ListView fx:id="paneListView" onKeyPressed="#KeyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
|
<ListView fx:id="paneListView" onKeyPressed="#keyPressed" styleClass="landing" stylesheets="@../res/landing.css" VBox.vgrow="ALWAYS" />
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
|
|
|
@ -54,6 +54,7 @@ settings_videoExtensionList=Avaliable video files extensions:
|
||||||
settings_audioExtensionList=Avaliable audio layer extensions:
|
settings_audioExtensionList=Avaliable audio layer extensions:
|
||||||
ApplyBtn=Apply
|
ApplyBtn=Apply
|
||||||
settings_backendSelect=Backend engine:
|
settings_backendSelect=Backend engine:
|
||||||
|
settings_OpenLatestOnStart=Open latest playlist on start
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,4 +54,5 @@ settings_audioExtensionList=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u04
|
||||||
ApplyBtn=\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C
|
ApplyBtn=\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C
|
||||||
settings_backendSelect=\u0414\u0432\u0438\u0436\u043E\u043A \u0432\u043E\u0441\u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438\u044F:
|
settings_backendSelect=\u0414\u0432\u0438\u0436\u043E\u043A \u0432\u043E\u0441\u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438\u044F:
|
||||||
about_line2=\u0420\u0435\u043B\u0438\u0437: v${project.version}
|
about_line2=\u0420\u0435\u043B\u0438\u0437: v${project.version}
|
||||||
|
settings_OpenLatestOnStart=\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u043F\u043B\u0435\u0439\u043B\u0438\u0441\u0442 \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue