Project-HomeFlix/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java

878 lines
30 KiB
Java
Raw Normal View History

2016-08-14 15:17:14 +02:00
/**
* Project-HomeFlix
2018-04-06 20:33:56 +02:00
*
* Copyright 2016-2019 <@Seil0>
2016-08-14 15:17:14 +02:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
package kellerkinder.HomeFlix.application;
2016-08-14 15:17:14 +02:00
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
2016-08-14 15:17:14 +02:00
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
2016-08-14 15:17:14 +02:00
import java.math.BigInteger;
import java.net.URLConnection;
2016-08-14 15:17:14 +02:00
import java.util.Locale;
import java.util.ResourceBundle;
2018-12-08 23:44:17 +01:00
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.kellerkinder.Alerts.JFXInfoAlert;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
2016-08-14 15:17:14 +02:00
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXColorPicker;
import com.jfoenix.controls.JFXHamburger;
2016-08-14 15:17:14 +02:00
import com.jfoenix.controls.JFXSlider;
import com.jfoenix.controls.JFXTextField;
import com.jfoenix.controls.JFXToggleButton;
import com.jfoenix.transitions.hamburger.HamburgerBackArrowBasicTransition;
2016-08-14 15:17:14 +02:00
2016-10-10 16:55:26 +02:00
import javafx.animation.TranslateTransition;
2016-08-14 15:17:14 +02:00
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
2016-08-14 15:17:14 +02:00
import javafx.fxml.FXML;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContextMenu;
2016-08-14 15:17:14 +02:00
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
2016-09-09 20:41:20 +02:00
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
2016-08-14 15:17:14 +02:00
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.SortType;
2016-08-14 15:17:14 +02:00
import javafx.scene.control.TreeTableView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
2016-08-14 15:17:14 +02:00
import javafx.scene.layout.AnchorPane;
2016-10-09 16:05:44 +02:00
import javafx.scene.layout.HBox;
2016-08-14 15:17:14 +02:00
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextFlow;
2016-08-14 15:17:14 +02:00
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
2016-10-10 16:55:26 +02:00
import javafx.util.Duration;
import kellerkinder.HomeFlix.controller.DBController;
import kellerkinder.HomeFlix.controller.OMDbAPIController;
import kellerkinder.HomeFlix.controller.UpdateController;
import kellerkinder.HomeFlix.controller.XMLController;
import kellerkinder.HomeFlix.datatypes.SourceDataType;
import kellerkinder.HomeFlix.player.Player;
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
2016-08-14 15:17:14 +02:00
public class MainWindowController {
2018-07-24 14:14:34 +02:00
// general/settings fxml elements
@FXML private AnchorPane mainAnchorPane;
@FXML private ScrollPane settingsScrollPane;
2018-07-24 14:14:34 +02:00
@FXML private JFXHamburger menuHam;
@FXML private HBox topHBox;
@FXML private VBox sideMenuVBox;
@FXML private TableView<SourceDataType> sourcesTable;
2018-07-24 14:14:34 +02:00
@FXML private JFXButton aboutBtn;
@FXML private JFXButton settingsBtn;
@FXML private JFXButton updateBtn;
@FXML private JFXButton addDirectoryBtn;
@FXML private JFXButton addStreamSourceBtn;
2018-07-24 14:14:34 +02:00
@FXML private JFXToggleButton autoUpdateToggleBtn;
@FXML private JFXToggleButton autoplayToggleBtn;
2018-07-24 14:14:34 +02:00
@FXML private JFXColorPicker colorPicker;
2018-07-24 14:14:34 +02:00
@FXML private ChoiceBox<String> languageChoisBox = new ChoiceBox<>();
@FXML private ChoiceBox<String> branchChoisBox = new ChoiceBox<>();
2018-07-24 14:14:34 +02:00
@FXML private JFXSlider fontsizeSlider;
2018-07-24 14:14:34 +02:00
@FXML private Label homeflixSettingsLbl;
@FXML private Label mainColorLbl;
@FXML private Label fontsizeLbl;
@FXML private Label languageLbl;
@FXML private Label updateLbl;
@FXML private Label branchLbl;
@FXML private Label sourcesLbl;
@FXML private Label versionLbl;
2018-04-13 11:11:25 +02:00
2018-07-24 14:14:34 +02:00
@FXML private TreeItem<SourceDataType> sourceRoot = new TreeItem<>(new SourceDataType("", ""));
@FXML private TableColumn<SourceDataType, String> sourceColumn;
@FXML private TableColumn<SourceDataType, String> modeColumn;
@FXML private TreeTableColumn<FilmTabelDataType, String> columnStreamUrl;
@FXML private TreeTableColumn<FilmTabelDataType, String> columnTitle;
@FXML private TreeTableColumn<FilmTabelDataType, ImageView> columnFavorite;
@FXML private TreeTableColumn<FilmTabelDataType, String> columnSeason;
@FXML private TreeTableColumn<FilmTabelDataType, String> columnEpisode;
2018-07-24 14:14:34 +02:00
// table-mode
@FXML private AnchorPane tableModeAnchorPane;
@FXML private JFXTextField searchTextField;
@FXML private TreeTableView<FilmTabelDataType> filmsTreeTable;
@FXML private TreeItem<FilmTabelDataType> filmRoot = new TreeItem<>(new FilmTabelDataType("", "", "", "", false, false, null));
2018-07-24 14:14:34 +02:00
@FXML private ScrollPane textScrollPane;
@FXML private TextFlow textFlow;
@FXML private ImageView posterImageView;
@FXML private JFXButton playbtn;
@FXML private JFXButton openfolderbtn;
@FXML private JFXButton returnBtn;
@FXML private JFXButton forwardBtn;
2018-07-24 14:14:34 +02:00
// poster-mode
// @FXML private AnchorPane posterModeAnchorPane;
2018-04-28 18:02:02 +02:00
private static DBController dbController; // the player needs the initialized dbController
2018-04-28 18:02:02 +02:00
private UpdateController updateController;
private XMLController xmlController;
private Stage primaryStage;
2018-04-28 18:02:02 +02:00
private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName());
2018-03-01 16:10:37 +01:00
private boolean menuTrue = false;
private boolean settingsTrue = false;
private final String version = "0.7.0";
private final String buildNumber = "169";
private final String versionName = "toothless dragon";
2018-04-28 18:02:02 +02:00
private String btnStyle;
2018-04-28 18:02:02 +02:00
private final int hashA = -647380320;
2016-08-14 15:17:14 +02:00
private int last;
private int indexTable;
private int indexList;
2016-08-14 15:17:14 +02:00
private int next;
2018-04-06 20:33:56 +02:00
private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, false, null);
private ObservableList<String> languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)");
private ObservableList<String> branches = FXCollections.observableArrayList("stable", "beta");
private ObservableList<FilmTabelDataType> filterData = FXCollections.observableArrayList();
private ObservableList<FilmTabelDataType> filmsList = FXCollections.observableArrayList();
private static ObservableList<SourceDataType> sourcesList = FXCollections.observableArrayList();
2018-04-07 17:26:56 +02:00
private MenuItem like = new MenuItem("like");
private MenuItem dislike = new MenuItem("dislike"); // TODO one option (like or dislike)
2017-02-09 20:39:43 +01:00
private ContextMenu menu = new ContextMenu(like, dislike);
2018-05-17 18:58:54 +02:00
public MainWindowController() {
// the constructor
}
@FXML
public void initialize() {
xmlController = new XMLController();
dbController = new DBController(this);
2016-08-14 15:17:14 +02:00
}
2018-10-11 12:29:26 +02:00
public void init() {
2018-04-18 21:04:14 +02:00
LOGGER.info("Initializing Project-HomeFlix build " + buildNumber);
2018-10-11 12:29:26 +02:00
xmlController.loadSettings(); // load settings
checkAutoUpdate();
2018-05-17 18:58:54 +02:00
// initialize the GUI and the DBController
primaryStage = (Stage) mainAnchorPane.getScene().getWindow(); // set primary stage for dialogs
initTabel();
initUI();
2018-04-06 20:33:56 +02:00
initActions();
2018-05-17 18:58:54 +02:00
dbController.init();
// load sources list in gui
addSourceToTable();
2018-12-08 23:44:17 +01:00
// posterModeStartup(); // TODO testing DO NOT USE THIS!!
2018-10-11 12:29:26 +02:00
}
2018-07-22 23:30:52 +02:00
// Initialize general UI elements
2018-04-28 18:02:02 +02:00
private void initUI() {
versionLbl.setText("Version: " + version + " (Build: " + buildNumber + ")");
fontsizeSlider.setValue(XMLController.getFontSize());
colorPicker.setValue(Color.valueOf(XMLController.getColor()));
2018-04-28 18:02:02 +02:00
updateBtn.setFont(Font.font("System", 12));
autoUpdateToggleBtn.setSelected(XMLController.isAutoUpdate());
autoplayToggleBtn.setSelected(XMLController.isAutoplay());
2018-04-28 18:02:02 +02:00
languageChoisBox.setItems(languages);
branchChoisBox.setItems(branches);
if (XMLController.isUseBeta()) {
2018-04-28 18:02:02 +02:00
branchChoisBox.getSelectionModel().select(1);
} else {
branchChoisBox.getSelectionModel().select(0);
}
setLocalUI();
applyColor();
}
2018-07-22 23:30:52 +02:00
/**
* Initialize the tables (treeTableViewfilm and sourcesTable)
* only needed for Tabel-Mode
*/
2018-03-01 16:10:37 +01:00
private void initTabel() {
2016-08-14 15:17:14 +02:00
// film Table
filmsTreeTable.setRoot(filmRoot);
filmsTreeTable.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
filmsTreeTable.setShowRoot(false);
// write content into cell
columnStreamUrl.setCellValueFactory(cellData -> cellData.getValue().getValue().streamUrlProperty());
columnTitle.setCellValueFactory(cellData -> cellData.getValue().getValue().titleProperty());
columnSeason.setCellValueFactory(cellData -> cellData.getValue().getValue().seasonProperty());
columnEpisode.setCellValueFactory(cellData -> cellData.getValue().getValue().episodeProperty());
columnFavorite.setCellValueFactory(cellData -> cellData.getValue().getValue().imageProperty());
// context menu for treeTableViewfilm
filmsTreeTable.setContextMenu(menu);
// sourcesTreeTable
sourceColumn.setCellValueFactory(cellData -> cellData.getValue().pathProperty());
modeColumn.setCellValueFactory(cellData -> cellData.getValue().modeProperty());
sourcesTable.setItems(sourcesList);
2016-09-09 20:41:20 +02:00
}
// Initializing the actions
private void initActions() {
2018-07-22 23:30:52 +02:00
// general actions
HamburgerBackArrowBasicTransition burgerTask = new HamburgerBackArrowBasicTransition(menuHam);
menuHam.addEventHandler(MouseEvent.MOUSE_PRESSED, (e) -> {
2018-05-17 18:58:54 +02:00
if (menuTrue) {
sideMenuSlideOut();
burgerTask.setRate(-1.0);
burgerTask.play();
menuTrue = false;
2018-05-17 18:58:54 +02:00
} else {
sideMenuSlideIn();
burgerTask.setRate(1.0);
burgerTask.play();
menuTrue = true;
}
2018-05-17 18:58:54 +02:00
if (settingsTrue) {
settingsScrollPane.setVisible(false);
settingsTrue = false;
}
});
2016-10-09 18:35:55 +02:00
languageChoisBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number value, Number new_value) {
String local = languageChoisBox.getItems().get((int) new_value).toString();
local = local.substring(local.length() - 6, local.length() - 1); // reading only en_US from English (en_US)
XMLController.setUsrLocal(local);
setLocalUI();
xmlController.saveSettings();
}
});
branchChoisBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number value, Number new_value) {
if (branchChoisBox.getItems().get((int) new_value).toString() == "beta") {
XMLController.setUseBeta(true);
} else {
XMLController.setUseBeta(false);
}
xmlController.saveSettings();
}
});
fontsizeSlider.valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
XMLController.setFontSize(fontsizeSlider.getValue());
2018-04-06 20:33:56 +02:00
if (!getCurrentTitle().isEmpty()) {
dbController.readCache(getCurrentStreamUrl());
}
xmlController.saveSettings();
}
});
2018-07-22 23:30:52 +02:00
// Table-Mode actions
searchTextField.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
ObservableList<FilmTabelDataType> helpData;
filterData.clear();
filmRoot.getChildren().clear();
helpData = filmsList;
for (int i = 0; i < helpData.size(); i++) {
if (helpData.get(i).getTitle().toLowerCase().contains(searchTextField.getText().toLowerCase())) {
filterData.add(helpData.get(i)); // add data from newDaten to filteredData where title contains search input
}
}
for (int i = 0; i < filterData.size(); i++) {
filmRoot.getChildren().add(new TreeItem<FilmTabelDataType>(filterData.get(i))); // add filtered data to root node after search
}
if (searchTextField.getText().hashCode() == hashA) {
XMLController.setColor("000000");
2018-07-22 23:30:52 +02:00
colorPicker.setValue(new Color(0, 0, 0, 1));
applyColor();
}
}
});
like.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
2018-04-06 20:33:56 +02:00
dbController.like(getCurrentStreamUrl());
dbController.refresh(getCurrentStreamUrl(), indexList);
2018-04-28 18:02:02 +02:00
refreshTableElement();
2016-09-09 20:41:20 +02:00
}
});
dislike.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
2018-04-06 20:33:56 +02:00
dbController.dislike(getCurrentStreamUrl());
dbController.refresh(getCurrentStreamUrl(), indexList);
2018-04-28 18:02:02 +02:00
refreshTableElement();
2016-09-09 20:41:20 +02:00
}
});
/**
* FIXME fix bug when sort by ASCENDING, wrong order
*/
columnFavorite.sortTypeProperty().addListener(new ChangeListener<SortType>() {
@Override
public void changed(ObservableValue<? extends SortType> paramObservableValue, SortType paramT1, SortType paramT2) {
2018-04-06 20:33:56 +02:00
filmRoot.getChildren().clear();
filterData.clear();
2018-04-06 20:33:56 +02:00
if (paramT2.equals(SortType.DESCENDING)) {
2018-06-13 13:50:21 +02:00
// add favorites at the top
2018-04-06 20:33:56 +02:00
for (FilmTabelDataType film : filmsList) {
if (film.getFavorite()) {
filterData.add(0, film);
2018-04-06 20:33:56 +02:00
} else {
filterData.add(film);
2018-04-06 20:33:56 +02:00
}
}
} else {
2018-06-13 13:50:21 +02:00
// add favorites at the bottom
2018-04-06 20:33:56 +02:00
for (FilmTabelDataType film : filmsList) {
if (!film.getFavorite()) {
filterData.add(0, film);
2018-04-06 20:33:56 +02:00
} else {
filterData.add(film);
2018-04-06 20:33:56 +02:00
}
}
}
2018-05-09 22:55:32 +02:00
addFilmsToTable(filterData);
}
});
// Change-listener for treeTableViewfilm
filmsTreeTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
@Override
public void changed(ObservableValue<?> observable, Object oldVal, Object newVal) {
if (filmsTreeTable.getSelectionModel().getSelectedItem() == null) {
return;
}
2018-04-06 20:33:56 +02:00
currentTableFilm = filmsTreeTable.getSelectionModel().getSelectedItem().getValue(); // set the current film object
indexTable = filmsTreeTable.getSelectionModel().getSelectedIndex(); // get selected items table index
for (FilmTabelDataType film : filmsList) {
if (film.equals(currentTableFilm)) {
indexList = filmsList.indexOf(film); // get selected items list index
}
}
2018-04-06 20:33:56 +02:00
last = indexTable - 1;
next = indexTable + 1;
if (currentTableFilm.getCached() || dbController.searchCacheByURL(getCurrentStreamUrl())) {
2018-04-06 20:33:56 +02:00
LOGGER.info("loading from cache: " + getCurrentTitle());
dbController.readCache(getCurrentStreamUrl());
} else {
Thread omdbAPIThread = new Thread(new OMDbAPIController(dbController, currentTableFilm, XMLController.getOmdbAPIKey(), true));
omdbAPIThread.setName("OMDbAPI");
omdbAPIThread.start();
}
}
});
2018-07-22 23:30:52 +02:00
// Poster-Mode actions
2016-09-09 20:41:20 +02:00
}
2018-07-22 23:30:52 +02:00
// Table-Mode fxml actions
2018-03-01 16:10:37 +01:00
@FXML
private void playbtnclicked() {
if (currentTableFilm.getStreamUrl().contains("_rootNode")) {
LOGGER.info("rootNode found, getting last watched episode");
currentTableFilm = dbController.getLastWatchedEpisode(currentTableFilm.getTitle());
}
2018-04-06 20:33:56 +02:00
if (isSupportedFormat(currentTableFilm)) {
new Player(getCurrentTableFilm());
} else {
LOGGER.error("using fallback player!");
if (System.getProperty("os.name").contains("Linux")) {
String line;
String output = "";
Process p;
try {
p = Runtime.getRuntime().exec("which vlc");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output = line;
}
LOGGER.info("which vlc: " + output);
input.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (output.contains("which: no vlc") || output == "") {
JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info",
XMLController.getLocalBundle().getString("vlcNotInstalled"),
btnStyle, primaryStage);
vlcInfoAlert.showAndWait();
} else {
try {
2018-04-06 20:33:56 +02:00
new ProcessBuilder("vlc", getCurrentStreamUrl()).start();
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
}
}
} else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) {
2018-03-01 16:10:37 +01:00
try {
2018-04-06 20:33:56 +02:00
Desktop.getDesktop().open(new File(getCurrentStreamUrl()));
} catch (IOException e) {
LOGGER.warn("An error has occurred while opening the file!", e);
2018-03-01 16:10:37 +01:00
}
} else {
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
}
}
}
2018-03-01 16:10:37 +01:00
@FXML
2018-03-04 20:19:46 +01:00
private void openfolderbtnclicked() {
2018-04-06 20:33:56 +02:00
String dest = new File(getCurrentStreamUrl()).getParentFile().getAbsolutePath();
2018-03-04 20:19:46 +01:00
if (!System.getProperty("os.name").contains("Linux")) {
try {
Desktop.getDesktop().open(new File(dest));
} catch (IOException e) {
e.printStackTrace();
}
}
2018-03-01 16:10:37 +01:00
}
@FXML
private void returnBtnclicked(){
filmsTreeTable.getSelectionModel().select(last);
2018-03-01 16:10:37 +01:00
}
@FXML
private void forwardBtnclicked(){
filmsTreeTable.getSelectionModel().select(next);
2018-03-01 16:10:37 +01:00
}
2018-07-22 23:30:52 +02:00
// general fxml actions
2018-03-01 16:10:37 +01:00
@FXML
private void aboutBtnAction() {
2018-10-13 00:32:29 +02:00
String bodyText = "Project HomeFlix \nVersion: " + version + " (Build: " + buildNumber + ") \""
+ versionName + "\" \n" + XMLController.getLocalBundle().getString("infoText");
JFXInfoAlert infoAlert = new JFXInfoAlert("Project HomeFlix", bodyText, btnStyle, primaryStage);
infoAlert.showAndWait();
2018-03-01 16:10:37 +01:00
}
@FXML
2018-05-17 18:58:54 +02:00
private void settingsBtnclicked() {
if (settingsTrue) {
settingsScrollPane.setVisible(false);
2018-03-01 16:10:37 +01:00
settingsTrue = false;
2018-05-17 18:58:54 +02:00
} else {
settingsScrollPane.setVisible(true);
settingsTrue = true;
2018-03-01 16:10:37 +01:00
}
}
@FXML
private void addDirectoryBtnAction(){
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle(XMLController.getLocalBundle().getString("addDirectory"));
File selectedFolder = directoryChooser.showDialog(primaryStage);
if (selectedFolder != null && selectedFolder.exists()) {
addSource(selectedFolder.getPath(), "local");
} else {
LOGGER.error("The selected folder dosen't exist!");
}
2018-03-01 16:10:37 +01:00
}
@FXML
private void addStreamSourceBtnAction(){
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(XMLController.getLocalBundle().getString("addStreamSource"));
File selectedFile = fileChooser.showOpenDialog(primaryStage);
if (selectedFile != null && selectedFile.exists()) {
2018-03-05 12:14:54 +01:00
addSource(selectedFile.getPath(), "stream");
} else {
LOGGER.error("The selected file dosen't exist!");
}
2018-03-01 16:10:37 +01:00
}
@FXML
private void colorPickerAction() {
XMLController.setColor(colorPicker.getValue().toString().substring(2, 10));
xmlController.saveSettings();
2018-03-01 16:10:37 +01:00
applyColor();
}
@FXML
private void updateBtnAction() {
updateController = new UpdateController(this, buildNumber, XMLController.isUseBeta());
2018-03-01 16:10:37 +01:00
Thread updateThread = new Thread(updateController);
updateThread.setName("Updater");
updateThread.start();
}
@FXML
private void autoUpdateToggleBtnAction() {
XMLController.setAutoUpdate(!XMLController.isAutoUpdate());
xmlController.saveSettings();
2018-03-01 16:10:37 +01:00
}
@FXML
private void autoplayToggleBtnAction(){
XMLController.setAutoplay(!XMLController.isAutoplay());
xmlController.saveSettings();
}
// refresh the selected child of the root node
2018-04-28 18:02:02 +02:00
private void refreshTableElement() {
filmRoot.getChildren().get(indexTable).setValue(filmsList.get(indexList));
}
/**
* add data from films-list to films-table
*/
2018-05-09 22:55:32 +02:00
public void addFilmsToTable(ObservableList<FilmTabelDataType> elementsList) {
2018-03-05 23:03:05 +01:00
for (FilmTabelDataType element : elementsList) {
// only if the entry contains a season and a episode it's a valid series
if (!element.getSeason().isEmpty() && !element.getEpisode().isEmpty()) {
2018-04-13 11:11:25 +02:00
// check if there is a series node to add the item
for (int i = 0; i < filmRoot.getChildren().size(); i++) {
if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) {
2018-04-03 18:23:54 +02:00
// if a root node exists, add element as child
2018-04-13 11:11:25 +02:00
TreeItem<FilmTabelDataType> episodeNode = new TreeItem<>(new FilmTabelDataType(
element.getStreamUrl(), element.getTitle(), element.getSeason(), element.getEpisode(),
element.getFavorite(), element.getCached(), element.getImage()));
filmRoot.getChildren().get(i).getChildren().add(episodeNode);
2018-04-13 11:11:25 +02:00
} else if (filmRoot.getChildren().get(i).nextSibling() == null) {
2018-04-03 18:23:54 +02:00
// if no root node exists, create one and add element as child
2018-04-13 11:11:25 +02:00
TreeItem<FilmTabelDataType> seriesRootNode = new TreeItem<>(new FilmTabelDataType(
element.getTitle() + "_rootNode", element.getTitle(), "", "", element.getFavorite(),
false, element.getImage()));
filmRoot.getChildren().add(seriesRootNode);
}
}
} else {
2018-04-13 11:11:25 +02:00
// if season and episode are empty, we can assume the object is a film
filmRoot.getChildren().add(new TreeItem<FilmTabelDataType>(element));
2016-09-09 20:41:20 +02:00
}
2016-08-14 15:17:14 +02:00
}
}
// add a all elements of sourcesList to the sources table on the settings pane
public void addSourceToTable() {
for (SourceDataType source: sourcesList) {
sourceRoot.getChildren().add(new TreeItem<SourceDataType>(source)); // add data to root-node
}
2016-09-09 20:41:20 +02:00
}
2018-02-24 17:13:52 +01:00
2018-07-22 23:30:52 +02:00
/**
* add a source to the newsources list
* @param path to the source
* @param mode of the source (local or streaming)
*/
public void addSource(String path, String mode) {
JsonObject source = null;
JsonArray newsources = null;
try {
// read old array
File oldSources = new File(XMLController.getDirHomeFlix() + "/sources.json");
if (oldSources.exists()) {
newsources = Json.parse(new FileReader(XMLController.getDirHomeFlix() + "/sources.json")).asArray();
} else {
newsources = Json.array();
}
// add new source
source = Json.object().add("path", path).add("mode", mode);
newsources.add(source);
Writer writer = new FileWriter(XMLController.getDirHomeFlix() + "/sources.json");
newsources.writeTo(writer);
writer.close();
} catch (IOException e) {
LOGGER.error(e);
}
// clear old sources list/table
getSourcesList().clear();
getSourceRoot().getChildren().clear();
// update the database and all films from the database
dbController.refreshDataBase();
checkAllPosters(); // check if there is anything to cache
2016-08-14 15:17:14 +02:00
}
/**
* set the color of the GUI-Elements
* if usedColor is less than checkColor set text fill white, else black
*/
2018-03-01 16:10:37 +01:00
private void applyColor() {
2018-04-28 18:02:02 +02:00
String menuBtnStyle;
BigInteger usedColor = new BigInteger(XMLController.getColor(), 16);
BigInteger checkColor = new BigInteger("78909cff", 16);
2018-02-24 17:13:52 +01:00
if (usedColor.compareTo(checkColor) == -1) {
btnStyle = "-fx-button-type: RAISED; -fx-background-color: #" + XMLController.getColor() + "; -fx-text-fill: WHITE;";
2018-04-28 18:02:02 +02:00
menuBtnStyle = "-fx-text-fill: WHITE;";
2018-05-09 22:55:32 +02:00
playbtn.setGraphic(new ImageView(new Image("icons/ic_play_arrow_white_18dp_1x.png")));
returnBtn.setGraphic(new ImageView(new Image("icons/ic_skip_previous_white_18dp_1x.png")));
forwardBtn.setGraphic(new ImageView(new Image("icons/ic_skip_next_white_18dp_1x.png")));
menuHam.getStyleClass().clear();
menuHam.getStyleClass().add("jfx-hamburgerW");
2018-02-24 17:13:52 +01:00
} else {
btnStyle = "-fx-button-type: RAISED; -fx-background-color: #" + XMLController.getColor() + "; -fx-text-fill: BLACK;";
2018-04-28 18:02:02 +02:00
menuBtnStyle = "-fx-text-fill: BLACK;";
2018-05-09 22:55:32 +02:00
playbtn.setGraphic(new ImageView(new Image("icons/ic_play_arrow_black_18dp_1x.png")));
returnBtn.setGraphic(new ImageView(new Image("icons/ic_skip_previous_black_18dp_1x.png")));
forwardBtn.setGraphic(new ImageView(new Image("icons/ic_skip_next_black_18dp_1x.png")));
menuHam.getStyleClass().clear();
menuHam.getStyleClass().add("jfx-hamburgerB");
2016-08-14 15:17:14 +02:00
}
2018-04-28 18:02:02 +02:00
// boxes and TextFields
sideMenuVBox.setStyle("-fx-background-color: #" + XMLController.getColor() + ";");
topHBox.setStyle("-fx-background-color: #" + XMLController.getColor() + ";");
searchTextField.setFocusColor(Color.valueOf(XMLController.getColor()));
2018-04-28 18:02:02 +02:00
// normal buttons
addDirectoryBtn.setStyle(btnStyle);
addStreamSourceBtn.setStyle(btnStyle);
updateBtn.setStyle(btnStyle);
playbtn.setStyle(btnStyle);
openfolderbtn.setStyle(btnStyle);
returnBtn.setStyle(btnStyle);
forwardBtn.setStyle(btnStyle);
// menu buttons
settingsBtn.setStyle(menuBtnStyle);
aboutBtn.setStyle(menuBtnStyle);
2016-08-14 15:17:14 +02:00
}
// slide in in 400ms
2018-02-24 17:13:52 +01:00
private void sideMenuSlideIn() {
2016-10-10 16:55:26 +02:00
sideMenuVBox.setVisible(true);
TranslateTransition translateTransition = new TranslateTransition(Duration.millis(400), sideMenuVBox);
translateTransition.setFromX(-150);
translateTransition.setToX(0);
translateTransition.play();
2016-10-10 16:55:26 +02:00
}
2016-08-14 15:17:14 +02:00
// slide out in 400ms
2018-02-24 17:13:52 +01:00
private void sideMenuSlideOut() {
2016-10-10 16:55:26 +02:00
TranslateTransition translateTransition = new TranslateTransition(Duration.millis(400), sideMenuVBox);
translateTransition.setFromX(0);
translateTransition.setToX(-150);
translateTransition.play();
2016-10-10 16:55:26 +02:00
}
2016-08-14 15:17:14 +02:00
/**
* set the local based on the languageChoisBox selection
*/
2018-02-24 17:13:52 +01:00
void setLocalUI() {
switch (XMLController.getUsrLocal()) {
2018-02-24 17:13:52 +01:00
case "en_US":
XMLController.setLocalBundle(ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US)); // us_English
languageChoisBox.getSelectionModel().select(0);
2017-02-09 20:39:43 +01:00
break;
2018-02-24 17:13:52 +01:00
case "de_DE":
XMLController.setLocalBundle(ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.GERMAN)); // German
languageChoisBox.getSelectionModel().select(1);
2017-02-09 20:39:43 +01:00
break;
2018-02-24 17:13:52 +01:00
default:
XMLController.setLocalBundle(ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US)); // default local
languageChoisBox.getSelectionModel().select(0);
2017-02-09 20:39:43 +01:00
break;
2018-02-24 17:13:52 +01:00
}
aboutBtn.setText(XMLController.getLocalBundle().getString("info"));
settingsBtn.setText(XMLController.getLocalBundle().getString("settings"));
searchTextField.setPromptText(XMLController.getLocalBundle().getString("tfSearch"));
openfolderbtn.setText(XMLController.getLocalBundle().getString("openFolder"));
updateBtn.setText(XMLController.getLocalBundle().getString("checkUpdates"));
addDirectoryBtn.setText(XMLController.getLocalBundle().getString("addDirectory"));
addStreamSourceBtn.setText(XMLController.getLocalBundle().getString("addStreamSource"));
homeflixSettingsLbl.setText(XMLController.getLocalBundle().getString("homeflixSettingsLbl"));
mainColorLbl.setText(XMLController.getLocalBundle().getString("mainColorLbl"));
fontsizeLbl.setText(XMLController.getLocalBundle().getString("fontsizeLbl"));
languageLbl.setText(XMLController.getLocalBundle().getString("languageLbl"));
autoUpdateToggleBtn.setText(XMLController.getLocalBundle().getString("autoUpdate"));
autoplayToggleBtn.setText(XMLController.getLocalBundle().getString("autoplay"));
branchLbl.setText(XMLController.getLocalBundle().getString("branchLbl"));
columnStreamUrl.setText(XMLController.getLocalBundle().getString("columnStreamUrl"));
columnTitle.setText(XMLController.getLocalBundle().getString("columnName"));
columnFavorite.setText(XMLController.getLocalBundle().getString("columnFavorite"));
columnSeason.setText(XMLController.getLocalBundle().getString("columnSeason"));
columnEpisode.setText(XMLController.getLocalBundle().getString("columnEpisode"));
2016-08-14 15:17:14 +02:00
}
// if AutoUpdate, then check for updates
private void checkAutoUpdate() {
if (XMLController.isAutoUpdate()) {
try {
LOGGER.info("AutoUpdate: looking for updates on startup ...");
updateController = new UpdateController(this, buildNumber, XMLController.isUseBeta());
Thread updateThread = new Thread(updateController);
updateThread.setName("Updater");
updateThread.start();
updateThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* check if a film is supported by the HomeFlixPlayer or not
* this is the case if the mime type is mp4
* @param entry the film you want to check
* @return true if so, false if not
*/
private boolean isSupportedFormat(FilmTabelDataType film) {
String mimeType = URLConnection.guessContentTypeFromName(film.getStreamUrl());
return mimeType != null && (mimeType.contains("mp4") || mimeType.contains("vp6"));
2016-09-09 20:41:20 +02:00
}
private void posterModeStartup() {
checkAllPosters();
}
/**
* check if all posters are cached, if not cache the missing ones
*/
private void checkAllPosters() {
// get all not cached entries, none of them should have a cached poster
2018-12-08 23:44:17 +01:00
ExecutorService executor = Executors.newFixedThreadPool(5);
for (FilmTabelDataType entry : dbController.getAllNotCachedEntries()) {
System.out.println(entry.getStreamUrl() + " is NOT cached!");
2018-12-08 23:44:17 +01:00
Runnable OMDbAPIWorker = new OMDbAPIController(dbController, entry, XMLController.getOmdbAPIKey(), false);
2018-12-08 23:44:17 +01:00
executor.execute(OMDbAPIWorker);
}
2018-12-08 23:44:17 +01:00
executor.shutdown();
2018-12-08 23:44:17 +01:00
// TODO show loading screen
}
2018-02-24 17:13:52 +01:00
// getter and setter
public static DBController getDbController() {
return dbController;
}
2018-04-28 18:02:02 +02:00
public FilmTabelDataType getCurrentTableFilm() {
return currentTableFilm;
}
2016-09-09 20:41:20 +02:00
2018-04-06 20:33:56 +02:00
public String getCurrentTitle() {
return currentTableFilm.getTitle();
}
2018-04-06 20:33:56 +02:00
public String getCurrentStreamUrl() {
return currentTableFilm.getStreamUrl();
}
public int getIndexTable() {
return indexTable;
}
public int getIndexList() {
return indexList;
}
public ObservableList<FilmTabelDataType> getFilmsList() {
return filmsList;
}
public static ObservableList<SourceDataType> getSourcesList() {
return sourcesList;
}
public TreeTableView<FilmTabelDataType> getFilmsTreeTable() {
return filmsTreeTable;
}
public TextFlow getTextFlow() {
return textFlow;
}
public ImageView getPosterImageView() {
return posterImageView;
}
public JFXButton getUpdateBtn() {
return updateBtn;
}
public TreeItem<FilmTabelDataType> getFilmRoot() {
return filmRoot;
}
public TreeItem<SourceDataType> getSourceRoot() {
return sourceRoot;
}
2017-01-26 16:32:47 +01:00
}