|
@ -17,11 +17,16 @@
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="module" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=9
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=9
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
org.eclipse.jdt.core.compiler.compliance=9
|
org.eclipse.jdt.core.compiler.compliance=9
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
org.eclipse.jdt.core.compiler.source=9
|
org.eclipse.jdt.core.compiler.source=9
|
||||||
|
|
|
@ -18,7 +18,7 @@ sqlite-jdbc: https://github.com/xerial/sqlite-jdbc
|
||||||
apache commons io : https://commons.apache.org/proper/commons-io/
|
apache commons io : https://commons.apache.org/proper/commons-io/
|
||||||
|
|
||||||
## screenshots
|
## screenshots
|
||||||
![Screenshot](https://github.com/Seil0/Seil0.github.io/blob/master/pictures/Project-HomeFlix_MainWindow.png)
|
![Screenshot](https://github.com/Seil0/Seil0.github.io/blob/master/images/Project-HomeFlix_MainWindow.png)
|
||||||
|
|
||||||
Project-HomeFlix © 2016-2018 Kellerkinder ([Seil0](https://github.com/Seil0), [Windoofs](https://github.com/Windoofs))
|
Project-HomeFlix © 2016-2018 Kellerkinder ([Seil0](https://github.com/Seil0), [Windoofs](https://github.com/Windoofs))
|
||||||
www.kellerkinder.xyz
|
www.kellerkinder.xyz
|
||||||
|
|
24
pom.xml
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<groupId>org.kellerkinder</groupId>
|
<groupId>org.kellerkinder</groupId>
|
||||||
<artifactId>Project-HomeFlix</artifactId>
|
<artifactId>Project-HomeFlix</artifactId>
|
||||||
<version>0.6.0</version>
|
<version>0.7.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Project-HomeFlix</name>
|
<name>Project-HomeFlix</name>
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.11</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jfoenix</groupId>
|
<groupId>com.jfoenix</groupId>
|
||||||
<artifactId>jfoenix</artifactId>
|
<artifactId>jfoenix</artifactId>
|
||||||
<version>9.0.2</version>
|
<version>9.0.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -50,13 +50,13 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-api</artifactId>
|
<artifactId>log4j-api</artifactId>
|
||||||
<version>2.10.0</version>
|
<version>2.11.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-core</artifactId>
|
<artifactId>log4j-core</artifactId>
|
||||||
<version>2.10.0</version>
|
<version>2.11.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -78,13 +78,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.1.1</version>
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
<transformers>
|
<transformers>
|
||||||
|
@ -93,6 +87,12 @@
|
||||||
</transformer>
|
</transformer>
|
||||||
</transformers>
|
</transformers>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
/**
|
|
||||||
* cemu_UI
|
|
||||||
*
|
|
||||||
* Copyright 2017 <@Seil0>
|
|
||||||
*
|
|
||||||
* 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 com.cemu_UI.uiElements;
|
|
||||||
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
|
||||||
import com.jfoenix.controls.JFXDialog;
|
|
||||||
import com.jfoenix.controls.JFXDialogLayout;
|
|
||||||
|
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.event.EventHandler;
|
|
||||||
import javafx.scene.layout.AnchorPane;
|
|
||||||
import javafx.scene.layout.Pane;
|
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
public class JFXOkayCancelDialog {
|
|
||||||
|
|
||||||
private String headingText;
|
|
||||||
private String bodyText;
|
|
||||||
private String dialogBtnStyle;
|
|
||||||
private String okayText;
|
|
||||||
private String cancelText;
|
|
||||||
private int dialogWidth;
|
|
||||||
private int dialogHeight;
|
|
||||||
private EventHandler<ActionEvent> okayAction;
|
|
||||||
private EventHandler<ActionEvent> cancelAction;
|
|
||||||
private Pane pane;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new JFoenix Dialog to show some information with okay and cancel option
|
|
||||||
* @param headingText Heading Text, just the heading
|
|
||||||
* @param bodyText body Text, all other text belongs here
|
|
||||||
* @param dialogBtnStyle Style of the okay button
|
|
||||||
* @param dialogWidth dialog width
|
|
||||||
* @param dialogHeight dialog height
|
|
||||||
* @param okayAction action which is performed if the okay button is clicked
|
|
||||||
* @param cancelAction action which is performed if the cancel button is clicked
|
|
||||||
* @param pane pane to which the dialog belongs
|
|
||||||
*/
|
|
||||||
public JFXOkayCancelDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth,
|
|
||||||
int dialogHeight, EventHandler<ActionEvent> okayAction, EventHandler<ActionEvent> cancelAction, Pane pane,
|
|
||||||
ResourceBundle bundle) {
|
|
||||||
this.headingText = headingText;
|
|
||||||
this.bodyText = bodyText;
|
|
||||||
this.dialogBtnStyle = dialogBtnStyle;
|
|
||||||
this.dialogWidth = dialogWidth;
|
|
||||||
this.dialogHeight = dialogHeight;
|
|
||||||
this.okayAction = okayAction;
|
|
||||||
this.cancelAction = cancelAction;
|
|
||||||
this.pane = pane;
|
|
||||||
okayText = bundle.getString("okayBtnText");
|
|
||||||
cancelText = bundle.getString("cancelBtnText");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void show() {
|
|
||||||
|
|
||||||
JFXDialogLayout content = new JFXDialogLayout();
|
|
||||||
content.setHeading(new Text(headingText));
|
|
||||||
content.setBody(new Text(bodyText));
|
|
||||||
StackPane stackPane = new StackPane();
|
|
||||||
stackPane.autosize();
|
|
||||||
JFXDialog dialog = new JFXDialog(stackPane, content, JFXDialog.DialogTransition.LEFT, true);
|
|
||||||
JFXButton okayBtn = new JFXButton(okayText);
|
|
||||||
okayBtn.addEventHandler(ActionEvent.ACTION, (e)-> {
|
|
||||||
dialog.close();
|
|
||||||
});
|
|
||||||
okayBtn.addEventHandler(ActionEvent.ACTION, okayAction);
|
|
||||||
okayBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
|
||||||
okayBtn.setPrefHeight(32);
|
|
||||||
okayBtn.setStyle(dialogBtnStyle);
|
|
||||||
JFXButton cancelBtn = new JFXButton(cancelText);
|
|
||||||
cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> {
|
|
||||||
dialog.close();
|
|
||||||
});
|
|
||||||
cancelBtn.addEventHandler(ActionEvent.ACTION, cancelAction);
|
|
||||||
cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
|
||||||
cancelBtn.setPrefHeight(32);
|
|
||||||
cancelBtn.setStyle(dialogBtnStyle);
|
|
||||||
content.setActions(cancelBtn, okayBtn);
|
|
||||||
content.setPrefSize(dialogWidth, dialogHeight);
|
|
||||||
pane.getChildren().add(stackPane);
|
|
||||||
AnchorPane.setTopAnchor(stackPane, (pane.getHeight()-content.getPrefHeight())/2);
|
|
||||||
AnchorPane.setLeftAnchor(stackPane, (pane.getWidth()-content.getPrefWidth())/2);
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOkayText() {
|
|
||||||
return okayText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOkayText(String okayText) {
|
|
||||||
this.okayText = okayText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCancelText() {
|
|
||||||
return cancelText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCancelText(String cancelText) {
|
|
||||||
this.cancelText = cancelText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventHandler<ActionEvent> getOkayAction() {
|
|
||||||
return okayAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOkayAction(EventHandler<ActionEvent> okayAction) {
|
|
||||||
this.okayAction = okayAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventHandler<ActionEvent> getCancelAction() {
|
|
||||||
return cancelAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCancelAction(EventHandler<ActionEvent> cancelAction) {
|
|
||||||
this.cancelAction = cancelAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/**
|
|
||||||
* cemu_UI
|
|
||||||
*
|
|
||||||
* Copyright 2017 <@Seil0>
|
|
||||||
*
|
|
||||||
* 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 com.cemu_UI.uiElements;
|
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
|
||||||
import com.jfoenix.controls.JFXDialog;
|
|
||||||
import com.jfoenix.controls.JFXDialogLayout;
|
|
||||||
import com.jfoenix.controls.JFXTextArea;
|
|
||||||
|
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.event.EventHandler;
|
|
||||||
import javafx.scene.layout.AnchorPane;
|
|
||||||
import javafx.scene.layout.Pane;
|
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
|
|
||||||
public class JFXTextAreaInfoDialog {
|
|
||||||
|
|
||||||
private String headingText;
|
|
||||||
private String bodyText;
|
|
||||||
private String dialogBtnStyle;
|
|
||||||
private int dialogWidth;
|
|
||||||
private int dialogHeight;
|
|
||||||
private JFXTextArea textArea;
|
|
||||||
private Pane pane;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new JFoenix Dialog to show some information
|
|
||||||
* @param headingText Heading Text, just the heading
|
|
||||||
* @param bodyText body Text, all other text belongs here
|
|
||||||
* @param dialogBtnStyle Style of the okay button
|
|
||||||
* @param dialogWidth dialog width
|
|
||||||
* @param dialogHeight dialog height
|
|
||||||
* @param pane pane to which the dialog belongs
|
|
||||||
*/
|
|
||||||
public JFXTextAreaInfoDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth, int dialogHeight, Pane pane) {
|
|
||||||
this.headingText = headingText;
|
|
||||||
this.bodyText = bodyText;
|
|
||||||
this.dialogBtnStyle = dialogBtnStyle;
|
|
||||||
this.dialogWidth = dialogWidth;
|
|
||||||
this.dialogHeight = dialogHeight;
|
|
||||||
this.pane = pane;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void show() {
|
|
||||||
textArea = new JFXTextArea(bodyText);
|
|
||||||
|
|
||||||
JFXDialogLayout content = new JFXDialogLayout();
|
|
||||||
content.setHeading(new Text(headingText));
|
|
||||||
content.setBody(textArea);
|
|
||||||
content.setPrefSize(dialogWidth, dialogHeight);
|
|
||||||
StackPane stackPane = new StackPane();
|
|
||||||
stackPane.autosize();
|
|
||||||
JFXDialog dialog = new JFXDialog(stackPane, content, JFXDialog.DialogTransition.LEFT, true);
|
|
||||||
JFXButton button = new JFXButton("Okay");
|
|
||||||
button.setOnAction(new EventHandler<ActionEvent>() {
|
|
||||||
@Override
|
|
||||||
public void handle(ActionEvent event) {
|
|
||||||
dialog.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
button.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
|
||||||
button.setPrefHeight(32);
|
|
||||||
button.setStyle(dialogBtnStyle);
|
|
||||||
content.setActions(button);
|
|
||||||
pane.getChildren().add(stackPane);
|
|
||||||
AnchorPane.setTopAnchor(stackPane, (pane.getHeight() - content.getPrefHeight()) / 2);
|
|
||||||
AnchorPane.setLeftAnchor(stackPane, (pane.getWidth() - content.getPrefWidth()) / 2);
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JFXTextArea getTextArea() {
|
|
||||||
return textArea;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTextArea(JFXTextArea textArea) {
|
|
||||||
this.textArea = textArea;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,28 +19,28 @@
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.application;
|
package kellerkinder.HomeFlix.application;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.kellerkinder.Alerts.JFX2BtnCancelAlert;
|
||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.Alert.AlertType;
|
|
||||||
import javafx.scene.control.ButtonType;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.stage.DirectoryChooser;
|
import javafx.stage.DirectoryChooser;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.WindowEvent;
|
||||||
|
|
||||||
public class Main extends Application {
|
public class Main extends Application {
|
||||||
|
|
||||||
|
@ -54,17 +54,13 @@ public class Main extends Application {
|
||||||
private static String osArch = System.getProperty("os.arch");
|
private static String osArch = System.getProperty("os.arch");
|
||||||
private static String osVers = System.getProperty("os.version");
|
private static String osVers = System.getProperty("os.version");
|
||||||
private static String javaVers = System.getProperty("java.version");
|
private static String javaVers = System.getProperty("java.version");
|
||||||
private static String javaVend= System.getProperty("java.vendor");
|
private static String javaVend = System.getProperty("java.vendor");
|
||||||
private String dirWin = userHome + "/Documents/HomeFlix"; //Windows: C:/Users/"User"/Documents/HomeFlix
|
private static String local = System.getProperty("user.language") + "_" + System.getProperty("user.country");
|
||||||
private String dirLinux = userHome + "/HomeFlix"; //Linux: /home/"User"/HomeFlix
|
private String dirWin = userHome + "/Documents/HomeFlix"; // Windows: C:/Users/"User"/Documents/HomeFlix
|
||||||
|
private String dirLinux = userHome + "/HomeFlix"; // Linux: /home/"User"/HomeFlix
|
||||||
private File directory;
|
private File directory;
|
||||||
private File configFile;
|
private File configFile;
|
||||||
private File posterCache;
|
private File posterCache;
|
||||||
|
|
||||||
private String path;
|
|
||||||
private String FONT_FAMILY = "System";
|
|
||||||
private String local = System.getProperty("user.language")+"_"+System.getProperty("user.country");
|
|
||||||
private double FONT_SIZE = 17;
|
|
||||||
private ResourceBundle bundle;
|
private ResourceBundle bundle;
|
||||||
private static Logger LOGGER;
|
private static Logger LOGGER;
|
||||||
|
|
||||||
|
@ -78,6 +74,10 @@ public class Main extends Application {
|
||||||
mainWindow();
|
mainWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize the mainWindowController, GUI and load the saved settings or call addFirstSource
|
||||||
|
* initialize the primaryStage and set the file/directory paths
|
||||||
|
*/
|
||||||
private void mainWindow(){
|
private void mainWindow(){
|
||||||
try {
|
try {
|
||||||
FXMLLoader loader = new FXMLLoader();
|
FXMLLoader loader = new FXMLLoader();
|
||||||
|
@ -88,12 +88,18 @@ public class Main extends Application {
|
||||||
primaryStage.setResizable(false);
|
primaryStage.setResizable(false);
|
||||||
primaryStage.setTitle("Project HomeFlix");
|
primaryStage.setTitle("Project HomeFlix");
|
||||||
primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); //adds application icon
|
primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); //adds application icon
|
||||||
|
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
|
||||||
|
public void handle(WindowEvent we) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mainWindowController = loader.getController(); //Link of FXMLController and controller class
|
mainWindowController = loader.getController(); //Link of FXMLController and controller class
|
||||||
mainWindowController.setMain(this); //call setMain
|
mainWindowController.setMain(this); //call setMain
|
||||||
|
|
||||||
|
|
||||||
// get OS and the specific paths
|
// get OS and the specific paths
|
||||||
if (osName.equals("Windows")) {
|
if (osName.contains("Windows")) {
|
||||||
directory = new File(dirWin);
|
directory = new File(dirWin);
|
||||||
configFile = new File(dirWin + "/config.xml");
|
configFile = new File(dirWin + "/config.xml");
|
||||||
posterCache = new File(dirWin + "/posterCache");
|
posterCache = new File(dirWin + "/posterCache");
|
||||||
|
@ -103,33 +109,27 @@ public class Main extends Application {
|
||||||
posterCache = new File(dirLinux + "/posterCache");
|
posterCache = new File(dirLinux + "/posterCache");
|
||||||
}
|
}
|
||||||
|
|
||||||
// startup checks
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
directory.mkdir();
|
|
||||||
mainWindowController.addSource(firstStart(), "local");
|
|
||||||
mainWindowController.setColor("ee3523");
|
|
||||||
mainWindowController.setSize(FONT_SIZE);
|
|
||||||
mainWindowController.setAutoUpdate(false);
|
|
||||||
mainWindowController.setLocal(local);
|
|
||||||
mainWindowController.saveSettings();
|
|
||||||
try {
|
|
||||||
Runtime.getRuntime().exec("java -jar ProjectHomeFlix.jar"); // start again (preventing Bugs) TODO is this really needed
|
|
||||||
System.exit(0); // finishes it self
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("error while restarting HomeFlix", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!posterCache.exists()) {
|
|
||||||
posterCache.mkdir();
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate window
|
// generate window
|
||||||
scene = new Scene(pane); // create new scene, append pane to scene
|
scene = new Scene(pane); // create new scene, append pane to scene
|
||||||
scene.getStylesheets().add(getClass().getResource("/css/MainWindow.css").toExternalForm());
|
scene.getStylesheets().add(getClass().getResource("/css/MainWindow.css").toExternalForm());
|
||||||
primaryStage.setScene(scene); // append scene to stage
|
primaryStage.setScene(scene); // append scene to stage
|
||||||
primaryStage.show(); // show stage
|
primaryStage.show(); // show stage
|
||||||
|
|
||||||
|
// startup checks
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
directory.mkdir();
|
||||||
|
addFirstSource();
|
||||||
|
mainWindowController.setColor("ee3523");
|
||||||
|
mainWindowController.setFontSize(17.0);
|
||||||
|
mainWindowController.setAutoUpdate(false);
|
||||||
|
mainWindowController.setLocal(local);
|
||||||
|
mainWindowController.saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!posterCache.exists()) {
|
||||||
|
posterCache.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
// init here as it loads the games to the mwc and the gui, therefore the window must exist
|
// init here as it loads the games to the mwc and the gui, therefore the window must exist
|
||||||
mainWindowController.init();
|
mainWindowController.init();
|
||||||
mainWindowController.getDbController().init();
|
mainWindowController.getDbController().init();
|
||||||
|
@ -138,9 +138,12 @@ public class Main extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method for first Start
|
/**
|
||||||
private String firstStart(){
|
* we need to get the path for the first source from the user and add it to
|
||||||
switch (System.getProperty("user.language") + "_" + System.getProperty("user.country")) {
|
* sources.json, if the user ends the file-/directory-chooser the program will exit
|
||||||
|
*/
|
||||||
|
private void addFirstSource() {
|
||||||
|
switch (local) {
|
||||||
case "en_US":
|
case "en_US":
|
||||||
bundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US); // us_english
|
bundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US); // us_english
|
||||||
break;
|
break;
|
||||||
|
@ -152,30 +155,61 @@ public class Main extends Application {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with file-chooser
|
JFX2BtnCancelAlert selectFirstSource = new JFX2BtnCancelAlert(bundle.getString("addSourceHeader"),
|
||||||
alert.setTitle("Project HomeFlix");
|
bundle.getString("addSourceBody"),
|
||||||
alert.setHeaderText(bundle.getString("firstStartHeader"));
|
"-fx-button-type: RAISED; -fx-background-color: #ee3523; -fx-text-fill: BLACK;",
|
||||||
alert.setContentText(bundle.getString("firstStartContent"));
|
bundle.getString("addDirectory"), bundle.getString("addStreamSource"),
|
||||||
|
bundle.getString("cancelBtnText"), primaryStage);
|
||||||
|
|
||||||
Optional<ButtonType> result = alert.showAndWait();
|
// directory action
|
||||||
if (result.get() == ButtonType.OK){
|
EventHandler<ActionEvent> btn1Action = new EventHandler<ActionEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event) {
|
||||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||||
File selectedDirectory =
|
directoryChooser.setTitle(bundle.getString("addDirectory"));
|
||||||
directoryChooser.showDialog(primaryStage);
|
File selectedFolder = directoryChooser.showDialog(primaryStage);
|
||||||
path = selectedDirectory.getAbsolutePath();
|
if (selectedFolder != null && selectedFolder.exists()) {
|
||||||
|
mainWindowController.addSource(selectedFolder.getPath(), "local");
|
||||||
|
selectFirstSource.getAlert().close();
|
||||||
} else {
|
} else {
|
||||||
path = "";
|
LOGGER.error("The selected folder dosen't exist!");
|
||||||
|
System.exit(1);
|
||||||
}
|
}
|
||||||
return path;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// streaming action
|
||||||
|
EventHandler<ActionEvent> btn2Action = new EventHandler<ActionEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event) {
|
||||||
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
fileChooser.setTitle("addStreamSource");
|
||||||
|
File selectedFile = fileChooser.showOpenDialog(getPrimaryStage());
|
||||||
|
if (selectedFile != null && selectedFile.exists()) {
|
||||||
|
mainWindowController.addSource(selectedFile.getPath(), "stream");
|
||||||
|
selectFirstSource.getAlert().close();
|
||||||
|
} else {
|
||||||
|
LOGGER.error("The selected file dosen't exist!");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
selectFirstSource.setBtn1Action(btn1Action);
|
||||||
|
selectFirstSource.setBtn2Action(btn2Action);
|
||||||
|
selectFirstSource.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the log file location and initialize the logger
|
||||||
|
* launch the GUI
|
||||||
|
* @param args arguments given at the start
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if(System.getProperty("os.name").equals("Windows")){
|
if (System.getProperty("os.name").equals("Windows")) {
|
||||||
System.setProperty("logFilename", userHome + "/Documents/HomeFlix/app.log");
|
System.setProperty("logFilename", userHome + "/Documents/HomeFlix/app.log");
|
||||||
File logFile = new File(userHome + "/Documents/HomeFlix/app.log");
|
File logFile = new File(userHome + "/Documents/HomeFlix/app.log");
|
||||||
logFile.delete();
|
logFile.delete();
|
||||||
}else{
|
} else {
|
||||||
System.setProperty("logFilename", userHome + "/HomeFlix/app.log");
|
System.setProperty("logFilename", userHome + "/HomeFlix/app.log");
|
||||||
File logFile = new File(userHome + "/HomeFlix/app.log");
|
File logFile = new File(userHome + "/HomeFlix/app.log");
|
||||||
logFile.delete();
|
logFile.delete();
|
||||||
|
@ -188,22 +222,10 @@ public class Main extends Application {
|
||||||
return primaryStage;
|
return primaryStage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrimaryStage(Stage primaryStage) {
|
public AnchorPane getPane() {
|
||||||
this.primaryStage = primaryStage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnchorPane getPane( ) {
|
|
||||||
return pane;
|
return pane;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFONT_FAMILY() {
|
|
||||||
return FONT_FAMILY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFONT_FAMILY(String FONT_FAMILY) {
|
|
||||||
this.FONT_FAMILY = FONT_FAMILY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getDirectory() {
|
public File getDirectory() {
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.application;
|
package kellerkinder.HomeFlix.application;
|
||||||
|
|
||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
|
@ -33,19 +32,17 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.net.URLConnection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.kellerkinder.Alerts.JFXInfoAlert;
|
||||||
|
|
||||||
import com.cemu_UI.uiElements.JFXInfoDialog;
|
|
||||||
import com.eclipsesource.json.Json;
|
import com.eclipsesource.json.Json;
|
||||||
import com.eclipsesource.json.JsonArray;
|
import com.eclipsesource.json.JsonArray;
|
||||||
import com.eclipsesource.json.JsonObject;
|
import com.eclipsesource.json.JsonObject;
|
||||||
|
@ -65,8 +62,6 @@ import javafx.collections.ObservableList;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.Alert.AlertType;
|
|
||||||
import javafx.scene.control.ChoiceBox;
|
import javafx.scene.control.ChoiceBox;
|
||||||
import javafx.scene.control.ContextMenu;
|
import javafx.scene.control.ContextMenu;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
@ -74,7 +69,6 @@ import javafx.scene.control.MenuItem;
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.control.TableColumn;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.TableView;
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
import javafx.scene.control.TreeTableColumn;
|
import javafx.scene.control.TreeTableColumn;
|
||||||
import javafx.scene.control.TreeTableColumn.SortType;
|
import javafx.scene.control.TreeTableColumn.SortType;
|
||||||
|
@ -83,9 +77,7 @@ import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.GridPane;
|
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
|
@ -97,16 +89,18 @@ import kellerkinder.HomeFlix.controller.DBController;
|
||||||
import kellerkinder.HomeFlix.controller.OMDbAPIController;
|
import kellerkinder.HomeFlix.controller.OMDbAPIController;
|
||||||
import kellerkinder.HomeFlix.controller.UpdateController;
|
import kellerkinder.HomeFlix.controller.UpdateController;
|
||||||
import kellerkinder.HomeFlix.datatypes.SourceDataType;
|
import kellerkinder.HomeFlix.datatypes.SourceDataType;
|
||||||
|
import kellerkinder.HomeFlix.player.Player;
|
||||||
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||||
|
|
||||||
public class MainWindowController {
|
public class MainWindowController {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private AnchorPane mainAnchorPane;
|
private AnchorPane mainAnchorPane;
|
||||||
|
@FXML
|
||||||
|
private AnchorPane tableModeAnchorPane;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ScrollPane settingsScrollPane;
|
private ScrollPane settingsScrollPane;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ScrollPane textScrollPane;
|
private ScrollPane textScrollPane;
|
||||||
|
|
||||||
|
@ -127,31 +121,20 @@ public class MainWindowController {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton playbtn;
|
private JFXButton playbtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton openfolderbtn;
|
private JFXButton openfolderbtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton returnBtn;
|
private JFXButton returnBtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton forwardBtn;
|
private JFXButton forwardBtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton aboutBtn;
|
private JFXButton aboutBtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton settingsBtn;
|
private JFXButton settingsBtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton debugBtn;
|
private JFXButton updateBtn;
|
||||||
|
|
||||||
@FXML
|
|
||||||
public JFXButton updateBtn;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton addDirectoryBtn;
|
private JFXButton addDirectoryBtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton addStreamSourceBtn;
|
private JFXButton addStreamSourceBtn;
|
||||||
|
|
||||||
|
@ -160,43 +143,37 @@ public class MainWindowController {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXToggleButton autoUpdateToggleBtn;
|
private JFXToggleButton autoUpdateToggleBtn;
|
||||||
|
@FXML
|
||||||
|
private JFXToggleButton autoplayToggleBtn;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXTextField searchTextField;
|
private JFXTextField searchTextField;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public JFXColorPicker colorPicker;
|
private JFXColorPicker colorPicker;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public ChoiceBox<String> languageChoisBox = new ChoiceBox<>();
|
private ChoiceBox<String> languageChoisBox = new ChoiceBox<>();
|
||||||
|
@FXML
|
||||||
|
private ChoiceBox<String> branchChoisBox = new ChoiceBox<>();
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public ChoiceBox<String> branchChoisBox = new ChoiceBox<>();
|
private JFXSlider fontsizeSlider;
|
||||||
|
|
||||||
@FXML
|
|
||||||
public JFXSlider fontsizeSlider;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label homeflixSettingsLbl;
|
private Label homeflixSettingsLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label mainColorLbl;
|
private Label mainColorLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label fontsizeLbl;
|
private Label fontsizeLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label languageLbl;
|
private Label languageLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label updateLbl;
|
private Label updateLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label branchLbl;
|
private Label branchLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label sourcesLbl;
|
private Label sourcesLbl;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label versionLbl;
|
private Label versionLbl;
|
||||||
|
|
||||||
|
@ -218,7 +195,7 @@ public class MainWindowController {
|
||||||
private TreeTableColumn<FilmTabelDataType, ImageView> columnFavorite = new TreeTableColumn<>("Favorite");
|
private TreeTableColumn<FilmTabelDataType, ImageView> columnFavorite = new TreeTableColumn<>("Favorite");
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TreeItem<SourceDataType> sourceRoot =new TreeItem<>(new SourceDataType("", ""));
|
private TreeItem<SourceDataType> sourceRoot = new TreeItem<>(new SourceDataType("", ""));
|
||||||
@FXML
|
@FXML
|
||||||
private TableColumn<SourceDataType, String> sourceColumn;
|
private TableColumn<SourceDataType, String> sourceColumn;
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -228,33 +205,31 @@ public class MainWindowController {
|
||||||
private boolean settingsTrue = false;
|
private boolean settingsTrue = false;
|
||||||
private boolean autoUpdate = false;
|
private boolean autoUpdate = false;
|
||||||
private boolean useBeta = false;
|
private boolean useBeta = false;
|
||||||
|
private boolean autoplay = false;
|
||||||
private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName());
|
private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName());
|
||||||
private int hashA = -647380320;
|
private int hashA = -647380320;
|
||||||
|
|
||||||
private String version = "0.6.0";
|
private final String version = "0.7.0";
|
||||||
private String buildNumber = "141";
|
private final String buildNumber = "151";
|
||||||
private String versionName = "plasma vampire";
|
private final String versionName = "toothless dragon";
|
||||||
private String dialogBtnStyle;
|
private String dialogBtnStyle;
|
||||||
private String color;
|
private String color;
|
||||||
private String title;
|
|
||||||
private String streamUrl;
|
|
||||||
private String ratingSortType;
|
|
||||||
private String local;
|
private String local;
|
||||||
private String omdbAPIKey;
|
private String omdbAPIKey;
|
||||||
|
|
||||||
// text strings
|
// text strings
|
||||||
private String errorPlay;
|
|
||||||
private String errorLoad;
|
private String errorLoad;
|
||||||
private String errorSave;
|
private String errorSave;
|
||||||
private String infoText;
|
private String infoText;
|
||||||
private String vlcNotInstalled;
|
private String vlcNotInstalled;
|
||||||
|
|
||||||
public double size;
|
private double fontSize;
|
||||||
private int last;
|
private int last;
|
||||||
private int indexTable;
|
private int indexTable;
|
||||||
private int indexList;
|
private int indexList;
|
||||||
private int next;
|
private int next;
|
||||||
private ResourceBundle bundle;
|
private ResourceBundle bundle;
|
||||||
|
private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, false, null);
|
||||||
|
|
||||||
private ObservableList<String> languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)");
|
private ObservableList<String> languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)");
|
||||||
private ObservableList<String> branches = FXCollections.observableArrayList("stable", "beta");
|
private ObservableList<String> branches = FXCollections.observableArrayList("stable", "beta");
|
||||||
|
@ -267,9 +242,8 @@ public class MainWindowController {
|
||||||
private ImageView skip_next_black = new ImageView(new Image("icons/ic_skip_next_black_18dp_1x.png"));
|
private ImageView skip_next_black = new ImageView(new Image("icons/ic_skip_next_black_18dp_1x.png"));
|
||||||
private ImageView play_arrow_white = new ImageView(new Image("icons/ic_play_arrow_white_18dp_1x.png"));
|
private ImageView play_arrow_white = new ImageView(new Image("icons/ic_play_arrow_white_18dp_1x.png"));
|
||||||
private ImageView play_arrow_black = new ImageView(new Image("icons/ic_play_arrow_black_18dp_1x.png"));
|
private ImageView play_arrow_black = new ImageView(new Image("icons/ic_play_arrow_black_18dp_1x.png"));
|
||||||
private DirectoryChooser directoryChooser = new DirectoryChooser();
|
|
||||||
private MenuItem like = new MenuItem("like");
|
private MenuItem like = new MenuItem("like");
|
||||||
private MenuItem dislike = new MenuItem("dislike"); //TODO one option (like or dislike)
|
private MenuItem dislike = new MenuItem("dislike"); // TODO one option (like or dislike)
|
||||||
private ContextMenu menu = new ContextMenu(like, dislike);
|
private ContextMenu menu = new ContextMenu(like, dislike);
|
||||||
private Properties props = new Properties();
|
private Properties props = new Properties();
|
||||||
|
|
||||||
|
@ -290,12 +264,14 @@ public class MainWindowController {
|
||||||
omdbAPIController = new OMDbAPIController(this, dbController, this.main);
|
omdbAPIController = new OMDbAPIController(this, dbController, this.main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call all initialize methods
|
||||||
void init() {
|
void init() {
|
||||||
|
LOGGER.info("Initializing Project-HomeFlix build " + buildNumber);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
checkAutoUpdate();
|
checkAutoUpdate();
|
||||||
initTabel();
|
initTabel();
|
||||||
initActions();
|
|
||||||
initUI();
|
initUI();
|
||||||
|
initActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the tables (treeTableViewfilm and sourcesTable)
|
// Initialize the tables (treeTableViewfilm and sourcesTable)
|
||||||
|
@ -326,7 +302,7 @@ public class MainWindowController {
|
||||||
filmsTreeTable.getColumns().add(columnFavorite);
|
filmsTreeTable.getColumns().add(columnFavorite);
|
||||||
filmsTreeTable.getColumns().add(columnSeason);
|
filmsTreeTable.getColumns().add(columnSeason);
|
||||||
filmsTreeTable.getColumns().add(columnEpisode);
|
filmsTreeTable.getColumns().add(columnEpisode);
|
||||||
filmsTreeTable.getColumns().get(0).setVisible(false); //hide columnStreamUrl (important)
|
filmsTreeTable.getColumns().get(0).setVisible(false); // hide columnStreamUrl (important)
|
||||||
|
|
||||||
// context menu for treeTableViewfilm
|
// context menu for treeTableViewfilm
|
||||||
filmsTreeTable.setContextMenu(menu);
|
filmsTreeTable.setContextMenu(menu);
|
||||||
|
@ -337,7 +313,7 @@ public class MainWindowController {
|
||||||
sourcesTable.setItems(sourcesList);
|
sourcesTable.setItems(sourcesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Initializing the actions
|
// Initializing the actions
|
||||||
private void initActions() {
|
private void initActions() {
|
||||||
|
|
||||||
HamburgerBackArrowBasicTransition burgerTask = new HamburgerBackArrowBasicTransition(menuHam);
|
HamburgerBackArrowBasicTransition burgerTask = new HamburgerBackArrowBasicTransition(menuHam);
|
||||||
|
@ -364,7 +340,7 @@ public class MainWindowController {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
|
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
|
||||||
ObservableList<FilmTabelDataType> helpData;
|
ObservableList<FilmTabelDataType> helpData;
|
||||||
filterData.removeAll(filterData);
|
filterData.clear();
|
||||||
filmRoot.getChildren().removeAll(filmRoot.getChildren());
|
filmRoot.getChildren().removeAll(filmRoot.getChildren());
|
||||||
|
|
||||||
helpData = filmsList;
|
helpData = filmsList;
|
||||||
|
@ -412,9 +388,9 @@ public class MainWindowController {
|
||||||
fontsizeSlider.valueProperty().addListener(new ChangeListener<Number>() {
|
fontsizeSlider.valueProperty().addListener(new ChangeListener<Number>() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
|
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
|
||||||
setSize(fontsizeSlider.getValue());
|
setFontSize(fontsizeSlider.getValue());
|
||||||
if (title != null) {
|
if (!getCurrentTitle().isEmpty()) {
|
||||||
dbController.readCache(streamUrl);
|
dbController.readCache(getCurrentStreamUrl());
|
||||||
}
|
}
|
||||||
// ta1.setFont(Font.font("System", size));
|
// ta1.setFont(Font.font("System", size));
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
@ -424,8 +400,8 @@ public class MainWindowController {
|
||||||
like.setOnAction(new EventHandler<ActionEvent>() {
|
like.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(ActionEvent event) {
|
public void handle(ActionEvent event) {
|
||||||
dbController.like(streamUrl);
|
dbController.like(getCurrentStreamUrl());
|
||||||
dbController.refresh(streamUrl, indexList);
|
dbController.refresh(getCurrentStreamUrl(), indexList);
|
||||||
refreshTable();
|
refreshTable();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -433,59 +409,41 @@ public class MainWindowController {
|
||||||
dislike.setOnAction(new EventHandler<ActionEvent>() {
|
dislike.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(ActionEvent event) {
|
public void handle(ActionEvent event) {
|
||||||
dbController.dislike(streamUrl);
|
dbController.dislike(getCurrentStreamUrl());
|
||||||
dbController.refresh(streamUrl, indexList);
|
dbController.refresh(getCurrentStreamUrl(), indexList);
|
||||||
refreshTable();
|
refreshTable();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME fix bug when sort by ASCENDING, wrong order
|
* FIXME fix bug when sort by ASCENDING, wrong order
|
||||||
* FIXME when sorting, series are expanded
|
|
||||||
*/
|
*/
|
||||||
columnFavorite.sortTypeProperty().addListener(new ChangeListener<SortType>() {
|
columnFavorite.sortTypeProperty().addListener(new ChangeListener<SortType>() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ObservableValue<? extends SortType> paramObservableValue, SortType paramT1, SortType paramT2) {
|
public void changed(ObservableValue<? extends SortType> paramObservableValue, SortType paramT1, SortType paramT2) {
|
||||||
LOGGER.info("NAME Clicked -- sortType = " + paramT1 + ", SortType=" + paramT2);
|
filmRoot.getChildren().clear();
|
||||||
ArrayList<Integer> fav_true = new ArrayList<Integer>();
|
filterData.clear();
|
||||||
ArrayList<Integer> fav_false = new ArrayList<Integer>();
|
|
||||||
ObservableList<FilmTabelDataType> helpData;
|
|
||||||
filterData.removeAll(filterData);
|
|
||||||
// treeTableViewfilm.getSelectionModel().clearSelection(selected);
|
|
||||||
filmRoot.getChildren().removeAll(filmRoot.getChildren());
|
|
||||||
|
|
||||||
helpData = filmsList;
|
if (paramT2.equals(SortType.DESCENDING)) {
|
||||||
|
for (FilmTabelDataType film : filmsList) {
|
||||||
for (int i = 0; i < helpData.size(); i++) {
|
if (film.getFavorite()) {
|
||||||
if (helpData.get(i).getFavorite() == true) {
|
filterData.add(0, film);
|
||||||
fav_true.add(i);
|
|
||||||
} else {
|
} else {
|
||||||
fav_false.add(i);
|
filterData.add(film);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (paramT2.toString().equals("DESCENDING")) {
|
|
||||||
LOGGER.info("Absteigend"); // Debug, delete?
|
|
||||||
for (int i = 0; i < fav_true.size(); i++) {
|
|
||||||
filterData.add(helpData.get(fav_true.get(i)));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < fav_false.size(); i++) {
|
|
||||||
filterData.add(helpData.get(fav_false.get(i)));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < fav_false.size(); i++) {
|
// System.out.println("ascending");
|
||||||
filterData.add(helpData.get(fav_false.get(i)));
|
for (FilmTabelDataType film : filmsList) {
|
||||||
|
if (!film.getFavorite()) {
|
||||||
|
filterData.add(0, film);
|
||||||
|
} else {
|
||||||
|
filterData.add(film);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < fav_true.size(); i++) {
|
|
||||||
filterData.add(helpData.get(fav_true.get(i)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.info(filterData.size()); // Debug, delete?
|
addDataUI(filterData);
|
||||||
for (int i = 0; i < filterData.size(); i++) {
|
|
||||||
// LOGGER.info(filterData.get(i).getTitle()+"; "+filterData.get(i).getRating()); // Debugging
|
|
||||||
// add filtered data to root node after search
|
|
||||||
filmRoot.getChildren().add(new TreeItem<FilmTabelDataType>(filterData.get(i)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -493,21 +451,24 @@ public class MainWindowController {
|
||||||
filmsTreeTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
|
filmsTreeTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ObservableValue<?> observable, Object oldVal, Object newVal) {
|
public void changed(ObservableValue<?> observable, Object oldVal, Object newVal) {
|
||||||
indexTable = filmsTreeTable.getSelectionModel().getSelectedIndex(); // get selected item
|
if (filmsTreeTable.getSelectionModel().getSelectedItem() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
last = indexTable - 1;
|
last = indexTable - 1;
|
||||||
next = indexTable + 1;
|
next = indexTable + 1;
|
||||||
title = columnTitle.getCellData(indexTable); // get name of selected item
|
|
||||||
streamUrl = columnStreamUrl.getCellData(indexTable); // get file path of selected item
|
|
||||||
|
|
||||||
for (FilmTabelDataType helpData : filmsList) {
|
if (currentTableFilm.getCached() || dbController.searchCache(getCurrentStreamUrl())) {
|
||||||
if (helpData.getStreamUrl().equals(streamUrl)) {
|
LOGGER.info("loading from cache: " + getCurrentTitle());
|
||||||
indexList = filmsList.indexOf(helpData);
|
dbController.readCache(getCurrentStreamUrl());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filmsList.get(indexList).getCached()) {
|
|
||||||
LOGGER.info("loading from cache: " + title);
|
|
||||||
dbController.readCache(streamUrl);
|
|
||||||
} else {
|
} else {
|
||||||
omdbAPIController = new OMDbAPIController(mainWindowController, dbController, main);
|
omdbAPIController = new OMDbAPIController(mainWindowController, dbController, main);
|
||||||
Thread omdbAPIThread = new Thread(omdbAPIController);
|
Thread omdbAPIThread = new Thread(omdbAPIController);
|
||||||
|
@ -520,15 +481,13 @@ public class MainWindowController {
|
||||||
|
|
||||||
// initialize UI elements
|
// initialize UI elements
|
||||||
private void initUI() {
|
private void initUI() {
|
||||||
debugBtn.setDisable(true); // debugging button for tests
|
|
||||||
debugBtn.setVisible(false);
|
|
||||||
|
|
||||||
versionLbl.setText("Version: " + version + " (Build: " + buildNumber + ")");
|
versionLbl.setText("Version: " + version + " (Build: " + buildNumber + ")");
|
||||||
fontsizeSlider.setValue(getSize());
|
fontsizeSlider.setValue(getFontSize());
|
||||||
colorPicker.setValue(Color.valueOf(getColor()));
|
colorPicker.setValue(Color.valueOf(getColor()));
|
||||||
|
|
||||||
updateBtn.setFont(Font.font("System", 12));
|
updateBtn.setFont(Font.font("System", 12));
|
||||||
autoUpdateToggleBtn.setSelected(isAutoUpdate());
|
autoUpdateToggleBtn.setSelected(isAutoUpdate());
|
||||||
|
autoplayToggleBtn.setSelected(isAutoplay());
|
||||||
languageChoisBox.setItems(languages);
|
languageChoisBox.setItems(languages);
|
||||||
branchChoisBox.setItems(branches);
|
branchChoisBox.setItems(branches);
|
||||||
|
|
||||||
|
@ -544,8 +503,15 @@ public class MainWindowController {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void playbtnclicked() {
|
private void playbtnclicked() {
|
||||||
// TODO rework when #19 is coming
|
if (currentTableFilm.getStreamUrl().contains("_rootNode")) {
|
||||||
|
LOGGER.info("rootNode found, getting last watched episode");
|
||||||
|
currentTableFilm = dbController.getLastWatchedEpisode(currentTableFilm.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSupportedFormat(currentTableFilm)) {
|
||||||
|
new Player(mainWindowController);
|
||||||
|
} else {
|
||||||
|
LOGGER.error("using fallback player!");
|
||||||
if (System.getProperty("os.name").contains("Linux")) {
|
if (System.getProperty("os.name").contains("Linux")) {
|
||||||
String line;
|
String line;
|
||||||
String output = "";
|
String output = "";
|
||||||
|
@ -562,30 +528,42 @@ public class MainWindowController {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
if (output.contains("which: no vlc") || output == "") {
|
if (output.contains("which: no vlc") || output == "") {
|
||||||
JFXInfoDialog vlcInfoDialog = new JFXInfoDialog("Info", vlcNotInstalled, dialogBtnStyle, 350, 200, main.getPane());
|
JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info", vlcNotInstalled, dialogBtnStyle, main.getPrimaryStage());
|
||||||
vlcInfoDialog.show();
|
vlcInfoAlert.showAndWait();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder
|
new ProcessBuilder("vlc", getCurrentStreamUrl()).start();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
showErrorMsg(errorPlay, 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")) {
|
} else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) {
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().open(new File(streamUrl));
|
Desktop.getDesktop().open(new File(getCurrentStreamUrl()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
showErrorMsg(errorPlay, e);
|
LOGGER.warn("An error has occurred while opening the file!", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
|
LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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"));
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void openfolderbtnclicked() {
|
private void openfolderbtnclicked() {
|
||||||
String dest = new File(streamUrl).getParentFile().getAbsolutePath();
|
String dest = new File(getCurrentStreamUrl()).getParentFile().getAbsolutePath();
|
||||||
if (!System.getProperty("os.name").contains("Linux")) {
|
if (!System.getProperty("os.name").contains("Linux")) {
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().open(new File(dest));
|
Desktop.getDesktop().open(new File(dest));
|
||||||
|
@ -609,8 +587,8 @@ public class MainWindowController {
|
||||||
private void aboutBtnAction() {
|
private void aboutBtnAction() {
|
||||||
String bodyText = "cemu_UI by @Seil0 \nVersion: " + version + " (Build: " + buildNumber + ") \""
|
String bodyText = "cemu_UI by @Seil0 \nVersion: " + version + " (Build: " + buildNumber + ") \""
|
||||||
+ versionName + "\" \n" + infoText;
|
+ versionName + "\" \n" + infoText;
|
||||||
JFXInfoDialog aboutDialog = new JFXInfoDialog("Project HomeFlix", bodyText, dialogBtnStyle, 350, 200, main.getPane());
|
JFXInfoAlert infoAlert = new JFXInfoAlert("Project HomeFlix", bodyText, dialogBtnStyle, main.getPrimaryStage());
|
||||||
aboutDialog.show();
|
infoAlert.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -625,17 +603,13 @@ public class MainWindowController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
private void debugBtnclicked(){
|
|
||||||
//for testing
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void addDirectoryBtnAction(){
|
private void addDirectoryBtnAction(){
|
||||||
File selectedFolder = directoryChooser.showDialog(null);
|
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||||
|
directoryChooser.setTitle(bundle.getString("addDirectory"));
|
||||||
|
File selectedFolder = directoryChooser.showDialog(main.getPrimaryStage());
|
||||||
if (selectedFolder != null && selectedFolder.exists()) {
|
if (selectedFolder != null && selectedFolder.exists()) {
|
||||||
addSource(selectedFolder.getPath(), "local");
|
mainWindowController.addSource(selectedFolder.getPath(), "local");
|
||||||
dbController.refreshDataBase();
|
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("The selected folder dosen't exist!");
|
LOGGER.error("The selected folder dosen't exist!");
|
||||||
}
|
}
|
||||||
|
@ -644,7 +618,7 @@ public class MainWindowController {
|
||||||
@FXML
|
@FXML
|
||||||
private void addStreamSourceBtnAction(){
|
private void addStreamSourceBtnAction(){
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
fileChooser.setTitle("Open Resource File");
|
fileChooser.setTitle("addStreamSource");
|
||||||
File selectedFile = fileChooser.showOpenDialog(main.getPrimaryStage());
|
File selectedFile = fileChooser.showOpenDialog(main.getPrimaryStage());
|
||||||
if (selectedFile != null && selectedFile.exists()) {
|
if (selectedFile != null && selectedFile.exists()) {
|
||||||
addSource(selectedFile.getPath(), "stream");
|
addSource(selectedFile.getPath(), "stream");
|
||||||
|
@ -670,7 +644,7 @@ public class MainWindowController {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void autoUpdateToggleBtnAction(){
|
private void autoUpdateToggleBtnAction(){
|
||||||
if (autoUpdate) {
|
if (isAutoUpdate()) {
|
||||||
setAutoUpdate(false);
|
setAutoUpdate(false);
|
||||||
} else {
|
} else {
|
||||||
setAutoUpdate(true);
|
setAutoUpdate(true);
|
||||||
|
@ -678,6 +652,16 @@ public class MainWindowController {
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private void autoplayToggleBtnAction(){
|
||||||
|
if (isAutoplay()) {
|
||||||
|
setAutoplay(false);
|
||||||
|
} else {
|
||||||
|
setAutoplay(true);
|
||||||
|
}
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
// refresh the selected child of the root node
|
// refresh the selected child of the root node
|
||||||
private void refreshTable() {
|
private void refreshTable() {
|
||||||
filmRoot.getChildren().get(indexTable).setValue(filmsList.get(indexList));
|
filmRoot.getChildren().get(indexTable).setValue(filmsList.get(indexList));
|
||||||
|
@ -686,32 +670,32 @@ public class MainWindowController {
|
||||||
/**
|
/**
|
||||||
* add data from films-list to films-table
|
* add data from films-list to films-table
|
||||||
*/
|
*/
|
||||||
public void addDataUI() {
|
public void addDataUI(ObservableList<FilmTabelDataType> elementsList) {
|
||||||
|
|
||||||
for (FilmTabelDataType element : filmsList) {
|
for (FilmTabelDataType element : elementsList) {
|
||||||
|
|
||||||
// only if the entry contains a season and a episode it's a valid series
|
// only if the entry contains a season and a episode it's a valid series
|
||||||
if (!element.getSeason().isEmpty() && !element.getEpisode().isEmpty()) {
|
if (!element.getSeason().isEmpty() && !element.getEpisode().isEmpty()) {
|
||||||
// System.out.println("Found Series: " + element.getTitle());
|
|
||||||
// check if there is a series node to add the item
|
// check if there is a series node to add the item
|
||||||
for (int i = 0; i < filmRoot.getChildren().size(); i++) {
|
for (int i = 0; i < filmRoot.getChildren().size(); i++) {
|
||||||
if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) {
|
if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) {
|
||||||
// System.out.println("Found a root node to add child");
|
// if a root node exists, add element as child
|
||||||
// System.out.println("Adding: " + element.getStreamUrl());
|
TreeItem<FilmTabelDataType> episodeNode = new TreeItem<>(new FilmTabelDataType(
|
||||||
TreeItem<FilmTabelDataType> episodeNode = new TreeItem<>(new FilmTabelDataType(element.getStreamUrl(),
|
element.getStreamUrl(), element.getTitle(), element.getSeason(), element.getEpisode(),
|
||||||
element.getTitle(), element.getSeason(), element.getEpisode(), element.getFavorite(),
|
element.getFavorite(), element.getCached(), element.getImage()));
|
||||||
element.getCached(), element.getImage()));
|
|
||||||
filmRoot.getChildren().get(i).getChildren().add(episodeNode);
|
filmRoot.getChildren().get(i).getChildren().add(episodeNode);
|
||||||
} else if (i == filmRoot.getChildren().size() - 1) {
|
} else if (filmRoot.getChildren().get(i).nextSibling() == null) {
|
||||||
// System.out.println("Create a root node to add child");
|
// if no root node exists, create one and add element as child
|
||||||
// System.out.println("Adding: " + element.getStreamUrl());
|
TreeItem<FilmTabelDataType> seriesRootNode = new TreeItem<>(new FilmTabelDataType(
|
||||||
TreeItem<FilmTabelDataType> seriesRootNode = new TreeItem<>(new FilmTabelDataType(element.getStreamUrl(),
|
element.getTitle() + "_rootNode", element.getTitle(), "", "", element.getFavorite(),
|
||||||
element.getTitle(), "", "", element.getFavorite(), element.getCached(), element.getImage()));
|
false, element.getImage()));
|
||||||
filmRoot.getChildren().add(seriesRootNode);
|
filmRoot.getChildren().add(seriesRootNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filmRoot.getChildren().add(new TreeItem<FilmTabelDataType>(element)); // add data to root-node
|
// if season and episode are empty, we can assume the object is a film
|
||||||
|
filmRoot.getChildren().add(new TreeItem<FilmTabelDataType>(element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -729,12 +713,17 @@ public class MainWindowController {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// read old array
|
// read old array
|
||||||
|
File oldSources = new File(main.getDirectory() + "/sources.json");
|
||||||
|
if (oldSources.exists()) {
|
||||||
newsources = Json.parse(new FileReader(main.getDirectory() + "/sources.json")).asArray();
|
newsources = Json.parse(new FileReader(main.getDirectory() + "/sources.json")).asArray();
|
||||||
|
} else {
|
||||||
|
newsources = Json.array();
|
||||||
|
}
|
||||||
|
|
||||||
// add new source
|
// add new source
|
||||||
Writer writer = new FileWriter(main.getDirectory() + "/sources.json");
|
|
||||||
source = Json.object().add("path", path).add("mode", mode);
|
source = Json.object().add("path", path).add("mode", mode);
|
||||||
newsources.add(source);
|
newsources.add(source);
|
||||||
|
Writer writer = new FileWriter(main.getDirectory() + "/sources.json");
|
||||||
newsources.writeTo(writer);
|
newsources.writeTo(writer);
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -742,23 +731,25 @@ public class MainWindowController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//set color of UI-Elements
|
/**
|
||||||
|
* set the color of the GUI-Elements
|
||||||
|
* if usedColor is less than checkColor set text fill white, else black
|
||||||
|
*/
|
||||||
private void applyColor() {
|
private void applyColor() {
|
||||||
String style = "-fx-background-color: #" + getColor() + ";";
|
String style = "-fx-background-color: #" + getColor() + ";";
|
||||||
String btnStyleBlack = "-fx-button-type: RAISED; -fx-background-color: #" + getColor() + "; -fx-text-fill: BLACK;";
|
String btnStyleBlack = "-fx-button-type: RAISED; -fx-background-color: #" + getColor() + "; -fx-text-fill: BLACK;";
|
||||||
String btnStyleWhite = "-fx-button-type: RAISED; -fx-background-color: #" + getColor() + "; -fx-text-fill: WHITE;";
|
String btnStyleWhite = "-fx-button-type: RAISED; -fx-background-color: #" + getColor() + "; -fx-text-fill: WHITE;";
|
||||||
BigInteger icolor = new BigInteger(getColor(), 16);
|
BigInteger usedColor = new BigInteger(getColor(), 16);
|
||||||
BigInteger ccolor = new BigInteger("78909cff", 16);
|
BigInteger checkColor = new BigInteger("78909cff", 16);
|
||||||
|
|
||||||
sideMenuVBox.setStyle(style);
|
sideMenuVBox.setStyle(style);
|
||||||
topHBox.setStyle(style);
|
topHBox.setStyle(style);
|
||||||
searchTextField.setFocusColor(Color.valueOf(getColor()));
|
searchTextField.setFocusColor(Color.valueOf(getColor()));
|
||||||
|
|
||||||
if (icolor.compareTo(ccolor) == -1) {
|
if (usedColor.compareTo(checkColor) == -1) {
|
||||||
dialogBtnStyle = btnStyleWhite;
|
dialogBtnStyle = btnStyleWhite;
|
||||||
settingsBtn.setStyle("-fx-text-fill: WHITE;");
|
settingsBtn.setStyle("-fx-text-fill: WHITE;");
|
||||||
aboutBtn.setStyle("-fx-text-fill: WHITE;");
|
aboutBtn.setStyle("-fx-text-fill: WHITE;");
|
||||||
debugBtn.setStyle("-fx-text-fill: WHITE;");
|
|
||||||
addDirectoryBtn.setStyle(btnStyleWhite);
|
addDirectoryBtn.setStyle(btnStyleWhite);
|
||||||
addStreamSourceBtn.setStyle(btnStyleWhite);
|
addStreamSourceBtn.setStyle(btnStyleWhite);
|
||||||
updateBtn.setStyle(btnStyleWhite);
|
updateBtn.setStyle(btnStyleWhite);
|
||||||
|
@ -774,7 +765,6 @@ public class MainWindowController {
|
||||||
dialogBtnStyle = btnStyleBlack;
|
dialogBtnStyle = btnStyleBlack;
|
||||||
settingsBtn.setStyle("-fx-text-fill: BLACK;");
|
settingsBtn.setStyle("-fx-text-fill: BLACK;");
|
||||||
aboutBtn.setStyle("-fx-text-fill: BLACK;");
|
aboutBtn.setStyle("-fx-text-fill: BLACK;");
|
||||||
debugBtn.setStyle("-fx-text-fill: BLACK;");
|
|
||||||
addDirectoryBtn.setStyle(btnStyleBlack);
|
addDirectoryBtn.setStyle(btnStyleBlack);
|
||||||
addStreamSourceBtn.setStyle(btnStyleBlack);
|
addStreamSourceBtn.setStyle(btnStyleBlack);
|
||||||
updateBtn.setStyle(btnStyleBlack);
|
updateBtn.setStyle(btnStyleBlack);
|
||||||
|
@ -806,6 +796,9 @@ public class MainWindowController {
|
||||||
translateTransition.play();
|
translateTransition.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the local based on the languageChoisBox selection
|
||||||
|
*/
|
||||||
void setLocalUI() {
|
void setLocalUI() {
|
||||||
switch (getLocal()) {
|
switch (getLocal()) {
|
||||||
case "en_US":
|
case "en_US":
|
||||||
|
@ -833,72 +826,45 @@ public class MainWindowController {
|
||||||
fontsizeLbl.setText(getBundle().getString("fontsizeLbl"));
|
fontsizeLbl.setText(getBundle().getString("fontsizeLbl"));
|
||||||
languageLbl.setText(getBundle().getString("languageLbl"));
|
languageLbl.setText(getBundle().getString("languageLbl"));
|
||||||
autoUpdateToggleBtn.setText(getBundle().getString("autoUpdate"));
|
autoUpdateToggleBtn.setText(getBundle().getString("autoUpdate"));
|
||||||
|
autoplayToggleBtn.setText(getBundle().getString("autoplay"));
|
||||||
branchLbl.setText(getBundle().getString("branchLbl"));
|
branchLbl.setText(getBundle().getString("branchLbl"));
|
||||||
columnStreamUrl.setText(getBundle().getString("columnStreamUrl"));
|
columnStreamUrl.setText(getBundle().getString("columnStreamUrl"));
|
||||||
columnTitle.setText(getBundle().getString("columnName"));
|
columnTitle.setText(getBundle().getString("columnName"));
|
||||||
columnSeason.setText(getBundle().getString("columnSeason"));
|
columnSeason.setText(getBundle().getString("columnSeason"));
|
||||||
columnEpisode.setText(getBundle().getString("columnEpisode"));
|
columnEpisode.setText(getBundle().getString("columnEpisode"));
|
||||||
columnFavorite.setText(getBundle().getString("columnFavorite"));
|
columnFavorite.setText(getBundle().getString("columnFavorite"));
|
||||||
errorPlay = getBundle().getString("errorPlay");
|
|
||||||
errorLoad = getBundle().getString("errorLoad");
|
errorLoad = getBundle().getString("errorLoad");
|
||||||
errorSave = getBundle().getString("errorSave");
|
errorSave = getBundle().getString("errorSave");
|
||||||
infoText = getBundle().getString("infoText");
|
infoText = getBundle().getString("infoText");
|
||||||
vlcNotInstalled = getBundle().getString("vlcNotInstalled");
|
vlcNotInstalled = getBundle().getString("vlcNotInstalled");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove after #19 has landed
|
/**
|
||||||
public void showErrorMsg(String msg, Exception exception) {
|
* save the configuration to the config.xml file
|
||||||
Alert alert = new Alert(AlertType.ERROR);
|
*/
|
||||||
alert.setTitle("Error");
|
|
||||||
alert.setHeaderText("");
|
|
||||||
alert.setContentText(msg);
|
|
||||||
alert.initOwner(main.getPrimaryStage());
|
|
||||||
|
|
||||||
// Create expandable Exception.
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
exception.printStackTrace(pw);
|
|
||||||
String exceptionText = sw.toString();
|
|
||||||
|
|
||||||
TextArea textArea = new TextArea(exceptionText);
|
|
||||||
textArea.setEditable(false);
|
|
||||||
textArea.setWrapText(true);
|
|
||||||
|
|
||||||
textArea.setMaxWidth(Double.MAX_VALUE);
|
|
||||||
textArea.setMaxHeight(Double.MAX_VALUE);
|
|
||||||
GridPane.setVgrow(textArea, Priority.ALWAYS);
|
|
||||||
GridPane.setHgrow(textArea, Priority.ALWAYS);
|
|
||||||
|
|
||||||
GridPane expContent = new GridPane();
|
|
||||||
expContent.setMaxWidth(Double.MAX_VALUE);
|
|
||||||
expContent.add(textArea, 0, 1);
|
|
||||||
|
|
||||||
// Set expandable Exception into the dialog pane.
|
|
||||||
alert.getDialogPane().setExpandableContent(expContent);
|
|
||||||
alert.showAndWait();
|
|
||||||
LOGGER.error("An error occurred", exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save settings
|
|
||||||
public void saveSettings() {
|
public void saveSettings() {
|
||||||
LOGGER.info("saving settings ...");
|
LOGGER.info("saving settings ...");
|
||||||
try {
|
try {
|
||||||
props.setProperty("color", getColor());
|
props.setProperty("color", getColor());
|
||||||
props.setProperty("autoUpdate", String.valueOf(isAutoUpdate()));
|
props.setProperty("autoUpdate", String.valueOf(isAutoUpdate()));
|
||||||
props.setProperty("useBeta", String.valueOf(isUseBeta()));
|
props.setProperty("useBeta", String.valueOf(isUseBeta()));
|
||||||
props.setProperty("size", getSize().toString());
|
props.setProperty("autoplay", String.valueOf(isAutoplay()));
|
||||||
|
props.setProperty("size", getFontSize().toString());
|
||||||
props.setProperty("local", getLocal());
|
props.setProperty("local", getLocal());
|
||||||
props.setProperty("ratingSortType", columnFavorite.getSortType().toString());
|
props.setProperty("ratingSortType", columnFavorite.getSortType().toString());
|
||||||
|
|
||||||
OutputStream outputStream = new FileOutputStream(main.getConfigFile()); // new output-stream
|
OutputStream outputStream = new FileOutputStream(main.getConfigFile()); // new output-stream
|
||||||
props.storeToXML(outputStream, "Project HomeFlix settings"); // writes new .xml
|
props.storeToXML(outputStream, "Project HomeFlix settings"); // write new .xml
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error(errorLoad, e);
|
LOGGER.error(errorLoad, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load settings
|
/**
|
||||||
|
* load the configuration from the config.xml file
|
||||||
|
* and try to load the API keys from apiKeys.json
|
||||||
|
*/
|
||||||
public void loadSettings() {
|
public void loadSettings() {
|
||||||
LOGGER.info("loading settings ...");
|
LOGGER.info("loading settings ...");
|
||||||
|
|
||||||
|
@ -914,10 +880,10 @@ public class MainWindowController {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setSize(Double.parseDouble(props.getProperty("size")));
|
setFontSize(Double.parseDouble(props.getProperty("size")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("cloud not load fontsize", e);
|
LOGGER.error("cloud not load fontsize", e);
|
||||||
setSize(17.0);
|
setFontSize(17.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -934,6 +900,13 @@ public class MainWindowController {
|
||||||
setUseBeta(false);
|
setUseBeta(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setAutoplay(Boolean.parseBoolean(props.getProperty("autoplay")));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("cloud not load autoplay", e);
|
||||||
|
setAutoplay(false);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setLocal(props.getProperty("local"));
|
setLocal(props.getProperty("local"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -941,13 +914,6 @@ public class MainWindowController {
|
||||||
setLocal(System.getProperty("user.language") + "_" + System.getProperty("user.country"));
|
setLocal(System.getProperty("user.language") + "_" + System.getProperty("user.country"));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
setRatingSortType(props.getProperty("ratingSortType"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("cloud not load autoUpdate", e);
|
|
||||||
setRatingSortType("");
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error(errorSave, e);
|
LOGGER.error(errorSave, e);
|
||||||
|
@ -956,9 +922,15 @@ public class MainWindowController {
|
||||||
// try loading the omdbAPI key
|
// try loading the omdbAPI key
|
||||||
try {
|
try {
|
||||||
InputStream in = getClass().getClassLoader().getResourceAsStream("apiKeys.json");
|
InputStream in = getClass().getClassLoader().getResourceAsStream("apiKeys.json");
|
||||||
|
if (in != null) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||||
JsonObject apiKeys = Json.parse(reader).asObject();
|
JsonObject apiKeys = Json.parse(reader).asObject();
|
||||||
omdbAPIKey = apiKeys.getString("omdbAPIKey", "");
|
omdbAPIKey = apiKeys.getString("omdbAPIKey", "");
|
||||||
|
reader.close();
|
||||||
|
in.close();
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Cloud not load apiKeys.json. No such file");
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("Cloud not load the omdbAPI key. Please contact the developer!", e);
|
LOGGER.error("Cloud not load the omdbAPI key. Please contact the developer!", e);
|
||||||
}
|
}
|
||||||
|
@ -1002,20 +974,24 @@ public class MainWindowController {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public FilmTabelDataType getCurrentTableFilm() {
|
||||||
return title;
|
return currentTableFilm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStreamUrl() {
|
public String getCurrentTitle() {
|
||||||
return streamUrl;
|
return currentTableFilm.getTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSize(Double input) {
|
public String getCurrentStreamUrl() {
|
||||||
this.size = input;
|
return currentTableFilm.getStreamUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getSize() {
|
public void setFontSize(Double input) {
|
||||||
return size;
|
this.fontSize = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getFontSize() {
|
||||||
|
return fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndexTable() {
|
public int getIndexTable() {
|
||||||
|
@ -1042,6 +1018,14 @@ public class MainWindowController {
|
||||||
this.useBeta = useBeta;
|
this.useBeta = useBeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAutoplay() {
|
||||||
|
return autoplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoplay(boolean autoplay) {
|
||||||
|
this.autoplay = autoplay;
|
||||||
|
}
|
||||||
|
|
||||||
public void setLocal(String input) {
|
public void setLocal(String input) {
|
||||||
this.local = input;
|
this.local = input;
|
||||||
}
|
}
|
||||||
|
@ -1062,14 +1046,6 @@ public class MainWindowController {
|
||||||
return sourcesList;
|
return sourcesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRatingSortType() {
|
|
||||||
return ratingSortType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRatingSortType(String ratingSortType) {
|
|
||||||
this.ratingSortType = ratingSortType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceBundle getBundle() {
|
public ResourceBundle getBundle() {
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.controller;
|
package kellerkinder.HomeFlix.controller;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URLConnection;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
@ -54,11 +54,6 @@ import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||||
|
|
||||||
public class DBController {
|
public class DBController {
|
||||||
|
|
||||||
public DBController(Main main, MainWindowController mainWindowController) {
|
|
||||||
this.main = main;
|
|
||||||
this.mainWindowController = mainWindowController;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MainWindowController mainWindowController;
|
private MainWindowController mainWindowController;
|
||||||
private Main main;
|
private Main main;
|
||||||
private String DB_PATH = System.getProperty("user.home") + "\\Documents\\HomeFlix" + "\\" + "Homeflix.db"; //path to database file
|
private String DB_PATH = System.getProperty("user.home") + "\\Documents\\HomeFlix" + "\\" + "Homeflix.db"; //path to database file
|
||||||
|
@ -71,6 +66,22 @@ public class DBController {
|
||||||
private Connection connection = null;
|
private Connection connection = null;
|
||||||
private static final Logger LOGGER = LogManager.getLogger(DBController.class.getName());
|
private static final Logger LOGGER = LogManager.getLogger(DBController.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for DBController
|
||||||
|
* @param main the Main object
|
||||||
|
* @param mainWindowController the MainWindowController object
|
||||||
|
*/
|
||||||
|
public DBController(Main main, MainWindowController mainWindowController) {
|
||||||
|
this.main = main;
|
||||||
|
this.mainWindowController = mainWindowController;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize the {@link DBController}
|
||||||
|
* initialize the database connection
|
||||||
|
* check if there is a need to create a new database
|
||||||
|
* refresh the database
|
||||||
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
LOGGER.info("<========== starting loading sql ==========>");
|
LOGGER.info("<========== starting loading sql ==========>");
|
||||||
initDatabaseConnection();
|
initDatabaseConnection();
|
||||||
|
@ -79,12 +90,16 @@ public class DBController {
|
||||||
LOGGER.info("<========== finished loading sql ==========>");
|
LOGGER.info("<========== finished loading sql ==========>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new connection to the HomeFlix.db database
|
||||||
|
* AutoCommit is set to false to prevent some issues, so manual commit is active!
|
||||||
|
*/
|
||||||
private void initDatabaseConnection() {
|
private void initDatabaseConnection() {
|
||||||
DB_PATH = main.getDirectory() + "/Homeflix.db";
|
DB_PATH = main.getDirectory() + "/Homeflix.db";
|
||||||
try {
|
try {
|
||||||
// create a database connection
|
// create a database connection
|
||||||
connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH);
|
connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH);
|
||||||
connection.setAutoCommit(false); //AutoCommit to false -> manual commit is active
|
connection.setAutoCommit(false);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
// if the error message is "out of memory", it probably means no database file is found
|
// if the error message is "out of memory", it probably means no database file is found
|
||||||
LOGGER.error("error while loading the ROM database", e);
|
LOGGER.error("error while loading the ROM database", e);
|
||||||
|
@ -94,12 +109,13 @@ public class DBController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if tables don't exist create them
|
* if tables don't exist create them
|
||||||
|
* films table: streamUrl is primary key
|
||||||
* cache table: streamUrl is primary key
|
* cache table: streamUrl is primary key
|
||||||
*/
|
*/
|
||||||
private void createDatabase() {
|
private void createDatabase() {
|
||||||
try {
|
try {
|
||||||
Statement stmt = connection.createStatement();
|
Statement stmt = connection.createStatement();
|
||||||
stmt.executeUpdate("create table if not exists films (streamUrl, title, season, episode, favorite, cached)");
|
stmt.executeUpdate("create table if not exists films (streamUrl, title, season, episode, favorite, cached, currentTime)");
|
||||||
stmt.executeUpdate("create table if not exists cache ("
|
stmt.executeUpdate("create table if not exists cache ("
|
||||||
+ "streamUrl, Title, Year, Rated, Released, Runtime, Genre, Director, Writer,"
|
+ "streamUrl, Title, Year, Rated, Released, Runtime, Genre, Director, Writer,"
|
||||||
+ " Actors, Plot, Language, Country, Awards, Metascore, imdbRating, imdbVotes,"
|
+ " Actors, Plot, Language, Country, Awards, Metascore, imdbRating, imdbVotes,"
|
||||||
|
@ -110,6 +126,9 @@ public class DBController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all database entries
|
||||||
|
*/
|
||||||
private void loadDatabase() {
|
private void loadDatabase() {
|
||||||
// get all entries from the table
|
// get all entries from the table
|
||||||
try {
|
try {
|
||||||
|
@ -131,7 +150,11 @@ public class DBController {
|
||||||
LOGGER.info("filme in db: " + filmsdbStreamURL.size());
|
LOGGER.info("filme in db: " + filmsdbStreamURL.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the sources from sources.json
|
/**
|
||||||
|
* load sources from sources.json
|
||||||
|
* if mode == local, get all files and series-folder from the directory
|
||||||
|
* else mode must be streaming, read all entries from the streaming file
|
||||||
|
*/
|
||||||
private void loadSources() {
|
private void loadSources() {
|
||||||
// remove sources from table
|
// remove sources from table
|
||||||
mainWindowController.getSourcesList().removeAll(mainWindowController.getSourcesList());
|
mainWindowController.getSourcesList().removeAll(mainWindowController.getSourcesList());
|
||||||
|
@ -145,10 +168,9 @@ public class DBController {
|
||||||
mainWindowController.addSourceToTable(path, mode); // add source to source-table
|
mainWindowController.addSourceToTable(path, mode); // add source to source-table
|
||||||
if (mode.equals("local")) {
|
if (mode.equals("local")) {
|
||||||
for (File file : new File(path).listFiles()) {
|
for (File file : new File(path).listFiles()) {
|
||||||
if (file.isFile()) {
|
if (file.isFile() && isVideoFile(file.getPath())) {
|
||||||
// get all files (films)
|
|
||||||
filmsStreamURL.add(file.getPath());
|
filmsStreamURL.add(file.getPath());
|
||||||
} else {
|
} else if(file.isDirectory()) {
|
||||||
// get all folders (series)
|
// get all folders (series)
|
||||||
for (File season : file.listFiles()) {
|
for (File season : file.listFiles()) {
|
||||||
if (season.isDirectory()) {
|
if (season.isDirectory()) {
|
||||||
|
@ -181,7 +203,10 @@ public class DBController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loading data from database to mainWindowController
|
/**
|
||||||
|
* load the data to the mainWindowController
|
||||||
|
* order entries by title
|
||||||
|
*/
|
||||||
private void loadDataToMWC() {
|
private void loadDataToMWC() {
|
||||||
LOGGER.info("loading data to mwc ...");
|
LOGGER.info("loading data to mwc ...");
|
||||||
try {
|
try {
|
||||||
|
@ -207,11 +232,11 @@ public class DBController {
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.info("loading data to the GUI ...");
|
LOGGER.info("loading data to the GUI ...");
|
||||||
mainWindowController.addDataUI();
|
mainWindowController.addDataUI(mainWindowController.getFilmsList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* refresh data in mainWindowController localFilms and streamingFilms
|
* refresh data in mainWindowController for one element
|
||||||
* @param streamUrl of the film
|
* @param streamUrl of the film
|
||||||
* @param index of the film in LocalFilms list
|
* @param index of the film in LocalFilms list
|
||||||
*/
|
*/
|
||||||
|
@ -221,6 +246,7 @@ public class DBController {
|
||||||
Statement stmt = connection.createStatement();
|
Statement stmt = connection.createStatement();
|
||||||
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE streamUrl = \"" + streamUrl + "\";");
|
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE streamUrl = \"" + streamUrl + "\";");
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
if (rs.getBoolean("favorite") == true) {
|
if (rs.getBoolean("favorite") == true) {
|
||||||
mainWindowController.getFilmsList().set(indexList, new FilmTabelDataType(rs.getString("streamUrl"),
|
mainWindowController.getFilmsList().set(indexList, new FilmTabelDataType(rs.getString("streamUrl"),
|
||||||
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
||||||
|
@ -230,7 +256,7 @@ public class DBController {
|
||||||
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
||||||
rs.getBoolean("cached"), new ImageView(favorite_border_black)));
|
rs.getBoolean("cached"), new ImageView(favorite_border_black)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -247,15 +273,14 @@ public class DBController {
|
||||||
LOGGER.info("refreshing the Database ...");
|
LOGGER.info("refreshing the Database ...");
|
||||||
|
|
||||||
// clean all ArraLists
|
// clean all ArraLists
|
||||||
filmsdbAll.removeAll(filmsdbAll);
|
filmsdbAll.clear();
|
||||||
filmsdbDir.removeAll(filmsdbDir);
|
filmsdbDir.clear();
|
||||||
filmsdbStreamURL.removeAll(filmsdbStreamURL);
|
filmsdbStreamURL.clear();
|
||||||
filmsStreamURL.removeAll(filmsStreamURL);
|
filmsStreamURL.clear();
|
||||||
|
|
||||||
loadSources(); // reload all sources
|
loadSources(); // reload all sources
|
||||||
loadDatabase(); // reload all films saved in the DB
|
loadDatabase(); // reload all films saved in the DB
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkAddEntry();
|
checkAddEntry();
|
||||||
checkRemoveEntry();
|
checkRemoveEntry();
|
||||||
|
@ -275,14 +300,12 @@ public class DBController {
|
||||||
*/
|
*/
|
||||||
private void checkRemoveEntry() {
|
private void checkRemoveEntry() {
|
||||||
LOGGER.info("checking for entrys to remove to DB ...");
|
LOGGER.info("checking for entrys to remove to DB ...");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement stmt = connection.createStatement();
|
Statement stmt = connection.createStatement();
|
||||||
|
|
||||||
for (String entry : filmsdbStreamURL) {
|
for (String entry : filmsdbStreamURL) {
|
||||||
|
// if the directory doen't contain the entry form the db, remove it
|
||||||
if (!filmsStreamURL.contains(entry)) {
|
if (!filmsStreamURL.contains(entry)) {
|
||||||
System.out.println(filmsdbStreamURL + "\n");
|
|
||||||
System.out.println(filmsStreamURL);
|
|
||||||
stmt.executeUpdate("delete from films where streamUrl = \"" + entry + "\"");
|
stmt.executeUpdate("delete from films where streamUrl = \"" + entry + "\"");
|
||||||
connection.commit();
|
connection.commit();
|
||||||
LOGGER.info("removed \"" + entry + "\" from database");
|
LOGGER.info("removed \"" + entry + "\" from database");
|
||||||
|
@ -303,7 +326,7 @@ public class DBController {
|
||||||
*/
|
*/
|
||||||
private void checkAddEntry() throws SQLException, FileNotFoundException, IOException {
|
private void checkAddEntry() throws SQLException, FileNotFoundException, IOException {
|
||||||
Statement stmt = connection.createStatement();
|
Statement stmt = connection.createStatement();
|
||||||
PreparedStatement ps = connection.prepareStatement("insert into films values (?, ?, ?, ?, ?, ?)");
|
PreparedStatement ps = connection.prepareStatement("insert into films values (?, ?, ?, ?, ?, ?, ?)");
|
||||||
LOGGER.info("checking for entrys to add to DB ...");
|
LOGGER.info("checking for entrys to add to DB ...");
|
||||||
|
|
||||||
// source is a single source of the sources list
|
// source is a single source of the sources list
|
||||||
|
@ -311,19 +334,20 @@ public class DBController {
|
||||||
// if it's a local source check the folder for new film
|
// if it's a local source check the folder for new film
|
||||||
if (source.getMode().equals("local")) {
|
if (source.getMode().equals("local")) {
|
||||||
for (File file : new File(source.getPath()).listFiles()) {
|
for (File file : new File(source.getPath()).listFiles()) {
|
||||||
|
String mimeType = URLConnection.guessContentTypeFromName(file.getPath());
|
||||||
if (file.isFile()) {
|
// if file is file and has mime type "video"
|
||||||
|
if (file.isFile() && mimeType != null && mimeType.contains("video")) {
|
||||||
// get all files (films)
|
// get all files (films)
|
||||||
if (!filmsdbStreamURL.contains(file.getPath())) {
|
if (!filmsdbStreamURL.contains(file.getPath())) {
|
||||||
stmt.executeUpdate("insert into films values ("
|
stmt.executeUpdate("insert into films values ("
|
||||||
+ "'" + file.getPath() + "',"
|
+ "'" + file.getPath() + "',"
|
||||||
+ "'" + cutOffEnd(file.getName()) + "', '', '', 0, 0)");
|
+ "'" + cutOffEnd(file.getName()) + "', '', '', 0, 0, 0.0)");
|
||||||
connection.commit();
|
connection.commit();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
LOGGER.info("Added \"" + file.getName() + "\" to database");
|
LOGGER.info("Added \"" + file.getName() + "\" to database");
|
||||||
filmsdbStreamURL.add(file.getPath());
|
filmsdbStreamURL.add(file.getPath());
|
||||||
}
|
}
|
||||||
} else {
|
} else if (file.isDirectory()) {
|
||||||
// get all folders (series)
|
// get all folders (series)
|
||||||
int sn = 1;
|
int sn = 1;
|
||||||
for (File season : file.listFiles()) {
|
for (File season : file.listFiles()) {
|
||||||
|
@ -333,8 +357,8 @@ public class DBController {
|
||||||
if (!filmsdbStreamURL.contains(episode.getPath())) {
|
if (!filmsdbStreamURL.contains(episode.getPath())) {
|
||||||
LOGGER.info("Added \"" + file.getName() + "\", Episode: " + episode.getName() + " to database");
|
LOGGER.info("Added \"" + file.getName() + "\", Episode: " + episode.getName() + " to database");
|
||||||
stmt.executeUpdate("insert into films values ("
|
stmt.executeUpdate("insert into films values ("
|
||||||
+ "'" + episode.getPath() + "',"
|
+ "'" + episode.getPath().replace("'", "''") + "',"
|
||||||
+ "'" + cutOffEnd(file.getName()) + "','" + sn + "','" + ep + "', 0, 0)");
|
+ "'" + cutOffEnd(file.getName()) + "','" + sn + "','" + ep + "', 0, 0, 0.0)");
|
||||||
connection.commit();
|
connection.commit();
|
||||||
stmt.close();
|
stmt.close();
|
||||||
filmsStreamURL.add(episode.getPath());
|
filmsStreamURL.add(episode.getPath());
|
||||||
|
@ -366,6 +390,7 @@ public class DBController {
|
||||||
ps.setString(4, item.asObject().getString("episode", ""));
|
ps.setString(4, item.asObject().getString("episode", ""));
|
||||||
ps.setInt(5, 0);
|
ps.setInt(5, 0);
|
||||||
ps.setBoolean(6, false);
|
ps.setBoolean(6, false);
|
||||||
|
ps.setDouble(7, 0);
|
||||||
ps.addBatch(); // adds the entry
|
ps.addBatch(); // adds the entry
|
||||||
LOGGER.info("Added \"" + title + "\" to database");
|
LOGGER.info("Added \"" + title + "\" to database");
|
||||||
filmsdbStreamURL.add(streamUrl);
|
filmsdbStreamURL.add(streamUrl);
|
||||||
|
@ -380,7 +405,10 @@ public class DBController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints all entries from the database to the console
|
/**
|
||||||
|
* DEBUG
|
||||||
|
* prints all entries from the database to the console
|
||||||
|
*/
|
||||||
public void printAllDBEntriesDEBUG() {
|
public void printAllDBEntriesDEBUG() {
|
||||||
System.out.println("Outputting all entries ... \n");
|
System.out.println("Outputting all entries ... \n");
|
||||||
try {
|
try {
|
||||||
|
@ -392,7 +420,8 @@ public class DBController {
|
||||||
System.out.println(rs.getString("season"));
|
System.out.println(rs.getString("season"));
|
||||||
System.out.println(rs.getString("episode"));
|
System.out.println(rs.getString("episode"));
|
||||||
System.out.println(rs.getString("rating"));
|
System.out.println(rs.getString("rating"));
|
||||||
System.out.println(rs.getString("cached") + "\n");
|
System.out.println(rs.getString("cached"));
|
||||||
|
System.out.println(rs.getString("currentTime") + "\n");
|
||||||
}
|
}
|
||||||
stmt.close();
|
stmt.close();
|
||||||
rs.close();
|
rs.close();
|
||||||
|
@ -513,19 +542,39 @@ public class DBController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if there is already a entry with the given streamUrl in the cache
|
||||||
|
* @param streamUrl URL of the element
|
||||||
|
* @return true if the element is already cached, else false
|
||||||
|
*/
|
||||||
|
public boolean searchCache(String streamUrl) {
|
||||||
|
boolean retValue = false;
|
||||||
|
try {
|
||||||
|
Statement stmt = connection.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT * FROM cache WHERE streamUrl = \"" + streamUrl + "\";");
|
||||||
|
retValue = rs.next();
|
||||||
|
rs.close();
|
||||||
|
stmt.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Ups! error while getting the current time!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the cached data to mwc's TextFlow
|
* sets the cached data to mwc's TextFlow
|
||||||
* @param streamUrl URL of the film
|
* @param streamUrl URL of the film
|
||||||
*/
|
*/
|
||||||
public void readCache(String streamUrl) {
|
public void readCache(String streamUrl) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Statement stmt = connection.createStatement();
|
Statement stmt = connection.createStatement();
|
||||||
ResultSet rs = stmt.executeQuery("SELECT * FROM cache WHERE streamUrl=\"" + streamUrl + "\";");
|
ResultSet rs = stmt.executeQuery("SELECT * FROM cache WHERE streamUrl=\"" + streamUrl + "\";");
|
||||||
ArrayList<Text> nameText = new ArrayList<Text>();
|
ArrayList<Text> nameText = new ArrayList<Text>();
|
||||||
ArrayList<Text> responseText = new ArrayList<Text>();
|
ArrayList<Text> responseText = new ArrayList<Text>();
|
||||||
String fontFamily = main.getFONT_FAMILY();
|
|
||||||
Image im;
|
Image im;
|
||||||
int fontSize = (int) Math.round(mainWindowController.size);
|
int fontSize = (int) Math.round(mainWindowController.getFontSize());
|
||||||
int j = 2;
|
int j = 2;
|
||||||
|
|
||||||
nameText.add(0, new Text(mainWindowController.getBundle().getString("title") + ": "));
|
nameText.add(0, new Text(mainWindowController.getBundle().getString("title") + ": "));
|
||||||
|
@ -549,6 +598,7 @@ public class DBController {
|
||||||
responseText.add(new Text(rs.getString(j) + "\n"));
|
responseText.add(new Text(rs.getString(j) + "\n"));
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
responseText.add(new Text(rs.getString(19) + "\n"));
|
responseText.add(new Text(rs.getString(19) + "\n"));
|
||||||
im = new Image(new File(rs.getString(20)).toURI().toString());
|
im = new Image(new File(rs.getString(20)).toURI().toString());
|
||||||
|
|
||||||
|
@ -556,8 +606,8 @@ public class DBController {
|
||||||
rs.close();
|
rs.close();
|
||||||
|
|
||||||
for (int i = 0; i < nameText.size(); i++) {
|
for (int i = 0; i < nameText.size(); i++) {
|
||||||
nameText.get(i).setFont(Font.font(fontFamily, FontWeight.BOLD, fontSize));
|
nameText.get(i).setFont(Font.font("System", FontWeight.BOLD, fontSize));
|
||||||
responseText.get(i).setFont(Font.font(fontFamily, fontSize));
|
responseText.get(i).setFont(Font.font("System", fontSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindowController.getTextFlow().getChildren().remove(0,
|
mainWindowController.getTextFlow().getChildren().remove(0,
|
||||||
|
@ -579,6 +629,154 @@ public class DBController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the currentTime in ms saved in the database
|
||||||
|
* @param streamUrl URL of the film
|
||||||
|
* @return {@link Double} currentTime in ms
|
||||||
|
*/
|
||||||
|
public double getCurrentTime(String streamUrl) {
|
||||||
|
LOGGER.info("currentTime: " + streamUrl);
|
||||||
|
double currentTime = 0;
|
||||||
|
try {
|
||||||
|
Statement stmt = connection.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE streamUrl = \"" + streamUrl + "\";");
|
||||||
|
currentTime = rs.getDouble("currentTime");
|
||||||
|
rs.close();
|
||||||
|
stmt.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Ups! error while getting the current time!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save the currentTime to the database
|
||||||
|
* @param streamUrl URL of the film
|
||||||
|
* @param currentTime currentTime in ms of the film
|
||||||
|
*/
|
||||||
|
public void setCurrentTime(String streamUrl, double currentTime) {
|
||||||
|
LOGGER.info("currentTime: " + streamUrl);
|
||||||
|
try {
|
||||||
|
Statement stmt = connection.createStatement();
|
||||||
|
stmt.executeUpdate("UPDATE films SET currentTime=" + currentTime + " WHERE streamUrl=\"" + streamUrl + "\";");
|
||||||
|
connection.commit();
|
||||||
|
stmt.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("Ups! an error occured!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the next episode of a
|
||||||
|
* @param title URL of the film
|
||||||
|
* @param nextEp number of the next episode
|
||||||
|
* @return {@link FilmTabelDataType} the next episode as object
|
||||||
|
*/
|
||||||
|
public FilmTabelDataType getNextEpisode(String title, int episode, int season) {
|
||||||
|
FilmTabelDataType nextFilm = null;
|
||||||
|
ResultSet rs;
|
||||||
|
int nextEpisode = 3000;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Statement stmt = connection.createStatement();
|
||||||
|
|
||||||
|
rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND season = \"" + season + "\";");
|
||||||
|
while(rs.next()) {
|
||||||
|
int rsEpisode = Integer.parseInt(rs.getString("episode"));
|
||||||
|
if (rsEpisode > episode && rsEpisode < nextEpisode) {
|
||||||
|
// fitting episode found in current season, if rsEpisode < nextEpisode -> nextEpisode = rsEpisode
|
||||||
|
nextEpisode = rsEpisode;
|
||||||
|
System.out.println("next episode is: " + nextEpisode);
|
||||||
|
// favorite image is black
|
||||||
|
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"),
|
||||||
|
rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
||||||
|
rs.getBoolean("cached"), new ImageView(favorite_black));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextFilm == null) {
|
||||||
|
int nextSeason = 3000;
|
||||||
|
System.out.println("searching next season");
|
||||||
|
rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\";");
|
||||||
|
while(rs.next()) {
|
||||||
|
int rsSeason = Integer.parseInt(rs.getString("season"));
|
||||||
|
if (rsSeason > season && rsSeason < nextSeason) {
|
||||||
|
nextSeason = rsSeason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextSeason != 3000) {
|
||||||
|
System.out.println("next season is: " + nextSeason);
|
||||||
|
rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND season = \"" + season + "\";");
|
||||||
|
while(rs.next()) {
|
||||||
|
int rsEpisode = Integer.parseInt(rs.getString("episode"));
|
||||||
|
if (rsEpisode > episode && rsEpisode < nextEpisode) {
|
||||||
|
// fitting episode found in current season, if rsEpisode < nextEpisode -> nextEpisode = rsEpisode
|
||||||
|
nextEpisode = rsEpisode;
|
||||||
|
System.out.println("next episode is: " + nextEpisode);
|
||||||
|
// favorite image is black
|
||||||
|
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"), rs.getString("title"),
|
||||||
|
rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
||||||
|
rs.getBoolean("cached"), new ImageView(favorite_black));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
stmt.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Ups! error while getting next episode!", e);
|
||||||
|
}
|
||||||
|
return nextFilm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** TODO check if we relay need to separate between favorites and none favorites
|
||||||
|
* get the last watched episode
|
||||||
|
* @param title the title of the series
|
||||||
|
* @return the last watched episode as {@link FilmTabelDataType} object
|
||||||
|
*/
|
||||||
|
public FilmTabelDataType getLastWatchedEpisode(String title) {
|
||||||
|
LOGGER.info("last watched episode of: " + title);
|
||||||
|
FilmTabelDataType nextFilm = null;
|
||||||
|
double lastCurrentTime = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Statement stmt = connection.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\";");
|
||||||
|
while (rs.next()) {
|
||||||
|
if (rs.getBoolean("favorite") == true) {
|
||||||
|
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"),
|
||||||
|
rs.getString("title"), rs.getString("season"), rs.getString("episode") ,rs.getBoolean("favorite"),
|
||||||
|
rs.getBoolean("cached"), new ImageView(favorite_black));
|
||||||
|
} else {
|
||||||
|
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"),
|
||||||
|
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
||||||
|
rs.getBoolean("cached"), new ImageView(favorite_border_black));
|
||||||
|
}
|
||||||
|
if (rs.getDouble("currentTime") > lastCurrentTime) {
|
||||||
|
lastCurrentTime = rs.getDouble("currentTime");
|
||||||
|
if (rs.getBoolean("favorite") == true) {
|
||||||
|
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"),
|
||||||
|
rs.getString("title"), rs.getString("season"), rs.getString("episode") ,rs.getBoolean("favorite"),
|
||||||
|
rs.getBoolean("cached"), new ImageView(favorite_black));
|
||||||
|
} else {
|
||||||
|
nextFilm = new FilmTabelDataType(rs.getString("streamUrl"),
|
||||||
|
rs.getString("title"), rs.getString("season"), rs.getString("episode"), rs.getBoolean("favorite"),
|
||||||
|
rs.getBoolean("cached"), new ImageView(favorite_border_black));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
stmt.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Ups! error while getting the last watched episode!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextFilm;
|
||||||
|
}
|
||||||
|
|
||||||
// removes the ending
|
// removes the ending
|
||||||
private String cutOffEnd(String str) {
|
private String cutOffEnd(String str) {
|
||||||
if (str == null) return null;
|
if (str == null) return null;
|
||||||
|
@ -587,4 +785,14 @@ public class DBController {
|
||||||
return str.substring(0, pos);
|
return str.substring(0, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if a file is a video
|
||||||
|
* @param path the path to the file
|
||||||
|
* @return true if the file is a video, else false
|
||||||
|
*/
|
||||||
|
public static boolean isVideoFile(String path) {
|
||||||
|
String mimeType = URLConnection.guessContentTypeFromName(path);
|
||||||
|
return mimeType != null && mimeType.startsWith("video");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.controller;
|
package kellerkinder.HomeFlix.controller;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
@ -35,6 +34,7 @@ import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import com.eclipsesource.json.Json;
|
import com.eclipsesource.json.Json;
|
||||||
import com.eclipsesource.json.JsonObject;
|
import com.eclipsesource.json.JsonObject;
|
||||||
|
import com.eclipsesource.json.JsonValue;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import kellerkinder.HomeFlix.application.Main;
|
import kellerkinder.HomeFlix.application.Main;
|
||||||
|
@ -49,6 +49,12 @@ public class OMDbAPIController implements Runnable {
|
||||||
private String URL = "https://www.omdbapi.com/?apikey=";
|
private String URL = "https://www.omdbapi.com/?apikey=";
|
||||||
private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName());
|
private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for the OMDbAPIController
|
||||||
|
* @param mainWindowController the MainWindowController object
|
||||||
|
* @param dbController the DBController object
|
||||||
|
* @param main the Main object
|
||||||
|
*/
|
||||||
public OMDbAPIController(MainWindowController mainWindowController, DBController dbController, Main main){
|
public OMDbAPIController(MainWindowController mainWindowController, DBController dbController, Main main){
|
||||||
this.mainWindowController = mainWindowController;
|
this.mainWindowController = mainWindowController;
|
||||||
this.dbController = dbController;
|
this.dbController = dbController;
|
||||||
|
@ -62,23 +68,61 @@ public class OMDbAPIController implements Runnable {
|
||||||
String output = null;
|
String output = null;
|
||||||
String posterPath = null;
|
String posterPath = null;
|
||||||
|
|
||||||
// get by title, TODO implement search
|
// get information by title
|
||||||
try {
|
try {
|
||||||
URL apiUrl = new URL(URL + mainWindowController.getOmdbAPIKey() + "&t="
|
URL apiUrl = new URL(URL + mainWindowController.getOmdbAPIKey() + "&t="
|
||||||
+ mainWindowController.getTitle().replace(" ", "%20"));
|
+ mainWindowController.getCurrentTitle().replace(" ", "%20"));
|
||||||
BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream()));
|
BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream()));
|
||||||
output = ina.readLine();
|
output = ina.readLine();
|
||||||
ina.close();
|
ina.close();
|
||||||
LOGGER.info("response from " + URL + " was valid");
|
System.out.println(apiUrl);
|
||||||
LOGGER.info(output);
|
LOGGER.info("response from '" + URL + "&t=" + mainWindowController.getCurrentTitle() + "' was:" + output);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error("error while making api request or reading response");
|
LOGGER.error("error while making api request or reading response");
|
||||||
LOGGER.error("response from " + URL + " was: \n" + output, e);
|
LOGGER.error("response from '" + URL + "&t=" + mainWindowController.getCurrentTitle() + "' was:" + output, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject object = Json.parse(output).asObject();
|
JsonObject object = Json.parse(output).asObject();
|
||||||
|
|
||||||
|
if (object.getString("Error", "").equals("Movie not found!")) {
|
||||||
|
// if the movie was not found try to search it
|
||||||
|
LOGGER.warn("Movie was not found at first try, searching again!");
|
||||||
|
/** TODO
|
||||||
|
* split the name intelligent as it may contain the film title
|
||||||
|
* search for English name
|
||||||
|
* use tmdb
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
URL apiUrl = new URL(URL + mainWindowController.getOmdbAPIKey() + "&s="
|
||||||
|
+ mainWindowController.getCurrentTitle().replace(" ", "%20"));
|
||||||
|
BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream()));
|
||||||
|
output = ina.readLine();
|
||||||
|
ina.close();
|
||||||
|
LOGGER.info("response from '" + URL + "&s=" + mainWindowController.getCurrentTitle() + "' was:" + output);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("error while making api request or reading response");
|
||||||
|
LOGGER.error("response from '" + URL + "&s=" + mainWindowController.getCurrentTitle() + "' was:" + output, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject searchObject = Json.parse(output).asObject();
|
||||||
|
if (searchObject.getString("Response", "").equals("True")) {
|
||||||
|
for (JsonValue movie : searchObject.get("Search").asArray()) {
|
||||||
|
// get first entry from the array and set object = movie
|
||||||
|
object = (JsonObject) movie;
|
||||||
|
System.out.println(movie.toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println(object.getString("Title", ""));
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Movie not found! Not adding cache!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the response to the responseString[]
|
||||||
responseString[0] = object.getString("Title", "");
|
responseString[0] = object.getString("Title", "");
|
||||||
responseString[1] = object.getString("Year", "");
|
responseString[1] = object.getString("Year", "");
|
||||||
responseString[2] = object.getString("Rated", "");
|
responseString[2] = object.getString("Rated", "");
|
||||||
|
@ -103,7 +147,7 @@ public class OMDbAPIController implements Runnable {
|
||||||
//resize the image to fit in the posterImageView and add it to the cache
|
//resize the image to fit in the posterImageView and add it to the cache
|
||||||
try {
|
try {
|
||||||
BufferedImage originalImage = ImageIO.read(new URL(responseString[18])); //change path to where file is located
|
BufferedImage originalImage = ImageIO.read(new URL(responseString[18])); //change path to where file is located
|
||||||
posterPath = main.getPosterCache() + "/" + mainWindowController.getTitle() + ".png";
|
posterPath = main.getPosterCache() + "/" + mainWindowController.getCurrentTitle() + ".png";
|
||||||
ImageIO.write(originalImage, "png", new File(posterPath));
|
ImageIO.write(originalImage, "png", new File(posterPath));
|
||||||
LOGGER.info("adding poster to cache: "+posterPath);
|
LOGGER.info("adding poster to cache: "+posterPath);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -111,16 +155,16 @@ public class OMDbAPIController implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding strings to the cache
|
// adding strings to the cache
|
||||||
dbController.addCache(mainWindowController.getStreamUrl(), responseString[0], responseString[1],
|
dbController.addCache(mainWindowController.getCurrentStreamUrl(), responseString[0], responseString[1],
|
||||||
responseString[2], responseString[3], responseString[4], responseString[5], responseString[6],
|
responseString[2], responseString[3], responseString[4], responseString[5], responseString[6],
|
||||||
responseString[7], responseString[8], responseString[9], responseString[10], responseString[11],
|
responseString[7], responseString[8], responseString[9], responseString[10], responseString[11],
|
||||||
responseString[12], responseString[13], responseString[14], responseString[15], responseString[16],
|
responseString[12], responseString[13], responseString[14], responseString[15], responseString[16],
|
||||||
responseString[17], posterPath, responseString[19]);
|
responseString[17], posterPath, responseString[19]);
|
||||||
dbController.setCached(mainWindowController.getStreamUrl());
|
dbController.setCached(mainWindowController.getCurrentStreamUrl());
|
||||||
|
|
||||||
// load data to the MainWindowController
|
// load data to the MainWindowController
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
dbController.readCache(mainWindowController.getStreamUrl());
|
dbController.readCache(mainWindowController.getCurrentStreamUrl());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.controller;
|
package kellerkinder.HomeFlix.controller;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -61,6 +60,9 @@ public class UpdateController implements Runnable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updater for Project HomeFlix based on cemu_UIs, checks for Updates and download it
|
* updater for Project HomeFlix based on cemu_UIs, checks for Updates and download it
|
||||||
|
* @param mwc the MainWindowController object
|
||||||
|
* @param buildNumber the buildNumber of the used HomeFlix version
|
||||||
|
* @param useBeta if the updater should query the beta channel
|
||||||
*/
|
*/
|
||||||
public UpdateController(MainWindowController mwc, String buildNumber, boolean useBeta) {
|
public UpdateController(MainWindowController mwc, String buildNumber, boolean useBeta) {
|
||||||
mainWindowController = mwc;
|
mainWindowController = mwc;
|
||||||
|
@ -149,8 +151,8 @@ public class UpdateController implements Runnable {
|
||||||
FileUtils.copyInputStreamToFile(pmis, new File("ProjectHomeFlix_update.jar")); // download update
|
FileUtils.copyInputStreamToFile(pmis, new File("ProjectHomeFlix_update.jar")); // download update
|
||||||
org.apache.commons.io.FileUtils.copyFile(new File("ProjectHomeFlix_update.jar"), new File("ProjectHomeFlix.jar"));
|
org.apache.commons.io.FileUtils.copyFile(new File("ProjectHomeFlix_update.jar"), new File("ProjectHomeFlix.jar"));
|
||||||
org.apache.commons.io.FileUtils.deleteQuietly(new File("ProjectHomeFlix_update.jar")); // delete update
|
org.apache.commons.io.FileUtils.deleteQuietly(new File("ProjectHomeFlix_update.jar")); // delete update
|
||||||
Runtime.getRuntime().exec("java -jar ProjectHomeFlix.jar"); // start again TODO consider ProcessBuilder to execute
|
new ProcessBuilder("java", "-jar", "ProjectHomeFlix.jar").start(); // start the new application
|
||||||
System.exit(0); // finishes itself
|
System.exit(0); // close the current application
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
LOGGER.info("could not download update files", e);
|
LOGGER.info("could not download update files", e);
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.datatypes;
|
package kellerkinder.HomeFlix.datatypes;
|
||||||
|
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
@ -37,7 +36,6 @@ public class FilmTabelDataType {
|
||||||
private final BooleanProperty cached = new SimpleBooleanProperty();
|
private final BooleanProperty cached = new SimpleBooleanProperty();
|
||||||
private final SimpleObjectProperty<ImageView> image = new SimpleObjectProperty<>();
|
private final SimpleObjectProperty<ImageView> image = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tableData is the data-type of tree-table-view
|
* tableData is the data-type of tree-table-view
|
||||||
* @param streamUrl the concrete path to the file or the URL
|
* @param streamUrl the concrete path to the file or the URL
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kellerkinder.HomeFlix.datatypes;
|
package kellerkinder.HomeFlix.datatypes;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* Project-HomeFlix
|
||||||
|
*
|
||||||
|
* Copyright 2016-2018 <@Seil0>
|
||||||
|
*
|
||||||
|
* 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.player;
|
||||||
|
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.WindowEvent;
|
||||||
|
import kellerkinder.HomeFlix.application.Main;
|
||||||
|
import kellerkinder.HomeFlix.application.MainWindowController;
|
||||||
|
|
||||||
|
public class Player {
|
||||||
|
|
||||||
|
private PlayerController playerController;
|
||||||
|
private Stage stage;
|
||||||
|
private AnchorPane pane;
|
||||||
|
private Scene scene;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate a new PlayerWindow
|
||||||
|
* @param mainWindowController the MainWindowController
|
||||||
|
*/
|
||||||
|
public Player(MainWindowController mainWindowController) {
|
||||||
|
try {
|
||||||
|
FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml"));
|
||||||
|
pane = (AnchorPane) fxmlLoader.load();
|
||||||
|
stage = new Stage();
|
||||||
|
scene = new Scene(pane);
|
||||||
|
stage.setScene(scene);
|
||||||
|
stage.setTitle("HomeFlix");
|
||||||
|
stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png")));
|
||||||
|
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
|
||||||
|
public void handle(WindowEvent we) {
|
||||||
|
mainWindowController.getDbController().setCurrentTime(mainWindowController.getCurrentStreamUrl(),
|
||||||
|
playerController.getCurrentTime());
|
||||||
|
playerController.getMediaPlayer().stop();
|
||||||
|
stage.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
playerController = fxmlLoader.getController();
|
||||||
|
playerController.init(mainWindowController, this, mainWindowController.getCurrentTableFilm());
|
||||||
|
|
||||||
|
stage.setFullScreen(true);
|
||||||
|
stage.show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stage getStage() {
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Parent getPane() {
|
||||||
|
return pane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scene getScene() {
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,276 @@
|
||||||
|
/**
|
||||||
|
* Project-HomeFlix
|
||||||
|
*
|
||||||
|
* Copyright 2016-2018 <@Seil0>
|
||||||
|
*
|
||||||
|
* 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.player;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXSlider;
|
||||||
|
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.property.DoubleProperty;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.Cursor;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.input.MouseEvent;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.media.Media;
|
||||||
|
import javafx.scene.media.MediaPlayer;
|
||||||
|
import javafx.scene.media.MediaPlayer.Status;
|
||||||
|
import javafx.scene.media.MediaView;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
import kellerkinder.HomeFlix.application.MainWindowController;
|
||||||
|
import kellerkinder.HomeFlix.datatypes.FilmTabelDataType;
|
||||||
|
|
||||||
|
public class PlayerController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private MediaView mediaView;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private VBox bottomVBox;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private HBox controlsHBox;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private JFXSlider timeSlider;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private JFXButton stopBtn;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private JFXButton playBtn;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private JFXButton fullscreenBtn;
|
||||||
|
|
||||||
|
private Player player;
|
||||||
|
private MainWindowController mainWCon;
|
||||||
|
private Media media;
|
||||||
|
private MediaPlayer mediaPlayer;
|
||||||
|
|
||||||
|
private FilmTabelDataType film;
|
||||||
|
private double currentTime = 0;
|
||||||
|
private double seekTime = 0;
|
||||||
|
private double startTime = 0;
|
||||||
|
private double duration = 0;
|
||||||
|
private boolean mousePressed = false;
|
||||||
|
private boolean showControls = true;
|
||||||
|
private boolean autoplay;
|
||||||
|
|
||||||
|
private ImageView stop_black = new ImageView(new Image("icons/ic_stop_black_24dp_1x.png"));
|
||||||
|
private ImageView play_arrow_black = new ImageView(new Image("icons/ic_play_arrow_black_24dp_1x.png"));
|
||||||
|
private ImageView pause_black = new ImageView(new Image("icons/ic_pause_black_24dp_1x.png"));
|
||||||
|
private ImageView fullscreen_black = new ImageView(new Image("icons/ic_fullscreen_black_24dp_1x.png"));
|
||||||
|
private ImageView fullscreen_exit_black = new ImageView(new Image("icons/ic_fullscreen_exit_black_24dp_1x.png"));
|
||||||
|
|
||||||
|
/** FIXME double set currentTime(
|
||||||
|
* initialize the new PlayerWindow
|
||||||
|
* @param entry the film object
|
||||||
|
* @param player the player object (needed for closing action)
|
||||||
|
* @param dbController the dbController object
|
||||||
|
*/
|
||||||
|
public void init(MainWindowController mainWCon, Player player, FilmTabelDataType film) {
|
||||||
|
this.mainWCon = mainWCon;
|
||||||
|
this.player = player;
|
||||||
|
this.film = film;
|
||||||
|
startTime = mainWCon.getDbController().getCurrentTime(film.getStreamUrl());
|
||||||
|
autoplay = mainWCon.isAutoplay();
|
||||||
|
initActions();
|
||||||
|
|
||||||
|
if (film.getStreamUrl().startsWith("http")) {
|
||||||
|
media = new Media(film.getStreamUrl());
|
||||||
|
} else {
|
||||||
|
media = new Media(new File(film.getStreamUrl()).toURI().toString());
|
||||||
|
}
|
||||||
|
startTime = mainWCon.getDbController().getCurrentTime(film.getStreamUrl());
|
||||||
|
autoplay = mainWCon.isAutoplay();
|
||||||
|
|
||||||
|
mediaPlayer = new MediaPlayer(media);
|
||||||
|
mediaView.setPreserveRatio(true);
|
||||||
|
mediaView.setMediaPlayer(mediaPlayer);
|
||||||
|
|
||||||
|
final DoubleProperty width = mediaView.fitWidthProperty();
|
||||||
|
final DoubleProperty height = mediaView.fitHeightProperty();
|
||||||
|
|
||||||
|
width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width"));
|
||||||
|
height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height"));
|
||||||
|
|
||||||
|
// start the media if the player is ready
|
||||||
|
mediaPlayer.setOnReady(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
duration = media.getDuration().toMillis();
|
||||||
|
|
||||||
|
timeSlider.setMax((duration / 1000) / 60);
|
||||||
|
|
||||||
|
mediaPlayer.play();
|
||||||
|
mediaPlayer.seek(Duration.millis(startTime));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// every time the play time changes execute this
|
||||||
|
mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
|
||||||
|
currentTime = newValue.toMillis(); // set the current time
|
||||||
|
int episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 0;
|
||||||
|
int season = !film.getSeason().isEmpty() ? Integer.parseInt(film.getSeason()) : 0;
|
||||||
|
|
||||||
|
// if we are end time -10 seconds, do autoplay, if activated
|
||||||
|
if ((duration - currentTime) < 10000 && episode != 0 && autoplay) {
|
||||||
|
autoplay = false;
|
||||||
|
mainWCon.getDbController().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
|
||||||
|
FilmTabelDataType nextFilm = mainWCon.getDbController().getNextEpisode(film.getTitle(), episode, season);
|
||||||
|
if (nextFilm != null) {
|
||||||
|
mediaPlayer.stop();
|
||||||
|
init(mainWCon, player, nextFilm);
|
||||||
|
autoplay = true;
|
||||||
|
}
|
||||||
|
} else if ((duration - currentTime) < 120) {
|
||||||
|
// if we are -20ms stop the media
|
||||||
|
mediaPlayer.stop();
|
||||||
|
mainWCon.getDbController().setCurrentTime(film.getStreamUrl(), 0); // reset old video start time
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mousePressed) {
|
||||||
|
timeSlider.setValue((currentTime / 1000) / 60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// set the control elements to the correct value
|
||||||
|
stopBtn.setGraphic(stop_black);
|
||||||
|
playBtn.setGraphic(pause_black);
|
||||||
|
fullscreenBtn.setGraphic(fullscreen_exit_black);
|
||||||
|
timeSlider.setValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize some PlayerWindow GUI-Elements actions
|
||||||
|
*/
|
||||||
|
private void initActions() {
|
||||||
|
|
||||||
|
player.getScene().addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler<MouseEvent>() {
|
||||||
|
// hide controls timer initialization
|
||||||
|
final Timer timer = new Timer();
|
||||||
|
TimerTask controlAnimationTask = null; // task to execute save operation
|
||||||
|
final long delayTime = 2000; // hide the controls after 2 seconds
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(MouseEvent mouseEvent) {
|
||||||
|
|
||||||
|
// show controls
|
||||||
|
if (!showControls) {
|
||||||
|
player.getScene().setCursor(Cursor.DEFAULT);
|
||||||
|
bottomVBox.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide controls
|
||||||
|
if (controlAnimationTask != null)
|
||||||
|
controlAnimationTask.cancel();
|
||||||
|
|
||||||
|
controlAnimationTask = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
bottomVBox.setVisible(false);
|
||||||
|
player.getScene().setCursor(Cursor.NONE);
|
||||||
|
showControls = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timer.schedule(controlAnimationTask, delayTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// if the mouse on the timeSlider is released seek to the new position
|
||||||
|
timeSlider.setOnMouseReleased(new EventHandler<MouseEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(MouseEvent event) {
|
||||||
|
mediaPlayer.seek(new Duration(seekTime));
|
||||||
|
mousePressed = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
timeSlider.setOnMousePressed(new EventHandler<MouseEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(MouseEvent event) {
|
||||||
|
mousePressed = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// get the new seek time
|
||||||
|
timeSlider.valueProperty().addListener(new ChangeListener<Number>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
|
||||||
|
seekTime = (double) new_val * 1000 * 60;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void stopBtnAction(ActionEvent event) {
|
||||||
|
mainWCon.getDbController().setCurrentTime(film.getStreamUrl(), currentTime);
|
||||||
|
mediaPlayer.stop();
|
||||||
|
player.getStage().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void fullscreenBtnAction(ActionEvent event) {
|
||||||
|
if (player.getStage().isFullScreen()) {
|
||||||
|
player.getStage().setFullScreen(false);
|
||||||
|
fullscreenBtn.setGraphic(fullscreen_black);
|
||||||
|
} else {
|
||||||
|
player.getStage().setFullScreen(true);
|
||||||
|
fullscreenBtn.setGraphic(fullscreen_exit_black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void playBtnAction(ActionEvent event) {
|
||||||
|
|
||||||
|
if (mediaPlayer.getStatus().equals(Status.PLAYING)) {
|
||||||
|
mediaPlayer.pause();
|
||||||
|
playBtn.setGraphic(play_arrow_black);
|
||||||
|
} else {
|
||||||
|
mediaPlayer.play();
|
||||||
|
playBtn.setGraphic(pause_black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaPlayer getMediaPlayer() {
|
||||||
|
return mediaPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCurrentTime() {
|
||||||
|
return currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/**
|
||||||
|
* Kellerkinder Framework Alerts
|
||||||
|
*
|
||||||
|
* Copyright 2018 <@Seil0>
|
||||||
|
*
|
||||||
|
* 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 org.kellerkinder.Alerts;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXAlert;
|
||||||
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXDialogLayout;
|
||||||
|
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class JFX2BtnCancelAlert {
|
||||||
|
|
||||||
|
private String headingText;
|
||||||
|
private String bodyText;
|
||||||
|
private String btnStyle;
|
||||||
|
private String btn1Text;
|
||||||
|
private String btn2Text;
|
||||||
|
private String cancelText;
|
||||||
|
private EventHandler<ActionEvent> btn1Action;
|
||||||
|
private EventHandler<ActionEvent> btn2Action;
|
||||||
|
private Stage stage;
|
||||||
|
private JFXAlert<Void> alert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new JFoenix Alert with 2 buttons and one cancel button
|
||||||
|
* @param titleText Title text of the alert
|
||||||
|
* @param headerText Heading text of the alert
|
||||||
|
* @param contentText Content text of the alert
|
||||||
|
* @param btnStyle Style of the okay button
|
||||||
|
* @param btn1Text btn1 text
|
||||||
|
* @param btn2Text btn2 text
|
||||||
|
* @param cancelText cancel button text
|
||||||
|
* @param stage stage to which the dialog belongs
|
||||||
|
*/
|
||||||
|
public JFX2BtnCancelAlert(String headingText, String bodyText, String btnStyle, String btn1Text, String btn2Text,
|
||||||
|
String cancelText, Stage stage) {
|
||||||
|
setHeadingText(headingText);
|
||||||
|
setBodyText(bodyText);
|
||||||
|
setBtnStyle(btnStyle);
|
||||||
|
setBtn1Text(btn1Text);
|
||||||
|
setBtn2Text(btn2Text);
|
||||||
|
setCancelText(cancelText);
|
||||||
|
setStage(stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JFX2BtnCancelAlert() {
|
||||||
|
// Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showAndWait() {
|
||||||
|
alert = new JFXAlert<>(stage);
|
||||||
|
|
||||||
|
JFXButton btnOne = new JFXButton();
|
||||||
|
|
||||||
|
btnOne.setText(btn1Text);
|
||||||
|
btnOne.setOnAction(btn1Action);
|
||||||
|
btnOne.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
||||||
|
btnOne.setPrefHeight(32);
|
||||||
|
btnOne.setStyle(btnStyle);
|
||||||
|
|
||||||
|
JFXButton btnTwo = new JFXButton();
|
||||||
|
btnTwo.setText(btn2Text);
|
||||||
|
btnTwo.setOnAction(btn2Action);
|
||||||
|
btnTwo.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
||||||
|
btnTwo.setPrefHeight(32);
|
||||||
|
btnTwo.setStyle(btnStyle);
|
||||||
|
|
||||||
|
JFXButton cancelBtn = new JFXButton();
|
||||||
|
cancelBtn.setText(cancelText);
|
||||||
|
cancelBtn.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event) {
|
||||||
|
alert.close();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
||||||
|
cancelBtn.setPrefHeight(32);
|
||||||
|
cancelBtn.setStyle(btnStyle);
|
||||||
|
|
||||||
|
JFXDialogLayout content = new JFXDialogLayout();
|
||||||
|
content.setActions(btnOne, btnTwo, cancelBtn);
|
||||||
|
content.setHeading(new Text(headingText));
|
||||||
|
content.setBody(new Text(bodyText));
|
||||||
|
alert.setContent(content);
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeadingText() {
|
||||||
|
return headingText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadingText(String headingText) {
|
||||||
|
this.headingText = headingText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBodyText() {
|
||||||
|
return bodyText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBodyText(String bodyText) {
|
||||||
|
this.bodyText = bodyText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBtnStyle() {
|
||||||
|
return btnStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtnStyle(String btnStyle) {
|
||||||
|
this.btnStyle = btnStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBtn1Text() {
|
||||||
|
return btn1Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtn1Text(String btn1Text) {
|
||||||
|
this.btn1Text = btn1Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBtn2Text() {
|
||||||
|
return btn2Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtn2Text(String btn2Text) {
|
||||||
|
this.btn2Text = btn2Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCancelText() {
|
||||||
|
return cancelText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCancelText(String cancelText) {
|
||||||
|
this.cancelText = cancelText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventHandler<ActionEvent> getBtn1Action() {
|
||||||
|
return btn1Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtn1Action(EventHandler<ActionEvent> btn1Action) {
|
||||||
|
this.btn1Action = btn1Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventHandler<ActionEvent> getBtn2Action() {
|
||||||
|
return btn2Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtn2Action(EventHandler<ActionEvent> btn2Action) {
|
||||||
|
this.btn2Action = btn2Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stage getStage() {
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStage(Stage stage) {
|
||||||
|
this.stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JFXAlert<Void> getAlert() {
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlert(JFXAlert<Void> alert) {
|
||||||
|
this.alert = alert;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* cemu_UI
|
* Kellerkinder Framework Alerts
|
||||||
*
|
*
|
||||||
* Copyright 2017 <@Seil0>
|
* Copyright 2018 <@Seil0>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,69 +18,94 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
package org.kellerkinder.Alerts;
|
||||||
|
|
||||||
package com.cemu_UI.uiElements;
|
import com.jfoenix.controls.JFXAlert;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import com.jfoenix.controls.JFXDialog;
|
|
||||||
import com.jfoenix.controls.JFXDialogLayout;
|
import com.jfoenix.controls.JFXDialogLayout;
|
||||||
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.layout.AnchorPane;
|
|
||||||
import javafx.scene.layout.Pane;
|
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class JFXInfoDialog {
|
public class JFXInfoAlert {
|
||||||
|
|
||||||
private String headingText;
|
private String headingText;
|
||||||
private String bodyText;
|
private String bodyText;
|
||||||
private String dialogBtnStyle;
|
private String btnStyle;
|
||||||
private int dialogWidth;
|
private Stage stage;
|
||||||
private int dialogHeight;
|
|
||||||
private Pane pane;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new JFoenix Dialog to show some information
|
* Creates a new JFoenix Alert to show some information
|
||||||
* @param headingText Heading Text, just the heading
|
* @param headerText Heading text of the alert
|
||||||
* @param bodyText body Text, all other text belongs here
|
* @param bodyText Content text of the alert
|
||||||
* @param dialogBtnStyle Style of the okay button
|
* @param btnStyle Style of the okay button
|
||||||
* @param dialogWidth dialog width
|
* @param stage stage to which the dialog belongs
|
||||||
* @param dialogHeight dialog height
|
|
||||||
* @param pane pane to which the dialog belongs
|
|
||||||
*/
|
*/
|
||||||
public JFXInfoDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth, int dialogHeight, Pane pane) {
|
public JFXInfoAlert(String headingText, String bodyText, String btnStyle, Stage stage) {
|
||||||
this.headingText = headingText;
|
setHeadingText(headingText);
|
||||||
this.bodyText = bodyText;
|
setBodyText(bodyText);
|
||||||
this.dialogBtnStyle = dialogBtnStyle;
|
setBtnStyle(btnStyle);
|
||||||
this.dialogWidth = dialogWidth;
|
setStage(stage);
|
||||||
this.dialogHeight = dialogHeight;
|
|
||||||
this.pane = pane;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public JFXInfoAlert() {
|
||||||
JFXDialogLayout content = new JFXDialogLayout();
|
// Auto-generated constructor stub
|
||||||
content.setHeading(new Text(headingText));
|
}
|
||||||
content.setBody(new Text(bodyText));
|
|
||||||
content.setPrefSize(dialogWidth, dialogHeight);
|
public void showAndWait( ) {
|
||||||
StackPane stackPane = new StackPane();
|
JFXAlert<Void> alert = new JFXAlert<>(stage);
|
||||||
stackPane.autosize();
|
|
||||||
JFXDialog dialog = new JFXDialog(stackPane, content, JFXDialog.DialogTransition.LEFT, true);
|
|
||||||
JFXButton button = new JFXButton("Okay");
|
JFXButton button = new JFXButton("Okay");
|
||||||
button.setOnAction(new EventHandler<ActionEvent>() {
|
button.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(ActionEvent event) {
|
public void handle(ActionEvent event) {
|
||||||
dialog.close();
|
alert.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
button.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
button.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
|
||||||
button.setPrefHeight(32);
|
button.setPrefHeight(32);
|
||||||
button.setStyle(dialogBtnStyle);
|
button.setStyle(btnStyle);
|
||||||
|
|
||||||
|
JFXDialogLayout content = new JFXDialogLayout();
|
||||||
content.setActions(button);
|
content.setActions(button);
|
||||||
pane.getChildren().add(stackPane);
|
content.setHeading(new Text(headingText));
|
||||||
AnchorPane.setTopAnchor(stackPane, (pane.getHeight() - content.getPrefHeight()) / 2);
|
content.setBody(new Text(bodyText));
|
||||||
AnchorPane.setLeftAnchor(stackPane, (pane.getWidth() - content.getPrefWidth()) / 2);
|
alert.setContent(content);
|
||||||
dialog.show();
|
alert.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHeadingText() {
|
||||||
|
return headingText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadingText(String headingText) {
|
||||||
|
this.headingText = headingText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBodyText() {
|
||||||
|
return bodyText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBodyText(String bodyText) {
|
||||||
|
this.bodyText = bodyText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBtnStyle() {
|
||||||
|
return btnStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBtnStyle(String btnStyle) {
|
||||||
|
this.btnStyle = btnStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stage getStage() {
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStage(Stage stage) {
|
||||||
|
this.stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,60 +22,40 @@
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
<?import javafx.scene.text.TextFlow?>
|
<?import javafx.scene.text.TextFlow?>
|
||||||
|
|
||||||
<AnchorPane fx:id="mainAnchorPane" prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.MainWindowController">
|
<AnchorPane fx:id="mainAnchorPane" prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.application.MainWindowController">
|
||||||
<children>
|
<children>
|
||||||
<ScrollPane fx:id="textScrollPane" fitToWidth="true" layoutX="408.0" layoutY="44.0" prefHeight="544.0" prefWidth="320.0" AnchorPane.bottomAnchor="12.0" AnchorPane.rightAnchor="222.0" AnchorPane.topAnchor="44.0">
|
<AnchorPane fx:id="tableModeAnchorPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="32.0">
|
||||||
|
<children>
|
||||||
|
<JFXTextField fx:id="searchTextField" maxWidth="-Infinity" minWidth="420.0" prefHeight="31.0" promptText="search ..." AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="568.0" AnchorPane.topAnchor="12.0">
|
||||||
|
<font>
|
||||||
|
<Font name="Arial" size="12.0" />
|
||||||
|
</font>
|
||||||
|
</JFXTextField>
|
||||||
|
<TreeTableView fx:id="filmsTreeTable" prefHeight="500.0" prefWidth="420.0" AnchorPane.bottomAnchor="12.0" AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="568.0" AnchorPane.topAnchor="56.0" />
|
||||||
|
<ScrollPane fx:id="textScrollPane" fitToWidth="true" prefHeight="544.0" prefWidth="320.0" AnchorPane.bottomAnchor="12.0" AnchorPane.rightAnchor="222.0" AnchorPane.topAnchor="12.0">
|
||||||
<content>
|
<content>
|
||||||
<TextFlow fx:id="textFlow" accessibleRole="TEXT_AREA" maxHeight="544.0" maxWidth="320.0" visible="true" />
|
<TextFlow fx:id="textFlow" accessibleRole="TEXT_AREA" maxHeight="544.0" maxWidth="320.0" visible="true" />
|
||||||
</content>
|
</content>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
<TreeTableView fx:id="filmsTreeTable" layoutX="14.0" layoutY="88.0" prefHeight="500.0" prefWidth="420.0" AnchorPane.bottomAnchor="12.0" AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="568.0" AnchorPane.topAnchor="88.0" />
|
<ImageView fx:id="posterImageView" fitHeight="297.0" fitWidth="198.0" pickOnBounds="true" preserveRatio="true" AnchorPane.rightAnchor="12.0" AnchorPane.topAnchor="12.0">
|
||||||
<JFXButton fx:id="playbtn" contentDisplay="CENTER" layoutX="690.0" layoutY="363.0" onAction="#playbtnclicked" prefHeight="25.0" prefWidth="198.0" AnchorPane.bottomAnchor="212.0" AnchorPane.rightAnchor="12.0">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="14.0" />
|
|
||||||
</font></JFXButton>
|
|
||||||
<JFXButton fx:id="openfolderbtn" layoutX="690.0" layoutY="404.0" onAction="#openfolderbtnclicked" prefHeight="25.0" prefWidth="198.0" text="open Folder" AnchorPane.bottomAnchor="171.0" AnchorPane.rightAnchor="12.0">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="14.0" />
|
|
||||||
</font></JFXButton>
|
|
||||||
<JFXTextField fx:id="searchTextField" layoutX="12.0" layoutY="44.0" maxWidth="-Infinity" minWidth="420.0" prefHeight="31.0" promptText="search ..." AnchorPane.leftAnchor="12.0" AnchorPane.rightAnchor="568.0" AnchorPane.topAnchor="44.0">
|
|
||||||
<font>
|
|
||||||
<Font name="Arial" size="12.0" />
|
|
||||||
</font></JFXTextField>
|
|
||||||
<ImageView fx:id="posterImageView" fitHeight="297.0" fitWidth="198.0" layoutX="481.0" layoutY="46.0" pickOnBounds="true" preserveRatio="true" AnchorPane.rightAnchor="12.0" AnchorPane.topAnchor="44.0">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/Homeflix_Poster.png" />
|
<Image url="@../icons/Homeflix_Poster.png" />
|
||||||
</image></ImageView>
|
</image>
|
||||||
<JFXButton fx:id="returnBtn" contentDisplay="CENTER" layoutX="690.0" layoutY="443.0" onAction="#returnBtnclicked" prefHeight="25.0" prefWidth="90.0" AnchorPane.bottomAnchor="132.0" AnchorPane.rightAnchor="120.0" />
|
</ImageView>
|
||||||
<JFXButton fx:id="forwardBtn" contentDisplay="CENTER" layoutX="798.0" layoutY="443.0" onAction="#forwardBtnclicked" prefHeight="25.0" prefWidth="90.0" AnchorPane.bottomAnchor="132.0" AnchorPane.rightAnchor="12.0" />
|
<JFXButton fx:id="playbtn" contentDisplay="CENTER" onAction="#playbtnclicked" prefHeight="25.0" prefWidth="198.0" AnchorPane.bottomAnchor="212.0" AnchorPane.rightAnchor="12.0">
|
||||||
<HBox fx:id="topHBox" layoutY="12.0" prefHeight="32.0" prefWidth="900.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<font>
|
||||||
<children>
|
<Font name="System Bold" size="14.0" />
|
||||||
<JFXHamburger fx:id="menuHam">
|
</font>
|
||||||
<padding>
|
</JFXButton>
|
||||||
<Insets left="3.0" />
|
<JFXButton fx:id="openfolderbtn" onAction="#openfolderbtnclicked" prefHeight="25.0" prefWidth="198.0" text="open Folder" AnchorPane.bottomAnchor="171.0" AnchorPane.rightAnchor="12.0">
|
||||||
</padding>
|
<font>
|
||||||
</JFXHamburger>
|
<Font name="System Bold" size="14.0" />
|
||||||
|
</font>
|
||||||
|
</JFXButton>
|
||||||
|
<JFXButton fx:id="returnBtn" contentDisplay="CENTER" onAction="#returnBtnclicked" prefHeight="25.0" prefWidth="90.0" AnchorPane.bottomAnchor="132.0" AnchorPane.rightAnchor="120.0" />
|
||||||
|
<JFXButton fx:id="forwardBtn" contentDisplay="CENTER" onAction="#forwardBtnclicked" prefHeight="25.0" prefWidth="90.0" AnchorPane.bottomAnchor="132.0" AnchorPane.rightAnchor="12.0" />
|
||||||
</children>
|
</children>
|
||||||
</HBox>
|
</AnchorPane>
|
||||||
<VBox fx:id="sideMenuVBox" layoutY="32.0" prefHeight="660.0" prefWidth="150.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="32.0">
|
|
||||||
<children>
|
|
||||||
<JFXButton fx:id="aboutBtn" onAction="#aboutBtnAction" prefHeight="32.0" prefWidth="150.0" textAlignment="CENTER">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="15.0" />
|
|
||||||
</font>
|
|
||||||
</JFXButton>
|
|
||||||
<JFXButton fx:id="settingsBtn" onAction="#settingsBtnclicked" prefHeight="37.0" prefWidth="150.0" textAlignment="CENTER">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="15.0" />
|
|
||||||
</font>
|
|
||||||
</JFXButton>
|
|
||||||
<JFXButton fx:id="debugBtn" onAction="#debugBtnclicked" prefHeight="32.0" prefWidth="150.0" text="debugging" textAlignment="CENTER">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="15.0" />
|
|
||||||
</font>
|
|
||||||
</JFXButton>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
<ScrollPane fx:id="settingsScrollPane" prefHeight="568.0" prefWidth="800.0" style="-fx-background: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="32.0">
|
<ScrollPane fx:id="settingsScrollPane" prefHeight="568.0" prefWidth="800.0" style="-fx-background: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="32.0">
|
||||||
<content>
|
<content>
|
||||||
<AnchorPane fx:id="settingsAnchorPane" style="-fx-background-color: white;">
|
<AnchorPane fx:id="settingsAnchorPane" style="-fx-background-color: white;">
|
||||||
|
@ -139,10 +119,26 @@
|
||||||
<ChoiceBox fx:id="branchChoisBox" prefWidth="150.0" />
|
<ChoiceBox fx:id="branchChoisBox" prefWidth="150.0" />
|
||||||
</children>
|
</children>
|
||||||
</HBox>
|
</HBox>
|
||||||
<JFXToggleButton fx:id="autoUpdateToggleBtn" onAction="#autoUpdateToggleBtnAction" text="check for updates on startup" />
|
<JFXToggleButton fx:id="autoUpdateToggleBtn" onAction="#autoUpdateToggleBtnAction" text="check for updates on startup">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="-5.0" top="-5.0" />
|
||||||
|
</padding></JFXToggleButton>
|
||||||
|
<Label fx:id="versionLbl" text="Version" />
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<VBox spacing="10.0">
|
||||||
|
<children>
|
||||||
|
<Label fx:id="PlayerLbl" text="Player" />
|
||||||
|
<JFXToggleButton fx:id="autoplayToggleBtn" onAction="#autoplayToggleBtnAction" text="autoplay">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets />
|
||||||
|
</VBox.margin>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="-5.0" top="-5.0" />
|
||||||
|
</padding>
|
||||||
|
</JFXToggleButton>
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
<Label fx:id="versionLbl" text="Version" />
|
|
||||||
<VBox spacing="10.0">
|
<VBox spacing="10.0">
|
||||||
<children>
|
<children>
|
||||||
<Label fx:id="sourcesLbl" text="Sources" />
|
<Label fx:id="sourcesLbl" text="Sources" />
|
||||||
|
@ -173,5 +169,28 @@
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
</content>
|
</content>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
|
<HBox fx:id="topHBox" layoutY="12.0" prefHeight="32.0" prefWidth="900.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
|
<children>
|
||||||
|
<JFXHamburger fx:id="menuHam">
|
||||||
|
<padding>
|
||||||
|
<Insets left="3.0" />
|
||||||
|
</padding>
|
||||||
|
</JFXHamburger>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<VBox fx:id="sideMenuVBox" layoutY="32.0" prefHeight="660.0" prefWidth="150.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="32.0">
|
||||||
|
<children>
|
||||||
|
<JFXButton fx:id="aboutBtn" onAction="#aboutBtnAction" prefHeight="32.0" prefWidth="150.0" textAlignment="CENTER">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="15.0" />
|
||||||
|
</font>
|
||||||
|
</JFXButton>
|
||||||
|
<JFXButton fx:id="settingsBtn" onAction="#settingsBtnclicked" prefHeight="37.0" prefWidth="150.0" textAlignment="CENTER">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="15.0" />
|
||||||
|
</font>
|
||||||
|
</JFXButton>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import com.jfoenix.controls.JFXButton?>
|
||||||
|
<?import com.jfoenix.controls.JFXSlider?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.media.MediaView?>
|
||||||
|
|
||||||
|
<AnchorPane prefHeight="720.0" prefWidth="1280.0" style="-fx-background-color: black;" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kellerkinder.HomeFlix.player.PlayerController">
|
||||||
|
<children>
|
||||||
|
<HBox alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
|
<children>
|
||||||
|
<MediaView fx:id="mediaView" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<VBox fx:id="bottomVBox" alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
|
||||||
|
<children>
|
||||||
|
<JFXSlider fx:id="timeSlider">
|
||||||
|
<padding>
|
||||||
|
<Insets left="5.0" right="5.0" />
|
||||||
|
</padding>
|
||||||
|
</JFXSlider>
|
||||||
|
<HBox fx:id="controlsHBox" alignment="CENTER" spacing="10.0">
|
||||||
|
<children>
|
||||||
|
<JFXButton fx:id="stopBtn" buttonType="RAISED" onAction="#stopBtnAction" prefHeight="39.0" style="-fx-background-color: white;" />
|
||||||
|
<JFXButton fx:id="playBtn" buttonType="RAISED" onAction="#playBtnAction" prefHeight="39.0" style="-fx-background-color: white;" />
|
||||||
|
<JFXButton fx:id="fullscreenBtn" buttonType="RAISED" onAction="#fullscreenBtnAction" prefHeight="39.0" style="-fx-background-color: white;" />
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="5.0" top="5.0" />
|
||||||
|
</padding>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
</AnchorPane>
|
After Width: | Height: | Size: 90 B |
After Width: | Height: | Size: 93 B |
After Width: | Height: | Size: 81 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 82 B |
|
@ -20,6 +20,7 @@ updateBtnChecking = Es wird nach Updates gesucht...
|
||||||
updateBtnUpdateAvailable = Update verf\u00FCgbar
|
updateBtnUpdateAvailable = Update verf\u00FCgbar
|
||||||
updateBtnNoUpdateAvailable = Kein Update verf\u00FCgbar
|
updateBtnNoUpdateAvailable = Kein Update verf\u00FCgbar
|
||||||
autoUpdate = beim Start nach Updates suchen:
|
autoUpdate = beim Start nach Updates suchen:
|
||||||
|
autoplay = autoplay
|
||||||
branchLbl = Updatezweig
|
branchLbl = Updatezweig
|
||||||
|
|
||||||
#column translations
|
#column translations
|
||||||
|
@ -32,7 +33,6 @@ columnFavorite = Favorit
|
||||||
#error translations
|
#error translations
|
||||||
errorUpdateV = Beim ausf\u00FChren des Updates ist ein Fehler aufgetreten! \nError: could not check update version (nvc)\nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
errorUpdateV = Beim ausf\u00FChren des Updates ist ein Fehler aufgetreten! \nError: could not check update version (nvc)\nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
||||||
errorUpdateD = Beim ausf\u00FChren des Updates ist ein Fehler aufgetreten! \nError: could not download update files (ndf)\nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
errorUpdateD = Beim ausf\u00FChren des Updates ist ein Fehler aufgetreten! \nError: could not download update files (ndf)\nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
||||||
errorPlay = Beim \u00F6ffnen der Datei ist ein Fehler aufgetreten! \nError: could not open file (nof) \nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
|
||||||
errorMode = Oh, da lief etwas falsch! Da hat jemand einen falschen Modus verwendet. \nError: mode unknow (muk)\nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
errorMode = Oh, da lief etwas falsch! Da hat jemand einen falschen Modus verwendet. \nError: mode unknow (muk)\nWeitere Hilfe erhalten sie unter www.kellerkinder.xyz \noder wenden sie sich an support@kellerkinder.xyz
|
||||||
errorOpenStream = Beim \u00F6ffnen des Streams ist ein Fehler aufgetreten!
|
errorOpenStream = Beim \u00F6ffnen des Streams ist ein Fehler aufgetreten!
|
||||||
errorLoad = Beim laden der Einstellungen ist ein Fehler aufgetreten!
|
errorLoad = Beim laden der Einstellungen ist ein Fehler aufgetreten!
|
||||||
|
@ -59,5 +59,7 @@ metascore = Metascore
|
||||||
imdbRating = IMDB-Bewertung
|
imdbRating = IMDB-Bewertung
|
||||||
type = Type
|
type = Type
|
||||||
|
|
||||||
firstStartHeader = Es ist kein Stammverzeichnis f\u00FCr Filme angegeben!
|
#first start
|
||||||
firstStartContent = Stammverzeichniss angeben?
|
addSourceHeader = Neue Quelle hinzuf\u00FCgen
|
||||||
|
addSourceBody = HomeFlix konnte keine Quelle finden. \nFüge eine loakels Verzeichniss oder eine Sreaming Datei als neue Quelle hinzu.
|
||||||
|
cancelBtnText = Abbrechen
|
||||||
|
|
|
@ -20,6 +20,7 @@ updateBtnChecking = checking for updates...
|
||||||
updateBtnUpdateAvailable = update available
|
updateBtnUpdateAvailable = update available
|
||||||
updateBtnNoUpdateAvailable = no update available
|
updateBtnNoUpdateAvailable = no update available
|
||||||
autoUpdate = check at startup for updates:
|
autoUpdate = check at startup for updates:
|
||||||
|
autoplay = autoplay
|
||||||
branchLbl = Branch
|
branchLbl = Branch
|
||||||
|
|
||||||
#column translations
|
#column translations
|
||||||
|
@ -32,7 +33,6 @@ columnFavorite = Favorite
|
||||||
#error translations
|
#error translations
|
||||||
errorUpdateV = An error has occurred during update! \nError: could not check update version (nvc) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
errorUpdateV = An error has occurred during update! \nError: could not check update version (nvc) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
||||||
errorUpdateD = An error has occurred during update! \nError: could not download update files (ndf) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
errorUpdateD = An error has occurred during update! \nError: could not download update files (ndf) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
||||||
errorPlay = An error has occurred during opening the file! \nError: could not open file (nof) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
|
||||||
errorMode = Oh, something went wrong! It seems someone has used a wrong mode. \nError: mode unknow (muk) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
errorMode = Oh, something went wrong! It seems someone has used a wrong mode. \nError: mode unknow (muk) \nTo get help, visit www.kellerkinder.xyz \nor contcat support@kellerkinder.xyz
|
||||||
errorOpenStream = An error has occurred during opening the stream!
|
errorOpenStream = An error has occurred during opening the stream!
|
||||||
errorLoad = An error occurred while loading the settings!
|
errorLoad = An error occurred while loading the settings!
|
||||||
|
@ -59,5 +59,7 @@ metascore = Metascore
|
||||||
imdbRating = IMDB-Rating
|
imdbRating = IMDB-Rating
|
||||||
type = Type
|
type = Type
|
||||||
|
|
||||||
firstStartHeader = There is no root directory for movies!
|
#first start
|
||||||
firstStartContent = Specify a root directory?
|
addSourceHeader = add a new source
|
||||||
|
addSourceBody = HomeFlix was not able to load a source. \nAdd a new local directory oa a streaming file as new source.
|
||||||
|
cancelBtnText = cancel
|
||||||
|
|