From 4be971efeef6ed44bdde1cd1b747c052473f9dd7 Mon Sep 17 00:00:00 2001 From: Jannik Date: Tue, 13 Mar 2018 18:08:30 +0100 Subject: [PATCH 01/32] bug fixes * fixed a crash at the first start on linux * fixed a crash caused by "" as source path * fixed HomeFlix is unable to start because sources.json is missing * removed one unnecessary restart --- .../kellerkinder/HomeFlix/application/Main.java | 14 ++++++-------- .../HomeFlix/application/MainWindowController.java | 9 +++++++-- .../locals/HomeFlix-Local_de_DE.properties | 1 + .../locals/HomeFlix-Local_en_US.properties | 1 + 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index 9d211f6..e2acd3a 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -112,12 +112,6 @@ public class Main extends Application { 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()) { @@ -152,10 +146,11 @@ public class Main extends Application { break; } - Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with file-chooser + Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with DirectoryChooser alert.setTitle("Project HomeFlix"); alert.setHeaderText(bundle.getString("firstStartHeader")); alert.setContentText(bundle.getString("firstStartContent")); + alert.setResizable(true); Optional result = alert.showAndWait(); if (result.get() == ButtonType.OK){ @@ -165,9 +160,12 @@ public class Main extends Application { path = selectedDirectory.getAbsolutePath(); } else { - path = ""; + LOGGER.warn("No directory selected!"); + System.exit(1); } + return path; + } public static void main(String[] args) { diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 918c9e6..6e152e3 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -729,12 +729,17 @@ public class MainWindowController { try { // read old array - newsources = Json.parse(new FileReader(main.getDirectory() + "/sources.json")).asArray(); + File oldSources = new File(main.getDirectory() + "/sources.json"); + if (oldSources.exists()) { + newsources = Json.parse(new FileReader(main.getDirectory() + "/sources.json")).asArray(); + } else { + newsources = Json.array(); + } // add new source - Writer writer = new FileWriter(main.getDirectory() + "/sources.json"); source = Json.object().add("path", path).add("mode", mode); newsources.add(source); + Writer writer = new FileWriter(main.getDirectory() + "/sources.json"); newsources.writeTo(writer); writer.close(); } catch (IOException e) { diff --git a/src/main/resources/locals/HomeFlix-Local_de_DE.properties b/src/main/resources/locals/HomeFlix-Local_de_DE.properties index 544d512..d64608e 100644 --- a/src/main/resources/locals/HomeFlix-Local_de_DE.properties +++ b/src/main/resources/locals/HomeFlix-Local_de_DE.properties @@ -59,5 +59,6 @@ metascore = Metascore imdbRating = IMDB-Bewertung type = Type +#first start firstStartHeader = Es ist kein Stammverzeichnis f\u00FCr Filme angegeben! firstStartContent = Stammverzeichniss angeben? diff --git a/src/main/resources/locals/HomeFlix-Local_en_US.properties b/src/main/resources/locals/HomeFlix-Local_en_US.properties index ce5f4af..047f2c7 100644 --- a/src/main/resources/locals/HomeFlix-Local_en_US.properties +++ b/src/main/resources/locals/HomeFlix-Local_en_US.properties @@ -59,5 +59,6 @@ metascore = Metascore imdbRating = IMDB-Rating type = Type +#first start firstStartHeader = There is no root directory for movies! firstStartContent = Specify a root directory? From f9a54abf68e729da01a6b60a2d36afda8e5d2cec Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 22 Mar 2018 11:55:06 +0100 Subject: [PATCH 02/32] small cleanup --- .classpath | 6 +++++- pom.xml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.classpath b/.classpath index e83910a..eab655a 100644 --- a/.classpath +++ b/.classpath @@ -22,6 +22,10 @@ - + + + + + diff --git a/pom.xml b/pom.xml index b5a8a73..82a9e6f 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ com.jfoenix jfoenix - 9.0.2 + 9.0.3 From 2d5887db4fe99682c382fac88567a6a126380cbe Mon Sep 17 00:00:00 2001 From: Jannik Date: Wed, 28 Mar 2018 21:58:01 +0200 Subject: [PATCH 03/32] windows 10 & sql fixes * fixed files wit ' in the name causing a crash *fixed windows 10 is not detected --- src/main/java/kellerkinder/HomeFlix/application/Main.java | 2 +- .../java/kellerkinder/HomeFlix/controller/DBController.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index e2acd3a..ae797af 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -93,7 +93,7 @@ public class Main extends Application { // get OS and the specific paths - if (osName.equals("Windows")) { + if (osName.contains("Windows")) { directory = new File(dirWin); configFile = new File(dirWin + "/config.xml"); posterCache = new File(dirWin + "/posterCache"); diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 36fd8fc..7ca7306 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -333,7 +333,7 @@ public class DBController { if (!filmsdbStreamURL.contains(episode.getPath())) { LOGGER.info("Added \"" + file.getName() + "\", Episode: " + episode.getName() + " to database"); stmt.executeUpdate("insert into films values (" - + "'" + episode.getPath() + "'," + + "'" + episode.getPath().replace("'", "''") + "'," + "'" + cutOffEnd(file.getName()) + "','" + sn + "','" + ep + "', 0, 0)"); connection.commit(); stmt.close(); From 8ec7653a5e00aeb76d1e08690bcf071c8f827472 Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 29 Mar 2018 11:26:20 +0200 Subject: [PATCH 04/32] added to option to select a local or streaming source at the first start --- .../uiElements/JFXDirStrmCancelDialog.java | 194 ++++++++++++++++++ .../com/cemu_UI/uiElements/JFXInfoDialog.java | 66 +++++- .../uiElements/JFXOkayCancelDialog.java | 126 ++++++++---- .../uiElements/JFXTextAreaInfoDialog.java | 65 +++++- .../HomeFlix/application/Main.java | 87 ++++++-- .../application/MainWindowController.java | 11 +- .../locals/HomeFlix-Local_de_DE.properties | 5 +- .../locals/HomeFlix-Local_en_US.properties | 5 +- 8 files changed, 483 insertions(+), 76 deletions(-) create mode 100644 src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java diff --git a/src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java new file mode 100644 index 0000000..71ec0ee --- /dev/null +++ b/src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java @@ -0,0 +1,194 @@ +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 JFXDirStrmCancelDialog { + private String headingText; + private String bodyText; + private String dialogBtnStyle; + private String btn1Text; + private String btn2Text; + private String cancelText; + private int dialogWidth; + private int dialogHeight; + private EventHandler btn1Action; + private EventHandler btn2Action; + 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 btn1Action action which is performed if btn1 is clicked + * @param btn2Action action which is performed if btn2 is clicked + * @param cancelAction action which is performed if the cancel button is clicked + * @param pane pane to which the dialog belongs + */ + public JFXDirStrmCancelDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth, + int dialogHeight, EventHandler btn1Action, EventHandler btn2Action, + Pane pane, ResourceBundle bundle) { + setHeadingText(headingText); + setBodyText(bodyText); + setDialogBtnStyle(dialogBtnStyle); + setDialogWidth(dialogWidth); + setDialogHeight(dialogHeight); + setBtn1Action(btn1Action); + setBtn2Action(btn2Action); + setPane(pane); + + btn1Text = bundle.getString("addDirectory"); + btn2Text = bundle.getString("addStreamSource"); + cancelText = bundle.getString("cancelBtnText"); + } + + public JFXDirStrmCancelDialog() { + // Auto-generated constructor stub + } + + 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 btn1 = new JFXButton(btn1Text); + btn1.addEventHandler(ActionEvent.ACTION, (e) -> { + dialog.close(); + }); + btn1.addEventHandler(ActionEvent.ACTION, btn1Action); + btn1.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); + btn1.setPrefHeight(32); + btn1.setStyle(dialogBtnStyle); + + JFXButton btn2 = new JFXButton(btn2Text); + btn2.addEventHandler(ActionEvent.ACTION, (e) -> { + dialog.close(); + }); + btn2.addEventHandler(ActionEvent.ACTION, btn2Action); + btn2.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); + btn2.setPrefHeight(32); + btn2.setStyle(dialogBtnStyle); + + JFXButton cancelBtn = new JFXButton(cancelText); + cancelBtn.addEventHandler(ActionEvent.ACTION, (e) -> { + dialog.close(); + }); + cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); + cancelBtn.setPrefHeight(32); + cancelBtn.setStyle(dialogBtnStyle); + + content.setActions(cancelBtn, btn1, btn2); + 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 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 getDialogBtnStyle() { + return dialogBtnStyle; + } + + public void setDialogBtnStyle(String dialogBtnStyle) { + this.dialogBtnStyle = dialogBtnStyle; + } + + 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 int getDialogWidth() { + return dialogWidth; + } + + public void setDialogWidth(int dialogWidth) { + this.dialogWidth = dialogWidth; + } + + public int getDialogHeight() { + return dialogHeight; + } + + public void setDialogHeight(int dialogHeight) { + this.dialogHeight = dialogHeight; + } + + public EventHandler getBtn1Action() { + return btn1Action; + } + + public void setBtn1Action(EventHandler btn1Action) { + this.btn1Action = btn1Action; + } + + public EventHandler getBtn2Action() { + return btn2Action; + } + + public void setBtn2Action(EventHandler btn2Action) { + this.btn2Action = btn2Action; + } + + public Pane getPane() { + return pane; + } + + public void setPane(Pane pane) { + this.pane = pane; + } + +} diff --git a/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java index 9c2b710..785630a 100644 --- a/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java +++ b/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017 <@Seil0> + * Copyright 2017-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 @@ -43,12 +43,12 @@ public class JFXInfoDialog { /** * 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 + * @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 JFXInfoDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth, int dialogHeight, Pane pane) { this.headingText = headingText; @@ -58,6 +58,10 @@ public class JFXInfoDialog { this.dialogHeight = dialogHeight; this.pane = pane; } + + public JFXInfoDialog() { + // Auto-generated constructor stub + } public void show() { JFXDialogLayout content = new JFXDialogLayout(); @@ -83,4 +87,52 @@ public class JFXInfoDialog { AnchorPane.setLeftAnchor(stackPane, (pane.getWidth() - content.getPrefWidth()) / 2); dialog.show(); } + + 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 getDialogBtnStyle() { + return dialogBtnStyle; + } + + public void setDialogBtnStyle(String dialogBtnStyle) { + this.dialogBtnStyle = dialogBtnStyle; + } + + public int getDialogWidth() { + return dialogWidth; + } + + public void setDialogWidth(int dialogWidth) { + this.dialogWidth = dialogWidth; + } + + public int getDialogHeight() { + return dialogHeight; + } + + public void setDialogHeight(int dialogHeight) { + this.dialogHeight = dialogHeight; + } + + public Pane getPane() { + return pane; + } + + public void setPane(Pane pane) { + this.pane = pane; + } } diff --git a/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java index 5dd4d1a..974fc3d 100644 --- a/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java +++ b/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017 <@Seil0> + * Copyright 2017-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 @@ -19,7 +19,6 @@ * MA 02110-1301, USA. */ - package com.cemu_UI.uiElements; import java.util.ResourceBundle; @@ -50,14 +49,14 @@ public class JFXOkayCancelDialog { /** * 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 + * @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 okayAction, EventHandler cancelAction, Pane pane, @@ -74,36 +73,63 @@ public class JFXOkayCancelDialog { cancelText = bundle.getString("cancelBtnText"); } + public JFXOkayCancelDialog() { + // Auto-generated constructor stub + } + 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(); + 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 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 getDialogBtnStyle() { + return dialogBtnStyle; + } + + public void setDialogBtnStyle(String dialogBtnStyle) { + this.dialogBtnStyle = dialogBtnStyle; } public String getOkayText() { @@ -122,6 +148,22 @@ public class JFXOkayCancelDialog { this.cancelText = cancelText; } + public int getDialogWidth() { + return dialogWidth; + } + + public void setDialogWidth(int dialogWidth) { + this.dialogWidth = dialogWidth; + } + + public int getDialogHeight() { + return dialogHeight; + } + + public void setDialogHeight(int dialogHeight) { + this.dialogHeight = dialogHeight; + } + public EventHandler getOkayAction() { return okayAction; } @@ -138,5 +180,13 @@ public class JFXOkayCancelDialog { this.cancelAction = cancelAction; } + public Pane getPane() { + return pane; + } + + public void setPane(Pane pane) { + this.pane = pane; + } + } diff --git a/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java index fd8ff2f..ea60f8c 100644 --- a/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java +++ b/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java @@ -1,7 +1,7 @@ /** * cemu_UI * - * Copyright 2017 <@Seil0> + * Copyright 2017-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 @@ -45,12 +45,12 @@ public class JFXTextAreaInfoDialog { /** * 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 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 + * @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; @@ -60,6 +60,10 @@ public class JFXTextAreaInfoDialog { this.dialogHeight = dialogHeight; this.pane = pane; } + + public JFXTextAreaInfoDialog() { + // Auto-generated constructor stub + } public void show() { textArea = new JFXTextArea(bodyText); @@ -88,6 +92,46 @@ public class JFXTextAreaInfoDialog { dialog.show(); } + 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 getDialogBtnStyle() { + return dialogBtnStyle; + } + + public void setDialogBtnStyle(String dialogBtnStyle) { + this.dialogBtnStyle = dialogBtnStyle; + } + + public int getDialogWidth() { + return dialogWidth; + } + + public void setDialogWidth(int dialogWidth) { + this.dialogWidth = dialogWidth; + } + + public int getDialogHeight() { + return dialogHeight; + } + + public void setDialogHeight(int dialogHeight) { + this.dialogHeight = dialogHeight; + } + public JFXTextArea getTextArea() { return textArea; } @@ -95,4 +139,13 @@ public class JFXTextAreaInfoDialog { public void setTextArea(JFXTextArea textArea) { this.textArea = textArea; } + + public Pane getPane() { + return pane; + } + + public void setPane(Pane pane) { + this.pane = pane; + } + } diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index ae797af..ceb0877 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -36,10 +36,12 @@ import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonBar.ButtonData; import javafx.scene.control.ButtonType; import javafx.scene.image.Image; import javafx.scene.layout.AnchorPane; import javafx.stage.DirectoryChooser; +import javafx.stage.FileChooser; import javafx.stage.Stage; public class Main extends Application { @@ -61,7 +63,6 @@ public class Main extends Application { private File configFile; 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; @@ -105,8 +106,8 @@ public class Main extends Application { // startup checks if (!configFile.exists()) { - directory.mkdir(); - mainWindowController.addSource(firstStart(), "local"); + directory.mkdir(); + getFirstSource(); mainWindowController.setColor("ee3523"); mainWindowController.setSize(FONT_SIZE); mainWindowController.setAutoUpdate(false); @@ -132,8 +133,10 @@ public class Main extends Application { } } - // Method for first Start - private String firstStart(){ + /** TODO add option to add streaming as first source + * when there i no config.xml we need to get the path for the first source from the user + */ + private void getFirstSource(){ switch (System.getProperty("user.language") + "_" + System.getProperty("user.country")) { case "en_US": bundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US); // us_english @@ -146,26 +149,78 @@ public class Main extends Application { break; } +// // directory action +// EventHandler btn1Action = new EventHandler() { +// @Override +// public void handle(ActionEvent event) { +// DirectoryChooser directoryChooser = new DirectoryChooser(); +// directoryChooser.setTitle(bundle.getString("addDirectory")); +// File selectedFolder = directoryChooser.showDialog(primaryStage); +// if (selectedFolder != null && selectedFolder.exists()) { +// mainWindowController.addSource(selectedFolder.getPath(), "local"); +// } else { +// LOGGER.error("The selected folder dosen't exist!"); +// } +// } +// }; +// +// // streaming action +// EventHandler btn2Action = new EventHandler() { +// @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"); +// } else { +// LOGGER.error("The selected file dosen't exist!"); +// } +// } +// }; +// +// JFXDirStrmCancelDialog selectFirstSource = new JFXDirStrmCancelDialog(bundle.getString("addSourceHeader"), +// bundle.getString("addSourceBody"), "", 200, 100, btn1Action, btn2Action, pane, bundle); +// selectFirstSource.show(); + + Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with DirectoryChooser alert.setTitle("Project HomeFlix"); - alert.setHeaderText(bundle.getString("firstStartHeader")); - alert.setContentText(bundle.getString("firstStartContent")); + alert.setHeaderText(bundle.getString("addSourceHeader")); + alert.setContentText(bundle.getString("addSourceBody")); alert.setResizable(true); + + ButtonType buttonDirectory = new ButtonType(bundle.getString("addDirectory")); + ButtonType buttonStreaming = new ButtonType(bundle.getString("addStreamSource")); + ButtonType buttonCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE); + + alert.getButtonTypes().setAll(buttonDirectory, buttonStreaming, buttonCancel); Optional result = alert.showAndWait(); - if (result.get() == ButtonType.OK){ + if (result.get() == buttonDirectory) { DirectoryChooser directoryChooser = new DirectoryChooser(); - File selectedDirectory = - directoryChooser.showDialog(primaryStage); - path = selectedDirectory.getAbsolutePath(); - + directoryChooser.setTitle(bundle.getString("addDirectory")); + File selectedFolder = directoryChooser.showDialog(primaryStage); + if (selectedFolder != null && selectedFolder.exists()) { + mainWindowController.addSource(selectedFolder.getPath(), "local"); + } else { + LOGGER.error("The selected folder dosen't exist!"); + System.exit(1); + } + } else if (result.get() == buttonStreaming) { + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("addStreamSource"); + File selectedFile = fileChooser.showOpenDialog(getPrimaryStage()); + if (selectedFile != null && selectedFile.exists()) { + mainWindowController.addSource(selectedFile.getPath(), "stream"); + } else { + LOGGER.error("The selected file dosen't exist!"); + System.exit(1); + } } else { - LOGGER.warn("No directory selected!"); + LOGGER.warn("No source selected!"); System.exit(1); } - - return path; - } public static void main(String[] args) { diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 6e152e3..83dc315 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -267,7 +267,6 @@ public class MainWindowController { 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_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 dislike = new MenuItem("dislike"); //TODO one option (like or dislike) private ContextMenu menu = new ContextMenu(like, dislike); @@ -290,6 +289,7 @@ public class MainWindowController { omdbAPIController = new OMDbAPIController(this, dbController, this.main); } + // call all init methods void init() { loadSettings(); checkAutoUpdate(); @@ -632,10 +632,11 @@ public class MainWindowController { @FXML 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()) { - addSource(selectedFolder.getPath(), "local"); - dbController.refreshDataBase(); + mainWindowController.addSource(selectedFolder.getPath(), "local"); } else { LOGGER.error("The selected folder dosen't exist!"); } @@ -644,7 +645,7 @@ public class MainWindowController { @FXML private void addStreamSourceBtnAction(){ FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle("Open Resource File"); + fileChooser.setTitle("addStreamSource"); File selectedFile = fileChooser.showOpenDialog(main.getPrimaryStage()); if (selectedFile != null && selectedFile.exists()) { addSource(selectedFile.getPath(), "stream"); diff --git a/src/main/resources/locals/HomeFlix-Local_de_DE.properties b/src/main/resources/locals/HomeFlix-Local_de_DE.properties index d64608e..f8c6279 100644 --- a/src/main/resources/locals/HomeFlix-Local_de_DE.properties +++ b/src/main/resources/locals/HomeFlix-Local_de_DE.properties @@ -60,5 +60,6 @@ imdbRating = IMDB-Bewertung type = Type #first start -firstStartHeader = Es ist kein Stammverzeichnis f\u00FCr Filme angegeben! -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 diff --git a/src/main/resources/locals/HomeFlix-Local_en_US.properties b/src/main/resources/locals/HomeFlix-Local_en_US.properties index 047f2c7..9df7ff2 100644 --- a/src/main/resources/locals/HomeFlix-Local_en_US.properties +++ b/src/main/resources/locals/HomeFlix-Local_en_US.properties @@ -60,5 +60,6 @@ imdbRating = IMDB-Rating type = Type #first start -firstStartHeader = There is no root directory for movies! -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 From 34371bb2b5bfc841b2f6b7ac7fa2b17ad7fc702d Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 29 Mar 2018 12:27:44 +0200 Subject: [PATCH 05/32] added info alert --- .../HomeFlix/application/Main.java | 25 +++-- .../org/kellerkinder/Alerts/JFXInfoAlert.java | 94 +++++++++++++++++++ 2 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index ceb0877..df01890 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -31,7 +31,13 @@ import java.util.ResourceBundle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.jfoenix.controls.JFXAlert; +import com.jfoenix.controls.JFXButton; +import com.jfoenix.controls.JFXDialogLayout; + import javafx.application.Application; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.Alert; @@ -40,8 +46,10 @@ import javafx.scene.control.ButtonBar.ButtonData; import javafx.scene.control.ButtonType; import javafx.scene.image.Image; import javafx.scene.layout.AnchorPane; +import javafx.scene.text.Text; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; +import javafx.stage.Modality; import javafx.stage.Stage; public class Main extends Application { @@ -104,6 +112,12 @@ public class Main extends Application { posterCache = new File(dirLinux + "/posterCache"); } + // generate window + scene = new Scene(pane); // create new scene, append pane to scene + scene.getStylesheets().add(getClass().getResource("/css/MainWindow.css").toExternalForm()); + primaryStage.setScene(scene); // append scene to stage + primaryStage.show(); // show stage + // startup checks if (!configFile.exists()) { directory.mkdir(); @@ -119,11 +133,11 @@ public class Main extends Application { posterCache.mkdir(); } - // generate window - scene = new Scene(pane); // create new scene, append pane to scene - scene.getStylesheets().add(getClass().getResource("/css/MainWindow.css").toExternalForm()); - primaryStage.setScene(scene); // append scene to stage - primaryStage.show(); // show stage +// // generate window +// scene = new Scene(pane); // create new scene, append pane to scene +// scene.getStylesheets().add(getClass().getResource("/css/MainWindow.css").toExternalForm()); +// primaryStage.setScene(scene); // append scene to stage +// primaryStage.show(); // show stage // init here as it loads the games to the mwc and the gui, therefore the window must exist mainWindowController.init(); @@ -182,7 +196,6 @@ public class Main extends Application { // JFXDirStrmCancelDialog selectFirstSource = new JFXDirStrmCancelDialog(bundle.getString("addSourceHeader"), // bundle.getString("addSourceBody"), "", 200, 100, btn1Action, btn2Action, pane, bundle); // selectFirstSource.show(); - Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with DirectoryChooser alert.setTitle("Project HomeFlix"); diff --git a/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java b/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java new file mode 100644 index 0000000..62b8ce7 --- /dev/null +++ b/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java @@ -0,0 +1,94 @@ +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.stage.Stage; + +public class JFXInfoAlert { + + private String titleText; + private String headerText; + private String contentText; + private String btnStyle; + private Stage stage; + + public JFXInfoAlert() { + // Auto-generated constructor stub + } + + public JFXInfoAlert(String titleText, String headerText, String contentText, String btnStyle, Stage stage) { + setTitleText(titleText); + setHeaderText(headerText); + setContentText(contentText); + setBtnStyle(btnStyle); + setStage(stage); + } + + public void showAndWait( ) { + JFXAlert alert = new JFXAlert<>(stage); + alert.setTitle(titleText); + alert.setHeaderText(headerText); + alert.setContentText(contentText); + + JFXButton button = new JFXButton("Okay"); + button.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + alert.close(); + } + }); + button.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); + button.setPrefHeight(32); + button.setStyle(btnStyle); + + JFXDialogLayout content = new JFXDialogLayout(); + content.setActions(button); + alert.setContent(content); + alert.showAndWait(); + } + + public String getTitleText() { + return titleText; + } + + public void setTitleText(String titleText) { + this.titleText = titleText; + } + + public String getHeaderText() { + return headerText; + } + + public void setHeaderText(String headerText) { + this.headerText = headerText; + } + + public String getContentText() { + return contentText; + } + + public void setContentText(String contentText) { + this.contentText = contentText; + } + + 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; + } + +} From 22df604093fb052ceb508a487cafc0fb1ff259b8 Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 29 Mar 2018 18:15:57 +0200 Subject: [PATCH 06/32] use alerts instead of dialogs * the first start alert is now material styled * the info dialog is now a alert --- .../uiElements/JFXDirStrmCancelDialog.java | 194 ------------------ .../HomeFlix/application/Main.java | 164 ++++++--------- .../application/MainWindowController.java | 11 +- .../Alerts/JFX2BtnCancelAlert.java | 190 +++++++++++++++++ .../org/kellerkinder/Alerts/JFXInfoAlert.java | 80 +++++--- 5 files changed, 305 insertions(+), 334 deletions(-) delete mode 100644 src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java create mode 100644 src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java diff --git a/src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java deleted file mode 100644 index 71ec0ee..0000000 --- a/src/main/java/com/cemu_UI/uiElements/JFXDirStrmCancelDialog.java +++ /dev/null @@ -1,194 +0,0 @@ -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 JFXDirStrmCancelDialog { - private String headingText; - private String bodyText; - private String dialogBtnStyle; - private String btn1Text; - private String btn2Text; - private String cancelText; - private int dialogWidth; - private int dialogHeight; - private EventHandler btn1Action; - private EventHandler btn2Action; - 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 btn1Action action which is performed if btn1 is clicked - * @param btn2Action action which is performed if btn2 is clicked - * @param cancelAction action which is performed if the cancel button is clicked - * @param pane pane to which the dialog belongs - */ - public JFXDirStrmCancelDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth, - int dialogHeight, EventHandler btn1Action, EventHandler btn2Action, - Pane pane, ResourceBundle bundle) { - setHeadingText(headingText); - setBodyText(bodyText); - setDialogBtnStyle(dialogBtnStyle); - setDialogWidth(dialogWidth); - setDialogHeight(dialogHeight); - setBtn1Action(btn1Action); - setBtn2Action(btn2Action); - setPane(pane); - - btn1Text = bundle.getString("addDirectory"); - btn2Text = bundle.getString("addStreamSource"); - cancelText = bundle.getString("cancelBtnText"); - } - - public JFXDirStrmCancelDialog() { - // Auto-generated constructor stub - } - - 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 btn1 = new JFXButton(btn1Text); - btn1.addEventHandler(ActionEvent.ACTION, (e) -> { - dialog.close(); - }); - btn1.addEventHandler(ActionEvent.ACTION, btn1Action); - btn1.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); - btn1.setPrefHeight(32); - btn1.setStyle(dialogBtnStyle); - - JFXButton btn2 = new JFXButton(btn2Text); - btn2.addEventHandler(ActionEvent.ACTION, (e) -> { - dialog.close(); - }); - btn2.addEventHandler(ActionEvent.ACTION, btn2Action); - btn2.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); - btn2.setPrefHeight(32); - btn2.setStyle(dialogBtnStyle); - - JFXButton cancelBtn = new JFXButton(cancelText); - cancelBtn.addEventHandler(ActionEvent.ACTION, (e) -> { - dialog.close(); - }); - cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED); - cancelBtn.setPrefHeight(32); - cancelBtn.setStyle(dialogBtnStyle); - - content.setActions(cancelBtn, btn1, btn2); - 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 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 getDialogBtnStyle() { - return dialogBtnStyle; - } - - public void setDialogBtnStyle(String dialogBtnStyle) { - this.dialogBtnStyle = dialogBtnStyle; - } - - 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 int getDialogWidth() { - return dialogWidth; - } - - public void setDialogWidth(int dialogWidth) { - this.dialogWidth = dialogWidth; - } - - public int getDialogHeight() { - return dialogHeight; - } - - public void setDialogHeight(int dialogHeight) { - this.dialogHeight = dialogHeight; - } - - public EventHandler getBtn1Action() { - return btn1Action; - } - - public void setBtn1Action(EventHandler btn1Action) { - this.btn1Action = btn1Action; - } - - public EventHandler getBtn2Action() { - return btn2Action; - } - - public void setBtn2Action(EventHandler btn2Action) { - this.btn2Action = btn2Action; - } - - public Pane getPane() { - return pane; - } - - public void setPane(Pane pane) { - this.pane = pane; - } - -} diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index df01890..ee36ce5 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -25,35 +25,25 @@ package kellerkinder.HomeFlix.application; import java.io.File; import java.io.IOException; import java.util.Locale; -import java.util.Optional; import java.util.ResourceBundle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - -import com.jfoenix.controls.JFXAlert; -import com.jfoenix.controls.JFXButton; -import com.jfoenix.controls.JFXDialogLayout; +import org.kellerkinder.Alerts.JFX2BtnCancelAlert; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.ButtonBar.ButtonData; -import javafx.scene.control.ButtonType; import javafx.scene.image.Image; import javafx.scene.layout.AnchorPane; -import javafx.scene.text.Text; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; -import javafx.stage.Modality; import javafx.stage.Stage; public class Main extends Application { - + private Stage primaryStage; private Scene scene; private AnchorPane pane; @@ -64,29 +54,29 @@ public class Main extends Application { private static String osArch = System.getProperty("os.arch"); private static String osVers = System.getProperty("os.version"); private static String javaVers = System.getProperty("java.version"); - private static String javaVend= System.getProperty("java.vendor"); - private String dirWin = userHome + "/Documents/HomeFlix"; //Windows: C:/Users/"User"/Documents/HomeFlix - private String dirLinux = userHome + "/HomeFlix"; //Linux: /home/"User"/HomeFlix + private static String javaVend = System.getProperty("java.vendor"); + 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 configFile; private File posterCache; - + private String FONT_FAMILY = "System"; - private String local = System.getProperty("user.language")+"_"+System.getProperty("user.country"); + private String local = System.getProperty("user.language") + "_" + System.getProperty("user.country"); private double FONT_SIZE = 17; private ResourceBundle bundle; private static Logger LOGGER; - + @Override public void start(Stage primaryStage) throws IOException { LOGGER.info("OS: " + osName + " " + osVers + " " + osArch); LOGGER.info("Java: " + javaVend + " " + javaVers); LOGGER.info("User: " + userName + " " + userHome); - - this.primaryStage = primaryStage; + + this.primaryStage = primaryStage; mainWindow(); } - + private void mainWindow(){ try { FXMLLoader loader = new FXMLLoader(); @@ -133,12 +123,6 @@ public class Main extends Application { posterCache.mkdir(); } -// // generate window -// scene = new Scene(pane); // create new scene, append pane to scene -// scene.getStylesheets().add(getClass().getResource("/css/MainWindow.css").toExternalForm()); -// primaryStage.setScene(scene); // append scene to stage -// primaryStage.show(); // show stage - // init here as it loads the games to the mwc and the gui, therefore the window must exist mainWindowController.init(); mainWindowController.getDbController().init(); @@ -146,11 +130,12 @@ public class Main extends Application { LOGGER.error(e); } } - - /** TODO add option to add streaming as first source - * when there i no config.xml we need to get the path for the first source from the user + + /** + * TODO add option to add streaming as first source when there i no config.xml + * we need to get the path for the first source from the user */ - private void getFirstSource(){ + private void getFirstSource() { switch (System.getProperty("user.language") + "_" + System.getProperty("user.country")) { case "en_US": bundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US); // us_english @@ -163,85 +148,56 @@ public class Main extends Application { break; } -// // directory action -// EventHandler btn1Action = new EventHandler() { -// @Override -// public void handle(ActionEvent event) { -// DirectoryChooser directoryChooser = new DirectoryChooser(); -// directoryChooser.setTitle(bundle.getString("addDirectory")); -// File selectedFolder = directoryChooser.showDialog(primaryStage); -// if (selectedFolder != null && selectedFolder.exists()) { -// mainWindowController.addSource(selectedFolder.getPath(), "local"); -// } else { -// LOGGER.error("The selected folder dosen't exist!"); -// } -// } -// }; -// -// // streaming action -// EventHandler btn2Action = new EventHandler() { -// @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"); -// } else { -// LOGGER.error("The selected file dosen't exist!"); -// } -// } -// }; -// -// JFXDirStrmCancelDialog selectFirstSource = new JFXDirStrmCancelDialog(bundle.getString("addSourceHeader"), -// bundle.getString("addSourceBody"), "", 200, 100, btn1Action, btn2Action, pane, bundle); -// selectFirstSource.show(); - - Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with DirectoryChooser - alert.setTitle("Project HomeFlix"); - alert.setHeaderText(bundle.getString("addSourceHeader")); - alert.setContentText(bundle.getString("addSourceBody")); - alert.setResizable(true); - - ButtonType buttonDirectory = new ButtonType(bundle.getString("addDirectory")); - ButtonType buttonStreaming = new ButtonType(bundle.getString("addStreamSource")); - ButtonType buttonCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE); + JFX2BtnCancelAlert selectFirstSource = new JFX2BtnCancelAlert(bundle.getString("addSourceHeader"), + bundle.getString("addSourceBody"), + "-fx-button-type: RAISED; -fx-background-color: #ee3523; -fx-text-fill: BLACK;", + bundle.getString("addDirectory"), bundle.getString("addStreamSource"), + bundle.getString("cancelBtnText"), primaryStage); - alert.getButtonTypes().setAll(buttonDirectory, buttonStreaming, buttonCancel); + // directory action + EventHandler btn1Action = new EventHandler() { + @Override + public void handle(ActionEvent event) { + DirectoryChooser directoryChooser = new DirectoryChooser(); + directoryChooser.setTitle(bundle.getString("addDirectory")); + File selectedFolder = directoryChooser.showDialog(primaryStage); + if (selectedFolder != null && selectedFolder.exists()) { + mainWindowController.addSource(selectedFolder.getPath(), "local"); + selectFirstSource.getAlert().close(); + } else { + LOGGER.error("The selected folder dosen't exist!"); + System.exit(1); + } + } + }; - Optional result = alert.showAndWait(); - if (result.get() == buttonDirectory) { - DirectoryChooser directoryChooser = new DirectoryChooser(); - directoryChooser.setTitle(bundle.getString("addDirectory")); - File selectedFolder = directoryChooser.showDialog(primaryStage); - if (selectedFolder != null && selectedFolder.exists()) { - mainWindowController.addSource(selectedFolder.getPath(), "local"); - } else { - LOGGER.error("The selected folder dosen't exist!"); - System.exit(1); + // streaming action + EventHandler btn2Action = new EventHandler() { + @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); + } } - } else if (result.get() == buttonStreaming) { - FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle("addStreamSource"); - File selectedFile = fileChooser.showOpenDialog(getPrimaryStage()); - if (selectedFile != null && selectedFile.exists()) { - mainWindowController.addSource(selectedFile.getPath(), "stream"); - } else { - LOGGER.error("The selected file dosen't exist!"); - System.exit(1); - } - } else { - LOGGER.warn("No source selected!"); - System.exit(1); - } + }; + selectFirstSource.setBtn1Action(btn1Action); + selectFirstSource.setBtn2Action(btn2Action); + selectFirstSource.showAndWait(); } 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"); File logFile = new File(userHome + "/Documents/HomeFlix/app.log"); logFile.delete(); - }else{ + } else { System.setProperty("logFilename", userHome + "/HomeFlix/app.log"); File logFile = new File(userHome + "/HomeFlix/app.log"); logFile.delete(); @@ -257,8 +213,8 @@ public class Main extends Application { public void setPrimaryStage(Stage primaryStage) { this.primaryStage = primaryStage; } - - public AnchorPane getPane( ) { + + public AnchorPane getPane() { return pane; } @@ -269,7 +225,7 @@ public class Main extends Application { public void setFONT_FAMILY(String FONT_FAMILY) { this.FONT_FAMILY = FONT_FAMILY; } - + public File getDirectory() { return directory; } diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 83dc315..2001c43 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -44,6 +44,7 @@ import java.util.ResourceBundle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.kellerkinder.Alerts.JFXInfoAlert; import com.cemu_UI.uiElements.JFXInfoDialog; import com.eclipsesource.json.Json; @@ -231,9 +232,9 @@ public class MainWindowController { private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; - private String version = "0.6.0"; - private String buildNumber = "141"; - private String versionName = "plasma vampire"; + private String version = "0.6.1"; + private String buildNumber = "145"; + private String versionName = "glowing vampire"; private String dialogBtnStyle; private String color; private String title; @@ -609,8 +610,8 @@ public class MainWindowController { private void aboutBtnAction() { String bodyText = "cemu_UI by @Seil0 \nVersion: " + version + " (Build: " + buildNumber + ") \"" + versionName + "\" \n" + infoText; - JFXInfoDialog aboutDialog = new JFXInfoDialog("Project HomeFlix", bodyText, dialogBtnStyle, 350, 200, main.getPane()); - aboutDialog.show(); + JFXInfoAlert infoAlert = new JFXInfoAlert("Project HomeFlix", bodyText, dialogBtnStyle, main.getPrimaryStage()); + infoAlert.showAndWait(); } @FXML diff --git a/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java b/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java new file mode 100644 index 0000000..8272b1d --- /dev/null +++ b/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java @@ -0,0 +1,190 @@ +/** + * 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 btn1Action; + private EventHandler btn2Action; + private Stage stage; + private JFXAlert 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() { + @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 getBtn1Action() { + return btn1Action; + } + + public void setBtn1Action(EventHandler btn1Action) { + this.btn1Action = btn1Action; + } + + public EventHandler getBtn2Action() { + return btn2Action; + } + + public void setBtn2Action(EventHandler btn2Action) { + this.btn2Action = btn2Action; + } + + public Stage getStage() { + return stage; + } + + public void setStage(Stage stage) { + this.stage = stage; + } + + public JFXAlert getAlert() { + return alert; + } + + public void setAlert(JFXAlert alert) { + this.alert = alert; + } +} diff --git a/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java b/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java index 62b8ce7..2375b4d 100644 --- a/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java +++ b/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java @@ -1,3 +1,24 @@ +/** + * 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; @@ -6,33 +27,36 @@ import com.jfoenix.controls.JFXDialogLayout; import javafx.event.ActionEvent; import javafx.event.EventHandler; +import javafx.scene.text.Text; import javafx.stage.Stage; public class JFXInfoAlert { - private String titleText; - private String headerText; - private String contentText; + private String headingText; + private String bodyText; private String btnStyle; private Stage stage; + + /** + * Creates a new JFoenix Alert to show some information + * @param headerText Heading text of the alert + * @param bodyText Content text of the alert + * @param btnStyle Style of the okay button + * @param stage stage to which the dialog belongs + */ + public JFXInfoAlert(String headingText, String bodyText, String btnStyle, Stage stage) { + setHeadingText(headingText); + setBodyText(bodyText); + setBtnStyle(btnStyle); + setStage(stage); + } public JFXInfoAlert() { // Auto-generated constructor stub } - public JFXInfoAlert(String titleText, String headerText, String contentText, String btnStyle, Stage stage) { - setTitleText(titleText); - setHeaderText(headerText); - setContentText(contentText); - setBtnStyle(btnStyle); - setStage(stage); - } - public void showAndWait( ) { JFXAlert alert = new JFXAlert<>(stage); - alert.setTitle(titleText); - alert.setHeaderText(headerText); - alert.setContentText(contentText); JFXButton button = new JFXButton("Okay"); button.setOnAction(new EventHandler() { @@ -47,32 +71,26 @@ public class JFXInfoAlert { JFXDialogLayout content = new JFXDialogLayout(); content.setActions(button); + content.setHeading(new Text(headingText)); + content.setBody(new Text(bodyText)); alert.setContent(content); alert.showAndWait(); } - public String getTitleText() { - return titleText; + public String getHeadingText() { + return headingText; } - public void setTitleText(String titleText) { - this.titleText = titleText; + public void setHeadingText(String headingText) { + this.headingText = headingText; } - public String getHeaderText() { - return headerText; + public String getBodyText() { + return bodyText; } - public void setHeaderText(String headerText) { - this.headerText = headerText; - } - - public String getContentText() { - return contentText; - } - - public void setContentText(String contentText) { - this.contentText = contentText; + public void setBodyText(String bodyText) { + this.bodyText = bodyText; } public String getBtnStyle() { @@ -91,4 +109,4 @@ public class JFXInfoAlert { this.stage = stage; } -} +} \ No newline at end of file From 2d0d138c089a813556a918bf753e1fafe253533f Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 29 Mar 2018 18:22:14 +0200 Subject: [PATCH 07/32] cleanup --- .../com/cemu_UI/uiElements/JFXInfoDialog.java | 138 ------------- .../uiElements/JFXOkayCancelDialog.java | 192 ------------------ .../uiElements/JFXTextAreaInfoDialog.java | 151 -------------- .../application/MainWindowController.java | 5 +- 4 files changed, 2 insertions(+), 484 deletions(-) delete mode 100644 src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java delete mode 100644 src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java delete mode 100644 src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java diff --git a/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java deleted file mode 100644 index 785630a..0000000 --- a/src/main/java/com/cemu_UI/uiElements/JFXInfoDialog.java +++ /dev/null @@ -1,138 +0,0 @@ -/** - * cemu_UI - * - * Copyright 2017-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 com.cemu_UI.uiElements; - -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 JFXInfoDialog { - - private String headingText; - private String bodyText; - private String dialogBtnStyle; - private int dialogWidth; - private int dialogHeight; - 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 JFXInfoDialog(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 JFXInfoDialog() { - // Auto-generated constructor stub - } - - public void show() { - JFXDialogLayout content = new JFXDialogLayout(); - content.setHeading(new Text(headingText)); - content.setBody(new Text(bodyText)); - 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() { - @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 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 getDialogBtnStyle() { - return dialogBtnStyle; - } - - public void setDialogBtnStyle(String dialogBtnStyle) { - this.dialogBtnStyle = dialogBtnStyle; - } - - public int getDialogWidth() { - return dialogWidth; - } - - public void setDialogWidth(int dialogWidth) { - this.dialogWidth = dialogWidth; - } - - public int getDialogHeight() { - return dialogHeight; - } - - public void setDialogHeight(int dialogHeight) { - this.dialogHeight = dialogHeight; - } - - public Pane getPane() { - return pane; - } - - public void setPane(Pane pane) { - this.pane = pane; - } -} diff --git a/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java deleted file mode 100644 index 974fc3d..0000000 --- a/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * cemu_UI - * - * Copyright 2017-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 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 okayAction; - private EventHandler 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 okayAction, EventHandler 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 JFXOkayCancelDialog() { - // Auto-generated constructor stub - } - - 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 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 getDialogBtnStyle() { - return dialogBtnStyle; - } - - public void setDialogBtnStyle(String dialogBtnStyle) { - this.dialogBtnStyle = dialogBtnStyle; - } - - 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 int getDialogWidth() { - return dialogWidth; - } - - public void setDialogWidth(int dialogWidth) { - this.dialogWidth = dialogWidth; - } - - public int getDialogHeight() { - return dialogHeight; - } - - public void setDialogHeight(int dialogHeight) { - this.dialogHeight = dialogHeight; - } - - public EventHandler getOkayAction() { - return okayAction; - } - - public void setOkayAction(EventHandler okayAction) { - this.okayAction = okayAction; - } - - public EventHandler getCancelAction() { - return cancelAction; - } - - public void setCancelAction(EventHandler cancelAction) { - this.cancelAction = cancelAction; - } - - public Pane getPane() { - return pane; - } - - public void setPane(Pane pane) { - this.pane = pane; - } - -} - diff --git a/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java deleted file mode 100644 index ea60f8c..0000000 --- a/src/main/java/com/cemu_UI/uiElements/JFXTextAreaInfoDialog.java +++ /dev/null @@ -1,151 +0,0 @@ -/** - * cemu_UI - * - * Copyright 2017-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 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 JFXTextAreaInfoDialog() { - // Auto-generated constructor stub - } - - 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() { - @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 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 getDialogBtnStyle() { - return dialogBtnStyle; - } - - public void setDialogBtnStyle(String dialogBtnStyle) { - this.dialogBtnStyle = dialogBtnStyle; - } - - public int getDialogWidth() { - return dialogWidth; - } - - public void setDialogWidth(int dialogWidth) { - this.dialogWidth = dialogWidth; - } - - public int getDialogHeight() { - return dialogHeight; - } - - public void setDialogHeight(int dialogHeight) { - this.dialogHeight = dialogHeight; - } - - public JFXTextArea getTextArea() { - return textArea; - } - - public void setTextArea(JFXTextArea textArea) { - this.textArea = textArea; - } - - public Pane getPane() { - return pane; - } - - public void setPane(Pane pane) { - this.pane = pane; - } - -} diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 2001c43..fe86e28 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -46,7 +46,6 @@ import org.apache.logging.log4j.LogManager; 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.JsonArray; import com.eclipsesource.json.JsonObject; @@ -563,8 +562,8 @@ public class MainWindowController { e1.printStackTrace(); } if (output.contains("which: no vlc") || output == "") { - JFXInfoDialog vlcInfoDialog = new JFXInfoDialog("Info", vlcNotInstalled, dialogBtnStyle, 350, 200, main.getPane()); - vlcInfoDialog.show(); + JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info", vlcNotInstalled, dialogBtnStyle, main.getPrimaryStage()); + vlcInfoAlert.showAndWait(); } else { try { Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder From 2881c1f9d65dc3fea6bf7b06d7efa1799bd4f22a Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 1 Apr 2018 23:24:49 +0200 Subject: [PATCH 08/32] added first version of the new player * added a javafx mediaplayer based player --- .../application/MainWindowController.java | 67 +++++++++-------- .../kellerkinder/HomeFlix/player/Player.java | 52 +++++++++++++ .../HomeFlix/player/PlayerController.java | 75 +++++++++++++++++++ src/main/resources/fxml/PlayerWindow.fxml | 26 +++++++ 4 files changed, 190 insertions(+), 30 deletions(-) create mode 100644 src/main/java/kellerkinder/HomeFlix/player/Player.java create mode 100644 src/main/java/kellerkinder/HomeFlix/player/PlayerController.java create mode 100644 src/main/resources/fxml/PlayerWindow.fxml diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index fe86e28..2c41075 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -97,6 +97,7 @@ import kellerkinder.HomeFlix.controller.DBController; import kellerkinder.HomeFlix.controller.OMDbAPIController; import kellerkinder.HomeFlix.controller.UpdateController; import kellerkinder.HomeFlix.datatypes.SourceDataType; +import kellerkinder.HomeFlix.player.Player; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class MainWindowController { @@ -228,6 +229,7 @@ public class MainWindowController { private boolean settingsTrue = false; private boolean autoUpdate = false; private boolean useBeta = false; + private boolean betaPlayer = false; private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; @@ -545,42 +547,47 @@ public class MainWindowController { @FXML private void playbtnclicked() { // TODO rework when #19 is coming - - if (System.getProperty("os.name").contains("Linux")) { - String line; - String output = ""; - Process p; - try { - p = Runtime.getRuntime().exec("which vlc"); - BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); - while ((line = input.readLine()) != null) { - output = line; - } - LOGGER.info(output); - input.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - if (output.contains("which: no vlc") || output == "") { - JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info", vlcNotInstalled, dialogBtnStyle, main.getPrimaryStage()); - vlcInfoAlert.showAndWait(); - } else { + + if (betaPlayer) { + new Player(streamUrl); + } else { + if (System.getProperty("os.name").contains("Linux")) { + String line; + String output = ""; + Process p; try { - Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder + p = Runtime.getRuntime().exec("which vlc"); + BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); + while ((line = input.readLine()) != null) { + output = line; + } + LOGGER.info(output); + input.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + if (output.contains("which: no vlc") || output == "") { + JFXInfoAlert vlcInfoAlert = new JFXInfoAlert("Info", vlcNotInstalled, dialogBtnStyle, main.getPrimaryStage()); + vlcInfoAlert.showAndWait(); + } else { + try { + Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder + } catch (IOException e) { + showErrorMsg(errorPlay, e); + } + } + + } else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) { + try { + Desktop.getDesktop().open(new File(streamUrl)); } catch (IOException e) { showErrorMsg(errorPlay, e); } + } else { + LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! "); } - - } else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) { - try { - Desktop.getDesktop().open(new File(streamUrl)); - } catch (IOException e) { - showErrorMsg(errorPlay, e); - } - } else { - LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! "); } + } @FXML diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java new file mode 100644 index 0000000..e1cc12e --- /dev/null +++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java @@ -0,0 +1,52 @@ +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; + +public class Player { + + private PlayerController playerController; + private Stage stage; + private AnchorPane pane; + + public Player(String file) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); + pane = (AnchorPane) fxmlLoader.load(); + stage = new Stage(); + stage.setScene(new Scene(pane)); + stage.setTitle("HomeFlix"); + stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); + stage.setOnCloseRequest(new EventHandler() { + public void handle(WindowEvent we) { + playerController.getMediaPlayer().stop(); + } + }); + + playerController = fxmlLoader.getController(); + playerController.init(file, this); + + stage.setFullScreen(true); + stage.show(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public Stage getStage() { + return stage; + } + + public Parent getPane() { + return pane; + } + +} diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java new file mode 100644 index 0000000..cc79eef --- /dev/null +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -0,0 +1,75 @@ +package kellerkinder.HomeFlix.player; + +import java.io.File; + +import com.jfoenix.controls.JFXButton; + +import javafx.beans.binding.Bindings; +import javafx.beans.property.DoubleProperty; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.layout.HBox; +import javafx.scene.media.Media; +import javafx.scene.media.MediaPlayer; +import javafx.scene.media.MediaPlayer.Status; +import javafx.scene.media.MediaView; + +public class PlayerController { + + @FXML + private MediaView mediaView; + + @FXML + private HBox controllsHBox; + + @FXML + private JFXButton playBtn; + + @FXML + private JFXButton fullscreenBtn; + + private Player player; + private Media media; + private MediaPlayer mediaPlayer; + + public void init(String file, Player player) { + this.player = player; + + media = new Media(new File(file).toURI().toString()); + mediaPlayer = new MediaPlayer(media); + 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")); + + mediaView.setPreserveRatio(true); + mediaPlayer.play(); + } + + @FXML + void fullscreenBtnAction(ActionEvent event) { + if (player.getStage().isFullScreen()) { + player.getStage().setFullScreen(false); + } else { + player.getStage().setFullScreen(true); + } + } + + @FXML + void playBtnAction(ActionEvent event) { + + if (mediaPlayer.getStatus().equals(Status.PLAYING)) { + mediaPlayer.pause(); + } else { + mediaPlayer.play(); + } + } + + public MediaPlayer getMediaPlayer() { + return mediaPlayer; + } + +} diff --git a/src/main/resources/fxml/PlayerWindow.fxml b/src/main/resources/fxml/PlayerWindow.fxml new file mode 100644 index 0000000..8abe8a4 --- /dev/null +++ b/src/main/resources/fxml/PlayerWindow.fxml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + From a918b0b1d832d566a30dfca611b2de4276df07cc Mon Sep 17 00:00:00 2001 From: Jannik Date: Mon, 2 Apr 2018 02:18:43 +0200 Subject: [PATCH 09/32] new player part 2 * homeflix now saves the progress you made for all films * added icons for the player * added a slider to set the play time for the player * disable contols and cursor if mous is not moved for 5sec, enable it if moved * autoplay, WIP needs testing --- .../application/MainWindowController.java | 23 +-- .../HomeFlix/controller/DBController.java | 56 +++++- .../controller/OMDbAPIController.java | 2 +- .../kellerkinder/HomeFlix/player/Player.java | 15 +- .../HomeFlix/player/PlayerController.java | 167 +++++++++++++++++- src/main/resources/fxml/PlayerWindow.fxml | 26 ++- .../icons/ic_fullscreen_black_24dp_1x.png | Bin 0 -> 90 bytes .../ic_fullscreen_exit_black_24dp_1x.png | Bin 0 -> 93 bytes .../icons/ic_pause_black_24dp_1x.png | Bin 0 -> 81 bytes .../icons/ic_play_arrow_black_24dp_1x.png | Bin 0 -> 150 bytes .../resources/icons/ic_stop_black_24dp_1x.png | Bin 0 -> 82 bytes 11 files changed, 259 insertions(+), 30 deletions(-) create mode 100644 src/main/resources/icons/ic_fullscreen_black_24dp_1x.png create mode 100644 src/main/resources/icons/ic_fullscreen_exit_black_24dp_1x.png create mode 100644 src/main/resources/icons/ic_pause_black_24dp_1x.png create mode 100644 src/main/resources/icons/ic_play_arrow_black_24dp_1x.png create mode 100644 src/main/resources/icons/ic_stop_black_24dp_1x.png diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 2c41075..074fbf4 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -229,7 +229,6 @@ public class MainWindowController { private boolean settingsTrue = false; private boolean autoUpdate = false; private boolean useBeta = false; - private boolean betaPlayer = false; private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; @@ -240,6 +239,7 @@ public class MainWindowController { private String color; private String title; private String streamUrl; + private String currentEp; private String ratingSortType; private String local; private String omdbAPIKey; @@ -500,6 +500,7 @@ public class MainWindowController { next = indexTable + 1; title = columnTitle.getCellData(indexTable); // get name of selected item streamUrl = columnStreamUrl.getCellData(indexTable); // get file path of selected item + currentEp = columnEpisode.getCellData(indexTable); // get the current episode of a series for (FilmTabelDataType helpData : filmsList) { if (helpData.getStreamUrl().equals(streamUrl)) { @@ -548,9 +549,12 @@ public class MainWindowController { private void playbtnclicked() { // TODO rework when #19 is coming - if (betaPlayer) { - new Player(streamUrl); - } else { + try { + System.out.println(); + new Player(streamUrl, currentEp, dbController); + } catch (Exception e) { + LOGGER.error("using fallback player!", e); // FIXME doesn't work! + if (System.getProperty("os.name").contains("Linux")) { String line; String output = ""; @@ -572,22 +576,21 @@ public class MainWindowController { } else { try { Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder - } catch (IOException e) { - showErrorMsg(errorPlay, e); + } catch (IOException e1) { + showErrorMsg(errorPlay, e1); } } } else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) { try { Desktop.getDesktop().open(new File(streamUrl)); - } catch (IOException e) { - showErrorMsg(errorPlay, e); + } catch (IOException e1) { + showErrorMsg(errorPlay, e1); } } else { LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! "); } - } - + } } @FXML diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 7ca7306..410c561 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -99,7 +99,7 @@ public class DBController { private void createDatabase() { try { 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 (" + "streamUrl, Title, Year, Rated, Released, Runtime, Genre, Director, Writer," + " Actors, Plot, Language, Country, Awards, Metascore, imdbRating, imdbVotes," @@ -303,7 +303,7 @@ public class DBController { */ private void checkAddEntry() throws SQLException, FileNotFoundException, IOException { 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 ..."); // source is a single source of the sources list @@ -317,7 +317,7 @@ public class DBController { if (!filmsdbStreamURL.contains(file.getPath())) { stmt.executeUpdate("insert into films values (" + "'" + file.getPath() + "'," - + "'" + cutOffEnd(file.getName()) + "', '', '', 0, 0)"); + + "'" + cutOffEnd(file.getName()) + "', '', '', 0, 0, 0.0)"); connection.commit(); stmt.close(); LOGGER.info("Added \"" + file.getName() + "\" to database"); @@ -334,7 +334,7 @@ public class DBController { LOGGER.info("Added \"" + file.getName() + "\", Episode: " + episode.getName() + " to database"); stmt.executeUpdate("insert into films values (" + "'" + episode.getPath().replace("'", "''") + "'," - + "'" + cutOffEnd(file.getName()) + "','" + sn + "','" + ep + "', 0, 0)"); + + "'" + cutOffEnd(file.getName()) + "','" + sn + "','" + ep + "', 0, 0, 0.0)"); connection.commit(); stmt.close(); filmsStreamURL.add(episode.getPath()); @@ -366,6 +366,7 @@ public class DBController { ps.setString(4, item.asObject().getString("episode", "")); ps.setInt(5, 0); ps.setBoolean(6, false); + ps.setDouble(7, 0); ps.addBatch(); // adds the entry LOGGER.info("Added \"" + title + "\" to database"); filmsdbStreamURL.add(streamUrl); @@ -392,7 +393,8 @@ public class DBController { System.out.println(rs.getString("season")); System.out.println(rs.getString("episode")); 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(); rs.close(); @@ -579,6 +581,50 @@ public class DBController { } } + 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 refreshing mwc!", e); + } + + return currentTime; + } + + 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); + } + } + + public String getNextEpisode(String streamUrl, int nextEp) { + String nextStreamUrl = ""; + try { + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery( + "SELECT * FROM films WHERE streamUrl = \"" + streamUrl + "\" AND episode = " + nextEp + ";"); + nextStreamUrl = rs.getString("streamUrl"); + rs.close(); + stmt.close(); + } catch (Exception e) { + LOGGER.error("Ups! error while refreshing mwc!", e); + } + return nextStreamUrl; + } + + // removes the ending private String cutOffEnd(String str) { if (str == null) return null; diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index 6e8f5cd..a3e7580 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -62,7 +62,7 @@ public class OMDbAPIController implements Runnable { String output = null; String posterPath = null; - // get by title, TODO implement search + // get by title, TODO implement search FIXME set correct info if film dosen't exist try { URL apiUrl = new URL(URL + mainWindowController.getOmdbAPIKey() + "&t=" + mainWindowController.getTitle().replace(" ", "%20")); diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java index e1cc12e..2ee468f 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/Player.java +++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java @@ -10,29 +10,34 @@ import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; import javafx.stage.WindowEvent; import kellerkinder.HomeFlix.application.Main; +import kellerkinder.HomeFlix.controller.DBController; public class Player { private PlayerController playerController; private Stage stage; private AnchorPane pane; + private Scene scene; - public Player(String file) { + public Player(String file, String currentEp, DBController dbController) { try { FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); pane = (AnchorPane) fxmlLoader.load(); stage = new Stage(); - stage.setScene(new Scene(pane)); + 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() { public void handle(WindowEvent we) { + dbController.setCurrentTime(file, playerController.getCurrentTime()); playerController.getMediaPlayer().stop(); + stage.close(); } }); playerController = fxmlLoader.getController(); - playerController.init(file, this); + playerController.init(file, currentEp, this, dbController); stage.setFullScreen(true); stage.show(); @@ -49,4 +54,8 @@ public class Player { return pane; } + public Scene getScene() { + return scene; + } + } diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index cc79eef..238d561 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -1,27 +1,49 @@ 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.controller.DBController; public class PlayerController { @FXML private MediaView mediaView; + + @FXML + private VBox bottomVBox; @FXML - private HBox controllsHBox; + private HBox controlsHBox; + @FXML + private JFXSlider timeSlider; + + @FXML + private JFXButton stopBtn; + @FXML private JFXButton playBtn; @@ -29,14 +51,39 @@ public class PlayerController { private JFXButton fullscreenBtn; private Player player; + private DBController dbController; private Media media; private MediaPlayer mediaPlayer; + + private double currentTime = 0; + private double futureTime= 0; + private double duration = 0; + private boolean mousePressed = false; + private boolean showControls = true; + private String file; + private int nextEp; + + 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")); - public void init(String file, Player player) { + public void init(String file, String currentEp, Player player, DBController dbController) { + this.file = file; this.player = player; + this.dbController = dbController; + initActions(); + + if (currentEp.length() > 0) { + nextEp = Integer.parseInt(currentEp) + 1; + } else { + nextEp = 0; + } media = new Media(new File(file).toURI().toString()); mediaPlayer = new MediaPlayer(media); + mediaView.setPreserveRatio(true); mediaView.setMediaPlayer(mediaPlayer); final DoubleProperty width = mediaView.fitWidthProperty(); @@ -44,17 +91,123 @@ public class PlayerController { width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width")); height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height")); + + mediaPlayer.setOnReady(new Runnable() { + @Override + public void run() { + duration = media.getDuration().toMillis(); + + timeSlider.setMax((duration/1000)/60); - mediaView.setPreserveRatio(true); - mediaPlayer.play(); + mediaPlayer.setStartTime(Duration.millis(dbController.getCurrentTime(file))); + mediaPlayer.play(); + } + }); + + mediaPlayer.currentTimeProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { + + + currentTime = newValue.toMillis(); + + if (duration - currentTime < 10000) { + if (nextEp != 0) { + dbController.getNextEpisode(file, nextEp); + System.out.println("next episode is: " + dbController.getNextEpisode(file, nextEp)); + } else { + if (duration - currentTime < 100) { + dbController.setCurrentTime(file, 0); + mediaPlayer.stop(); + player.getStage().close(); + } + } + } + + if (!mousePressed) { + timeSlider.setValue((currentTime/1000)/60); + } + } + }); + + stopBtn.setGraphic(stop_black); + playBtn.setGraphic(play_arrow_black); + fullscreenBtn.setGraphic(fullscreen_exit_black); + } + + private void initActions() { + + player.getScene().addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler() { + // hide controls timer init + final Timer timer = new Timer(); + TimerTask controlAnimationTask = null; // task to execute save operation + final long delayTime = 5000; + + @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); + } + }); + + timeSlider.setOnMouseReleased(new EventHandler() { + @Override + public void handle(MouseEvent event) { + mediaPlayer.seek(new Duration(futureTime)); + mousePressed = false; + } + }); + + timeSlider.setOnMousePressed(new EventHandler() { + @Override + public void handle(MouseEvent event) { + mousePressed = true; + } + }); + + timeSlider.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Number old_val, Number new_val) { + futureTime = (double) new_val*1000*60; + } + }); + } + + @FXML + void stopBtnAction(ActionEvent event) { + + dbController.setCurrentTime(file, 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); } } @@ -63,8 +216,10 @@ public class PlayerController { if (mediaPlayer.getStatus().equals(Status.PLAYING)) { mediaPlayer.pause(); + playBtn.setGraphic(play_arrow_black); } else { mediaPlayer.play(); + playBtn.setGraphic(pause_black); } } @@ -72,4 +227,8 @@ public class PlayerController { return mediaPlayer; } + public double getCurrentTime() { + return currentTime; + } + } diff --git a/src/main/resources/fxml/PlayerWindow.fxml b/src/main/resources/fxml/PlayerWindow.fxml index 8abe8a4..9008334 100644 --- a/src/main/resources/fxml/PlayerWindow.fxml +++ b/src/main/resources/fxml/PlayerWindow.fxml @@ -1,9 +1,11 @@ + + @@ -13,14 +15,24 @@ - + - - + + + + + + + + + + + + + + + - - - - + diff --git a/src/main/resources/icons/ic_fullscreen_black_24dp_1x.png b/src/main/resources/icons/ic_fullscreen_black_24dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3553d6a5d6c410575bb658b48e95e6a500f49e2c GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1MNb#UkP60RiI)%Td6K#U0-41e n)OimJ^3-g&q^R4Q!@v;bW`FSMsV|R!iWxjz{an^LB{Ts5YOxpV literal 0 HcmV?d00001 diff --git a/src/main/resources/icons/ic_fullscreen_exit_black_24dp_1x.png b/src/main/resources/icons/ic_fullscreen_exit_black_24dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8394487c9c3e539520d57b899313ab0779ed6ab GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*16;Bt(kP60RhQ`1T@*ERyFt2`S q&y&E=&B# wc=B>S&sUzDB`$N=G(DB)Hcp&$#GH%4Jltn(&bImcfEF=$y85}Sb4q9e09LOpNdN!< literal 0 HcmV?d00001 diff --git a/src/main/resources/icons/ic_stop_black_24dp_1x.png b/src/main/resources/icons/ic_stop_black_24dp_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..0588f0b4cf92eca1c16aa65c47550dddf8a39099 GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1NlzEYkP60R1<9VK{}u{-2CEW7 em^%|h7#LjB`wN$O|Lg=RV(@hJb6Mw<&;$UT`4g=G literal 0 HcmV?d00001 From 5e4373d70d0d0778e613ebcde4ffe346b6d4c0df Mon Sep 17 00:00:00 2001 From: Jannik Date: Mon, 2 Apr 2018 18:29:59 +0200 Subject: [PATCH 10/32] documentation work * added a lot of documentation to the code * log4j 2.10 -> 2.11 --- pom.xml | 8 +-- .../HomeFlix/application/Main.java | 22 +++--- .../application/MainWindowController.java | 25 +++++-- .../HomeFlix/controller/DBController.java | 71 +++++++++++++++---- .../controller/OMDbAPIController.java | 1 - .../HomeFlix/controller/UpdateController.java | 1 - .../HomeFlix/datatypes/FilmTabelDataType.java | 2 - .../HomeFlix/datatypes/SourceDataType.java | 1 - .../kellerkinder/HomeFlix/player/Player.java | 28 +++++++- .../HomeFlix/player/PlayerController.java | 33 ++++++++- .../Alerts/JFX2BtnCancelAlert.java | 1 - .../org/kellerkinder/Alerts/JFXInfoAlert.java | 1 - 12 files changed, 151 insertions(+), 43 deletions(-) diff --git a/pom.xml b/pom.xml index 82a9e6f..a31f960 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.kellerkinder Project-HomeFlix - 0.6.0 + 0.6.1 jar Project-HomeFlix @@ -19,7 +19,7 @@ junit junit - 4.11 + 4.12 test @@ -50,13 +50,13 @@ org.apache.logging.log4j log4j-api - 2.10.0 + 2.11.0 org.apache.logging.log4j log4j-core - 2.10.0 + 2.11.0 diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index ee36ce5..2e7356d 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -19,7 +19,6 @@ * MA 02110-1301, USA. * */ - package kellerkinder.HomeFlix.application; import java.io.File; @@ -77,6 +76,10 @@ public class Main extends Application { 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(){ try { FXMLLoader loader = new FXMLLoader(); @@ -111,7 +114,7 @@ public class Main extends Application { // startup checks if (!configFile.exists()) { directory.mkdir(); - getFirstSource(); + addFirstSource(); mainWindowController.setColor("ee3523"); mainWindowController.setSize(FONT_SIZE); mainWindowController.setAutoUpdate(false); @@ -132,10 +135,10 @@ public class Main extends Application { } /** - * TODO add option to add streaming as first source when there i no config.xml - * we need to get the path for the first source from the user + * we need to get the path for the first source from the user and add it to + * sources.json, if the user ends the file-/directory-chooser the program will exit */ - private void getFirstSource() { + private void addFirstSource() { switch (System.getProperty("user.language") + "_" + System.getProperty("user.country")) { case "en_US": bundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US); // us_english @@ -192,6 +195,11 @@ public class Main extends Application { 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) { if (System.getProperty("os.name").equals("Windows")) { System.setProperty("logFilename", userHome + "/Documents/HomeFlix/app.log"); @@ -210,10 +218,6 @@ public class Main extends Application { return primaryStage; } - public void setPrimaryStage(Stage primaryStage) { - this.primaryStage = primaryStage; - } - public AnchorPane getPane() { return pane; } diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 074fbf4..762ed15 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -19,7 +19,6 @@ * MA 02110-1301, USA. * */ - package kellerkinder.HomeFlix.application; import java.awt.Desktop; @@ -759,18 +758,22 @@ 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() { String style = "-fx-background-color: #" + getColor() + ";"; 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;"; - BigInteger icolor = new BigInteger(getColor(), 16); - BigInteger ccolor = new BigInteger("78909cff", 16); + BigInteger usedColor = new BigInteger(getColor(), 16); + BigInteger checkColor = new BigInteger("78909cff", 16); sideMenuVBox.setStyle(style); topHBox.setStyle(style); searchTextField.setFocusColor(Color.valueOf(getColor())); - if (icolor.compareTo(ccolor) == -1) { + if (usedColor.compareTo(checkColor) == -1) { dialogBtnStyle = btnStyleWhite; settingsBtn.setStyle("-fx-text-fill: WHITE;"); aboutBtn.setStyle("-fx-text-fill: WHITE;"); @@ -822,6 +825,9 @@ public class MainWindowController { translateTransition.play(); } + /** + * set the local based on the languageChoisBox selection + */ void setLocalUI() { switch (getLocal()) { case "en_US": @@ -895,7 +901,9 @@ public class MainWindowController { LOGGER.error("An error occurred", exception); } - // save settings + /** + * save the configuration to the config.xml file + */ public void saveSettings() { LOGGER.info("saving settings ..."); try { @@ -907,14 +915,17 @@ public class MainWindowController { props.setProperty("ratingSortType", columnFavorite.getSortType().toString()); 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(); } catch (IOException 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() { LOGGER.info("loading settings ..."); diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 410c561..b5f703f 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ - package kellerkinder.HomeFlix.controller; import java.io.File; @@ -53,12 +52,7 @@ import kellerkinder.HomeFlix.datatypes.SourceDataType; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class DBController { - - public DBController(Main main, MainWindowController mainWindowController) { - this.main = main; - this.mainWindowController = mainWindowController; - } - + private MainWindowController mainWindowController; private Main main; private String DB_PATH = System.getProperty("user.home") + "\\Documents\\HomeFlix" + "\\" + "Homeflix.db"; //path to database file @@ -71,6 +65,22 @@ public class DBController { private Connection connection = null; 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() { LOGGER.info("<========== starting loading sql ==========>"); initDatabaseConnection(); @@ -79,12 +89,16 @@ public class DBController { 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() { DB_PATH = main.getDirectory() + "/Homeflix.db"; try { // create a database connection connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH); - connection.setAutoCommit(false); //AutoCommit to false -> manual commit is active + connection.setAutoCommit(false); } catch (SQLException e) { // 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); @@ -94,6 +108,7 @@ public class DBController { /** * if tables don't exist create them + * films table: streamUrl is primary key * cache table: streamUrl is primary key */ private void createDatabase() { @@ -110,6 +125,9 @@ public class DBController { } } + /** + * get all database entries + */ private void loadDatabase() { // get all entries from the table try { @@ -131,7 +149,11 @@ public class DBController { 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() { // remove sources from table mainWindowController.getSourcesList().removeAll(mainWindowController.getSourcesList()); @@ -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() { LOGGER.info("loading data to mwc ..."); try { @@ -381,7 +406,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() { System.out.println("Outputting all entries ... \n"); try { @@ -581,6 +609,11 @@ 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; @@ -597,6 +630,11 @@ public class DBController { 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 { @@ -609,12 +647,18 @@ public class DBController { } } - public String getNextEpisode(String streamUrl, int nextEp) { + /** + * get the next episode of a + * @param title URL of the film + * @param nextEp number of the next episode + * @return {@link String} the streamUrl of the next episode + */ + public String getNextEpisode(String title, int nextEp) { String nextStreamUrl = ""; try { Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery( - "SELECT * FROM films WHERE streamUrl = \"" + streamUrl + "\" AND episode = " + nextEp + ";"); + "SELECT * FROM films WHERE title = \"" + title + "\" AND episode = " + nextEp + ";"); nextStreamUrl = rs.getString("streamUrl"); rs.close(); stmt.close(); @@ -624,7 +668,6 @@ public class DBController { return nextStreamUrl; } - // removes the ending private String cutOffEnd(String str) { if (str == null) return null; diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index a3e7580..b2bee2a 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -19,7 +19,6 @@ * MA 02110-1301, USA. * */ - package kellerkinder.HomeFlix.controller; import java.awt.image.BufferedImage; diff --git a/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java b/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java index a21b376..150f3d4 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ - package kellerkinder.HomeFlix.controller; import java.io.BufferedReader; diff --git a/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java b/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java index 3bc51b1..c2b86da 100644 --- a/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java +++ b/src/main/java/kellerkinder/HomeFlix/datatypes/FilmTabelDataType.java @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ - package kellerkinder.HomeFlix.datatypes; import javafx.beans.property.BooleanProperty; @@ -36,7 +35,6 @@ public class FilmTabelDataType { private final BooleanProperty favorite = new SimpleBooleanProperty(); private final BooleanProperty cached = new SimpleBooleanProperty(); private final SimpleObjectProperty image = new SimpleObjectProperty<>(); - /** * tableData is the data-type of tree-table-view diff --git a/src/main/java/kellerkinder/HomeFlix/datatypes/SourceDataType.java b/src/main/java/kellerkinder/HomeFlix/datatypes/SourceDataType.java index aab7fa5..fec991a 100644 --- a/src/main/java/kellerkinder/HomeFlix/datatypes/SourceDataType.java +++ b/src/main/java/kellerkinder/HomeFlix/datatypes/SourceDataType.java @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ - package kellerkinder.HomeFlix.datatypes; import javafx.beans.property.SimpleStringProperty; diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java index 2ee468f..276e144 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/Player.java +++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java @@ -1,6 +1,26 @@ +/** + * 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; @@ -19,6 +39,12 @@ public class Player { private AnchorPane pane; private Scene scene; + /** + * generate a new PlayerWindow + * @param file the file you want to play + * @param currentEp the current episode (needed for autoplay) + * @param dbController the dbController object + */ public Player(String file, String currentEp, DBController dbController) { try { FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 238d561..0c7d47c 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -1,3 +1,24 @@ +/** + * 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; @@ -69,6 +90,13 @@ public class PlayerController { 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")); + /** + * initialize the new PlayerWindow + * @param file the file you want to play + * @param currentEp the current episode (needed for autoplay) + * @param player the player object (needed for closing action) + * @param dbController the dbController object + */ public void init(String file, String currentEp, Player player, DBController dbController) { this.file = file; this.player = player; @@ -113,7 +141,7 @@ public class PlayerController { if (duration - currentTime < 10000) { if (nextEp != 0) { - dbController.getNextEpisode(file, nextEp); + dbController.getNextEpisode(new File(file).getName(), nextEp); System.out.println("next episode is: " + dbController.getNextEpisode(file, nextEp)); } else { if (duration - currentTime < 100) { @@ -135,6 +163,9 @@ public class PlayerController { fullscreenBtn.setGraphic(fullscreen_exit_black); } + /** + * initialize some PlayerWindow GUI-Elements actions + */ private void initActions() { player.getScene().addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler() { diff --git a/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java b/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java index 8272b1d..63b8ff2 100644 --- a/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java +++ b/src/main/java/org/kellerkinder/Alerts/JFX2BtnCancelAlert.java @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ - package org.kellerkinder.Alerts; import com.jfoenix.controls.JFXAlert; diff --git a/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java b/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java index 2375b4d..ab31c4d 100644 --- a/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java +++ b/src/main/java/org/kellerkinder/Alerts/JFXInfoAlert.java @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ - package org.kellerkinder.Alerts; import com.jfoenix.controls.JFXAlert; From 0379de6179fc3535eea4e5b3373d36ee28169140 Mon Sep 17 00:00:00 2001 From: Jannik Date: Tue, 3 Apr 2018 18:03:43 +0200 Subject: [PATCH 11/32] fixed time slider and autoplay * fixed a bug that made it impossible to go further back than the start time * fixed autoplay * fixed wrong icon on playBtn at the start of the player * fixed slider position at start of the player --- .../HomeFlix/application/Main.java | 7 ++ .../application/MainWindowController.java | 43 ++++++++----- .../HomeFlix/controller/DBController.java | 25 +++++--- .../kellerkinder/HomeFlix/player/Player.java | 16 +++-- .../HomeFlix/player/PlayerController.java | 64 ++++++++++--------- 5 files changed, 95 insertions(+), 60 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index 2e7356d..ec61e95 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -40,6 +40,7 @@ import javafx.scene.layout.AnchorPane; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.stage.Stage; +import javafx.stage.WindowEvent; public class Main extends Application { @@ -90,6 +91,12 @@ public class Main extends Application { primaryStage.setResizable(false); primaryStage.setTitle("Project HomeFlix"); primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); //adds application icon + primaryStage.setOnCloseRequest(new EventHandler() { + public void handle(WindowEvent we) { + System.exit(1); + } + }); + mainWindowController = loader.getController(); //Link of FXMLController and controller class mainWindowController.setMain(this); //call setMain diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 762ed15..1e47552 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -231,14 +231,13 @@ public class MainWindowController { private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; - private String version = "0.6.1"; - private String buildNumber = "145"; + private String version = "0.6.99"; + private String buildNumber = "147"; private String versionName = "glowing vampire"; private String dialogBtnStyle; private String color; private String title; private String streamUrl; - private String currentEp; private String ratingSortType; private String local; private String omdbAPIKey; @@ -256,7 +255,8 @@ public class MainWindowController { private int indexList; private int next; private ResourceBundle bundle; - + private FilmTabelDataType currentFilm; + private ObservableList languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)"); private ObservableList branches = FXCollections.observableArrayList("stable", "beta"); private ObservableList filterData = FXCollections.observableArrayList(); @@ -499,7 +499,6 @@ public class MainWindowController { next = indexTable + 1; title = columnTitle.getCellData(indexTable); // get name of selected item streamUrl = columnStreamUrl.getCellData(indexTable); // get file path of selected item - currentEp = columnEpisode.getCellData(indexTable); // get the current episode of a series for (FilmTabelDataType helpData : filmsList) { if (helpData.getStreamUrl().equals(streamUrl)) { @@ -507,6 +506,8 @@ public class MainWindowController { } } + currentFilm = filmsList.get(indexList); + if (filmsList.get(indexList).getCached()) { LOGGER.info("loading from cache: " + title); dbController.readCache(streamUrl); @@ -545,14 +546,11 @@ public class MainWindowController { } @FXML - private void playbtnclicked() { - // TODO rework when #19 is coming - - try { - System.out.println(); - new Player(streamUrl, currentEp, dbController); - } catch (Exception e) { - LOGGER.error("using fallback player!", e); // FIXME doesn't work! + private void playbtnclicked() { + if (isSupportedFormat(currentFilm)) { + new Player(currentFilm, dbController); + } else { + LOGGER.error("using fallback player!"); if (System.getProperty("os.name").contains("Linux")) { String line; @@ -574,7 +572,7 @@ public class MainWindowController { vlcInfoAlert.showAndWait(); } else { try { - Runtime.getRuntime().exec(new String[] { "vlc", streamUrl }); // TODO switch to ProcessBuilder + new ProcessBuilder("vlc", streamUrl).start(); } catch (IOException e1) { showErrorMsg(errorPlay, e1); } @@ -589,7 +587,20 @@ public class MainWindowController { } else { LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! "); } - } + } + } + + /** TODO improve function + * check if a film is supported by the HomeFlixPlayer or not + * @param entry the film you want to check + * @return true if so, false if not + */ + private boolean isSupportedFormat(FilmTabelDataType film) { + if (film.getStreamUrl().endsWith(".mp4")) { + return true; + } else { + return false; + } } @FXML @@ -868,7 +879,7 @@ public class MainWindowController { vlcNotInstalled = getBundle().getString("vlcNotInstalled"); } - // TODO remove after #19 has landed + // TODO rework after #19 has landed public void showErrorMsg(String msg, Exception exception) { Alert alert = new Alert(AlertType.ERROR); alert.setTitle("Error"); diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index b5f703f..07386b5 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -651,21 +651,30 @@ public class DBController { * get the next episode of a * @param title URL of the film * @param nextEp number of the next episode - * @return {@link String} the streamUrl of the next episode + * @return {@link FilmTabelDataType} the next episode as object */ - public String getNextEpisode(String title, int nextEp) { - String nextStreamUrl = ""; + public FilmTabelDataType getNextEpisode(String title, int nextEp) { + FilmTabelDataType nextFilm = null; try { Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery( - "SELECT * FROM films WHERE title = \"" + title + "\" AND episode = " + nextEp + ";"); - nextStreamUrl = rs.getString("streamUrl"); + ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND episode = \"" + nextEp + "\";"); + 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)); + } + } rs.close(); stmt.close(); } catch (Exception e) { - LOGGER.error("Ups! error while refreshing mwc!", e); + LOGGER.error("Ups! error while getting next episode!", e); } - return nextStreamUrl; + return nextFilm; } // removes the ending diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java index 276e144..5bbc3c2 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/Player.java +++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java @@ -31,21 +31,23 @@ import javafx.stage.Stage; import javafx.stage.WindowEvent; import kellerkinder.HomeFlix.application.Main; import kellerkinder.HomeFlix.controller.DBController; +import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class Player { private PlayerController playerController; + private DBController dbController; private Stage stage; private AnchorPane pane; private Scene scene; /** * generate a new PlayerWindow - * @param file the file you want to play - * @param currentEp the current episode (needed for autoplay) + * @param entry the film object * @param dbController the dbController object */ - public Player(String file, String currentEp, DBController dbController) { + public Player(FilmTabelDataType film, DBController dbController) { + this.dbController = dbController; try { FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); pane = (AnchorPane) fxmlLoader.load(); @@ -56,14 +58,14 @@ public class Player { stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); stage.setOnCloseRequest(new EventHandler() { public void handle(WindowEvent we) { - dbController.setCurrentTime(file, playerController.getCurrentTime()); + dbController.setCurrentTime(film.getStreamUrl(), playerController.getCurrentTime()); playerController.getMediaPlayer().stop(); stage.close(); } }); playerController = fxmlLoader.getController(); - playerController.init(file, currentEp, this, dbController); + playerController.init(film, this, dbController); stage.setFullScreen(true); stage.show(); @@ -71,6 +73,10 @@ public class Player { e.printStackTrace(); } } + + public void playNewFilm(FilmTabelDataType film) { + playerController.init(film, this, dbController); + } public Stage getStage() { return stage; diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 0c7d47c..b2c250a 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -47,6 +47,7 @@ import javafx.scene.media.MediaPlayer.Status; import javafx.scene.media.MediaView; import javafx.util.Duration; import kellerkinder.HomeFlix.controller.DBController; +import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class PlayerController { @@ -76,13 +77,14 @@ public class PlayerController { private Media media; private MediaPlayer mediaPlayer; + private FilmTabelDataType film; private double currentTime = 0; - private double futureTime= 0; + private double seekTime = 0; + private double startTime = 0; private double duration = 0; private boolean mousePressed = false; private boolean showControls = true; - private String file; - private int nextEp; + private boolean autoplay = true; 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")); @@ -92,24 +94,23 @@ public class PlayerController { /** * initialize the new PlayerWindow - * @param file the file you want to play - * @param currentEp the current episode (needed for autoplay) + * @param entry the film object * @param player the player object (needed for closing action) * @param dbController the dbController object */ - public void init(String file, String currentEp, Player player, DBController dbController) { - this.file = file; + public void init(FilmTabelDataType film, Player player, DBController dbController) { + this.film = film; this.player = player; this.dbController = dbController; initActions(); - if (currentEp.length() > 0) { - nextEp = Integer.parseInt(currentEp) + 1; + if (film.getStreamUrl().startsWith("http")) { + media = new Media(film.getStreamUrl()); } else { - nextEp = 0; + media = new Media(new File(film.getStreamUrl()).toURI().toString()); } + startTime = dbController.getCurrentTime(film.getStreamUrl()); - media = new Media(new File(file).toURI().toString()); mediaPlayer = new MediaPlayer(media); mediaView.setPreserveRatio(true); mediaView.setMediaPlayer(mediaPlayer); @@ -119,7 +120,7 @@ public class PlayerController { width.bind(Bindings.selectDouble(mediaView.sceneProperty(), "width")); height.bind(Bindings.selectDouble(mediaView.sceneProperty(), "height")); - + mediaPlayer.setOnReady(new Runnable() { @Override public void run() { @@ -127,29 +128,29 @@ public class PlayerController { timeSlider.setMax((duration/1000)/60); - mediaPlayer.setStartTime(Duration.millis(dbController.getCurrentTime(file))); - mediaPlayer.play(); + mediaPlayer.play(); + mediaPlayer.seek(Duration.millis(startTime)); } }); mediaPlayer.currentTimeProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { - - currentTime = newValue.toMillis(); + int episode = Integer.parseInt(film.getEpisode()); - if (duration - currentTime < 10000) { - if (nextEp != 0) { - dbController.getNextEpisode(new File(file).getName(), nextEp); - System.out.println("next episode is: " + dbController.getNextEpisode(file, nextEp)); - } else { - if (duration - currentTime < 100) { - dbController.setCurrentTime(file, 0); - mediaPlayer.stop(); - player.getStage().close(); - } - } + if ((duration - currentTime) < 10000 && episode != 0 && autoplay) { + autoplay = false; + dbController.setCurrentTime(film.getStreamUrl(), 0); // reset old video start time + + //start the new film + System.out.println("next episode is: " + dbController.getNextEpisode(film.getTitle(), episode + 1)); + mediaPlayer.stop(); + player.playNewFilm(dbController.getNextEpisode(film.getTitle(), episode + 1)); + } else if ((duration - currentTime) < 100) { + dbController.setCurrentTime(film.getStreamUrl(), 0); + mediaPlayer.stop(); + player.getStage().close(); } if (!mousePressed) { @@ -159,8 +160,9 @@ public class PlayerController { }); stopBtn.setGraphic(stop_black); - playBtn.setGraphic(play_arrow_black); + playBtn.setGraphic(pause_black); fullscreenBtn.setGraphic(fullscreen_exit_black); + timeSlider.setValue(0); } /** @@ -202,7 +204,7 @@ public class PlayerController { timeSlider.setOnMouseReleased(new EventHandler() { @Override public void handle(MouseEvent event) { - mediaPlayer.seek(new Duration(futureTime)); + mediaPlayer.seek(new Duration(seekTime)); mousePressed = false; } }); @@ -217,7 +219,7 @@ public class PlayerController { timeSlider.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, Number old_val, Number new_val) { - futureTime = (double) new_val*1000*60; + seekTime = (double) new_val*1000*60; } }); } @@ -225,7 +227,7 @@ public class PlayerController { @FXML void stopBtnAction(ActionEvent event) { - dbController.setCurrentTime(file, currentTime); + dbController.setCurrentTime(film.getStreamUrl(), currentTime); mediaPlayer.stop(); player.getStage().close(); From 2c3e9fd5e735c92de103193917e815791df2ab38 Mon Sep 17 00:00:00 2001 From: Jannik Date: Tue, 3 Apr 2018 18:23:54 +0200 Subject: [PATCH 12/32] autoplay fixes --- .../HomeFlix/application/MainWindowController.java | 3 +++ .../HomeFlix/controller/DBController.java | 2 +- .../HomeFlix/player/PlayerController.java | 12 +++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 1e47552..dba46e0 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -717,6 +717,7 @@ public class MainWindowController { // check if there is a series node to add the item for (int i = 0; i < filmRoot.getChildren().size(); i++) { if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) { + // if a root node exists, add element as child // System.out.println("Found a root node to add child"); // System.out.println("Adding: " + element.getStreamUrl()); TreeItem episodeNode = new TreeItem<>(new FilmTabelDataType(element.getStreamUrl(), @@ -724,8 +725,10 @@ public class MainWindowController { element.getCached(), element.getImage())); filmRoot.getChildren().get(i).getChildren().add(episodeNode); } else if (i == filmRoot.getChildren().size() - 1) { + // if no root node exists, create one and add element as child // System.out.println("Create a root node to add child"); // System.out.println("Adding: " + element.getStreamUrl()); + // TODO get the last watched episode, the first one with currentTime != 0 TreeItem seriesRootNode = new TreeItem<>(new FilmTabelDataType(element.getStreamUrl(), element.getTitle(), "", "", element.getFavorite(), element.getCached(), element.getImage())); filmRoot.getChildren().add(seriesRootNode); diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 07386b5..803dec9 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -236,7 +236,7 @@ public class DBController { } /** - * refresh data in mainWindowController localFilms and streamingFilms + * refresh data in mainWindowController for one element * @param streamUrl of the film * @param index of the film in LocalFilms list */ diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index b2c250a..e15ad32 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -144,13 +144,15 @@ public class PlayerController { dbController.setCurrentTime(film.getStreamUrl(), 0); // reset old video start time //start the new film - System.out.println("next episode is: " + dbController.getNextEpisode(film.getTitle(), episode + 1)); - mediaPlayer.stop(); - player.playNewFilm(dbController.getNextEpisode(film.getTitle(), episode + 1)); + FilmTabelDataType nextFilm = dbController.getNextEpisode(film.getTitle(), episode + 1); + if (nextFilm != null) { +// System.out.println("next episode is: " + nextFilm.getStreamUrl()); + mediaPlayer.stop(); + player.playNewFilm(nextFilm); + autoplay = true; + } } else if ((duration - currentTime) < 100) { - dbController.setCurrentTime(film.getStreamUrl(), 0); mediaPlayer.stop(); - player.getStage().close(); } if (!mousePressed) { From d6554b9acd5c3e0784188ae33cdb886e526b1876 Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 5 Apr 2018 12:09:39 +0200 Subject: [PATCH 13/32] minor player fixes and no more other files than videos in the db * fixed episode = ""resulting in many exceptons * only add video files to the database (and GUI) * check the videos mimetype to decide which player is used --- .../application/MainWindowController.java | 20 ++++++++------ .../HomeFlix/controller/DBController.java | 27 ++++++++++++------- .../HomeFlix/player/PlayerController.java | 3 ++- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index dba46e0..520ec40 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -36,6 +36,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.math.BigInteger; +import java.net.URLConnection; import java.util.ArrayList; import java.util.Locale; import java.util.Properties; @@ -596,11 +597,8 @@ public class MainWindowController { * @return true if so, false if not */ private boolean isSupportedFormat(FilmTabelDataType film) { - if (film.getStreamUrl().endsWith(".mp4")) { - return true; - } else { - return false; - } + String mimeType = URLConnection.guessContentTypeFromName(film.getStreamUrl()); + return mimeType != null && mimeType.contains("mp4"); } @FXML @@ -997,9 +995,15 @@ public class MainWindowController { // try loading the omdbAPI key try { InputStream in = getClass().getClassLoader().getResourceAsStream("apiKeys.json"); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - JsonObject apiKeys = Json.parse(reader).asObject(); - omdbAPIKey = apiKeys.getString("omdbAPIKey", ""); + if (in != null) { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + JsonObject apiKeys = Json.parse(reader).asObject(); + omdbAPIKey = apiKeys.getString("omdbAPIKey", ""); + reader.close(); + in.close(); + } else { + LOGGER.warn("Cloud not load apiKeys.json. No such file"); + } } catch (Exception e) { LOGGER.error("Cloud not load the omdbAPI key. Please contact the developer!", e); } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 803dec9..1d05e7b 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.net.URLConnection; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -167,10 +168,9 @@ public class DBController { mainWindowController.addSourceToTable(path, mode); // add source to source-table if (mode.equals("local")) { for (File file : new File(path).listFiles()) { - if (file.isFile()) { - // get all files (films) + if (file.isFile() && isVideoFile(file.getPath())) { filmsStreamURL.add(file.getPath()); - } else { + } else if(file.isDirectory()) { // get all folders (series) for (File season : file.listFiles()) { if (season.isDirectory()) { @@ -272,15 +272,14 @@ public class DBController { LOGGER.info("refreshing the Database ..."); // clean all ArraLists - filmsdbAll.removeAll(filmsdbAll); - filmsdbDir.removeAll(filmsdbDir); - filmsdbStreamURL.removeAll(filmsdbStreamURL); - filmsStreamURL.removeAll(filmsStreamURL); + filmsdbAll.clear(); + filmsdbDir.clear(); + filmsdbStreamURL.clear(); + filmsStreamURL.clear(); loadSources(); // reload all sources loadDatabase(); // reload all films saved in the DB - try { checkAddEntry(); checkRemoveEntry(); @@ -306,8 +305,6 @@ public class DBController { for (String entry : filmsdbStreamURL) { if (!filmsStreamURL.contains(entry)) { - System.out.println(filmsdbStreamURL + "\n"); - System.out.println(filmsStreamURL); stmt.executeUpdate("delete from films where streamUrl = \"" + entry + "\""); connection.commit(); LOGGER.info("removed \"" + entry + "\" from database"); @@ -685,4 +682,14 @@ public class DBController { 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"); + } + } diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index e15ad32..4ce8b3f 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -137,7 +137,8 @@ public class PlayerController { @Override public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { currentTime = newValue.toMillis(); - int episode = Integer.parseInt(film.getEpisode()); + int episode = 0; + if (film.getEpisode().length() != 0) episode = Integer.parseInt(film.getEpisode()); if ((duration - currentTime) < 10000 && episode != 0 && autoplay) { autoplay = false; From 3afc836df79bdfcf4be28c4480cd595e89a65949 Mon Sep 17 00:00:00 2001 From: Jannik Date: Fri, 6 Apr 2018 20:33:56 +0200 Subject: [PATCH 14/32] code cleanup --- .classpath | 5 +- .settings/org.eclipse.jdt.core.prefs | 8 ++ .../application/MainWindowController.java | 118 +++++++----------- .../controller/OMDbAPIController.java | 10 +- .../HomeFlix/player/PlayerController.java | 4 +- 5 files changed, 64 insertions(+), 81 deletions(-) diff --git a/.classpath b/.classpath index eab655a..d9ff1e3 100644 --- a/.classpath +++ b/.classpath @@ -17,12 +17,13 @@ - + + - + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 4a6c6b8..6f1d295 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,13 @@ 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.unusedLocal=preserve 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.source=9 diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 520ec40..59f9e0b 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -1,6 +1,6 @@ /** * Project-HomeFlix - * + * * Copyright 2016-2018 <@Seil0> * * This program is free software; you can redistribute it and/or modify @@ -37,7 +37,6 @@ import java.io.StringWriter; import java.io.Writer; import java.math.BigInteger; import java.net.URLConnection; -import java.util.ArrayList; import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; @@ -237,8 +236,6 @@ public class MainWindowController { private String versionName = "glowing vampire"; private String dialogBtnStyle; private String color; - private String title; - private String streamUrl; private String ratingSortType; private String local; private String omdbAPIKey; @@ -256,7 +253,7 @@ public class MainWindowController { private int indexList; private int next; private ResourceBundle bundle; - private FilmTabelDataType currentFilm; + private FilmTabelDataType currentTableFilm = new FilmTabelDataType("", "", "", "", false, false, null); private ObservableList languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)"); private ObservableList branches = FXCollections.observableArrayList("stable", "beta"); @@ -296,8 +293,8 @@ public class MainWindowController { loadSettings(); checkAutoUpdate(); initTabel(); - initActions(); initUI(); + initActions(); } // Initialize the tables (treeTableViewfilm and sourcesTable) @@ -415,8 +412,8 @@ public class MainWindowController { @Override public void changed(ObservableValue ov, Number old_val, Number new_val) { setSize(fontsizeSlider.getValue()); - if (title != null) { - dbController.readCache(streamUrl); + if (!getCurrentTitle().isEmpty()) { + dbController.readCache(getCurrentStreamUrl()); } // ta1.setFont(Font.font("System", size)); saveSettings(); @@ -426,8 +423,8 @@ public class MainWindowController { like.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - dbController.like(streamUrl); - dbController.refresh(streamUrl, indexList); + dbController.like(getCurrentStreamUrl()); + dbController.refresh(getCurrentStreamUrl(), indexList); refreshTable(); } }); @@ -435,8 +432,8 @@ public class MainWindowController { dislike.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - dbController.dislike(streamUrl); - dbController.refresh(streamUrl, indexList); + dbController.dislike(getCurrentStreamUrl()); + dbController.refresh(getCurrentStreamUrl(), indexList); refreshTable(); } }); @@ -448,45 +445,25 @@ public class MainWindowController { columnFavorite.sortTypeProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue paramObservableValue, SortType paramT1, SortType paramT2) { - LOGGER.info("NAME Clicked -- sortType = " + paramT1 + ", SortType=" + paramT2); - ArrayList fav_true = new ArrayList(); - ArrayList fav_false = new ArrayList(); - ObservableList helpData; - filterData.removeAll(filterData); -// treeTableViewfilm.getSelectionModel().clearSelection(selected); - filmRoot.getChildren().removeAll(filmRoot.getChildren()); - - helpData = filmsList; - - for (int i = 0; i < helpData.size(); i++) { - if (helpData.get(i).getFavorite() == true) { - fav_true.add(i); - } else { - fav_false.add(i); - } - } - 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))); + filmRoot.getChildren().clear(); + + if (paramT2.equals(SortType.DESCENDING)) { + for (FilmTabelDataType film : filmsList) { + if (film.getFavorite()) { + filmRoot.getChildren().add(0, new TreeItem(film)); + } else { + filmRoot.getChildren().add(new TreeItem(film)); + } } } else { - for (int i = 0; i < fav_false.size(); i++) { - filterData.add(helpData.get(fav_false.get(i))); + System.out.println("ascending"); + for (FilmTabelDataType film : filmsList) { + if (!film.getFavorite()) { + filmRoot.getChildren().add(new TreeItem(film)); + } else { + filmRoot.getChildren().add(new TreeItem(film)); + } } - for (int i = 0; i < fav_true.size(); i++) { - filterData.add(helpData.get(fav_true.get(i))); - } - } - - LOGGER.info(filterData.size()); // Debug, delete? - 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(filterData.get(i))); } } }); @@ -495,23 +472,16 @@ public class MainWindowController { filmsTreeTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Object oldVal, Object newVal) { - indexTable = filmsTreeTable.getSelectionModel().getSelectedIndex(); // get selected item + currentTableFilm = filmsTreeTable.getSelectionModel().getSelectedItem().getValue(); // set the current film object + indexList = filmsList.indexOf(currentTableFilm); // get selected items list index + indexTable = filmsTreeTable.getSelectionModel().getSelectedIndex(); // get selected items table index + last = 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 (helpData.getStreamUrl().equals(streamUrl)) { - indexList = filmsList.indexOf(helpData); - } - } - - currentFilm = filmsList.get(indexList); - - if (filmsList.get(indexList).getCached()) { - LOGGER.info("loading from cache: " + title); - dbController.readCache(streamUrl); + if (currentTableFilm.getCached()) { + LOGGER.info("loading from cache: " + getCurrentTitle()); + dbController.readCache(getCurrentStreamUrl()); } else { omdbAPIController = new OMDbAPIController(mainWindowController, dbController, main); Thread omdbAPIThread = new Thread(omdbAPIController); @@ -548,8 +518,8 @@ public class MainWindowController { @FXML private void playbtnclicked() { - if (isSupportedFormat(currentFilm)) { - new Player(currentFilm, dbController); + if (isSupportedFormat(currentTableFilm)) { + new Player(currentTableFilm, dbController); } else { LOGGER.error("using fallback player!"); @@ -573,7 +543,7 @@ public class MainWindowController { vlcInfoAlert.showAndWait(); } else { try { - new ProcessBuilder("vlc", streamUrl).start(); + new ProcessBuilder("vlc", getCurrentStreamUrl()).start(); } catch (IOException e1) { showErrorMsg(errorPlay, e1); } @@ -581,7 +551,7 @@ public class MainWindowController { } else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) { try { - Desktop.getDesktop().open(new File(streamUrl)); + Desktop.getDesktop().open(new File(getCurrentStreamUrl())); } catch (IOException e1) { showErrorMsg(errorPlay, e1); } @@ -603,7 +573,7 @@ public class MainWindowController { @FXML private void openfolderbtnclicked() { - String dest = new File(streamUrl).getParentFile().getAbsolutePath(); + String dest = new File(getCurrentStreamUrl()).getParentFile().getAbsolutePath(); if (!System.getProperty("os.name").contains("Linux")) { try { Desktop.getDesktop().open(new File(dest)); @@ -699,6 +669,12 @@ public class MainWindowController { // refresh the selected child of the root node private void refreshTable() { + System.out.println("refresh"); + System.out.println(filmRoot.getChildren().get(indexTable).getValue()); + System.out.println(currentTableFilm); + +// filmRoot.getChildren().get() + filmRoot.getChildren().get(indexTable).setValue(filmsList.get(indexList)); } @@ -1047,12 +1023,12 @@ public class MainWindowController { return color; } - public String getTitle() { - return title; + public String getCurrentTitle() { + return currentTableFilm.getTitle(); } - public String getStreamUrl() { - return streamUrl; + public String getCurrentStreamUrl() { + return currentTableFilm.getStreamUrl(); } public void setSize(Double input) { diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index b2bee2a..db0ee80 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -64,7 +64,7 @@ public class OMDbAPIController implements Runnable { // get by title, TODO implement search FIXME set correct info if film dosen't exist try { URL apiUrl = new URL(URL + mainWindowController.getOmdbAPIKey() + "&t=" - + mainWindowController.getTitle().replace(" ", "%20")); + + mainWindowController.getCurrentTitle().replace(" ", "%20")); BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream())); output = ina.readLine(); ina.close(); @@ -102,7 +102,7 @@ public class OMDbAPIController implements Runnable { //resize the image to fit in the posterImageView and add it to the cache try { 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)); LOGGER.info("adding poster to cache: "+posterPath); } catch (Exception e) { @@ -110,16 +110,16 @@ public class OMDbAPIController implements Runnable { } // 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[7], responseString[8], responseString[9], responseString[10], responseString[11], responseString[12], responseString[13], responseString[14], responseString[15], responseString[16], responseString[17], posterPath, responseString[19]); - dbController.setCached(mainWindowController.getStreamUrl()); + dbController.setCached(mainWindowController.getCurrentStreamUrl()); // load data to the MainWindowController Platform.runLater(() -> { - dbController.readCache(mainWindowController.getStreamUrl()); + dbController.readCache(mainWindowController.getCurrentStreamUrl()); }); } } diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 4ce8b3f..6a25342 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -137,8 +137,7 @@ public class PlayerController { @Override public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { currentTime = newValue.toMillis(); - int episode = 0; - if (film.getEpisode().length() != 0) episode = Integer.parseInt(film.getEpisode()); + int episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 0; if ((duration - currentTime) < 10000 && episode != 0 && autoplay) { autoplay = false; @@ -147,7 +146,6 @@ public class PlayerController { //start the new film FilmTabelDataType nextFilm = dbController.getNextEpisode(film.getTitle(), episode + 1); if (nextFilm != null) { -// System.out.println("next episode is: " + nextFilm.getStreamUrl()); mediaPlayer.stop(); player.playNewFilm(nextFilm); autoplay = true; From ee3ec73a638f66dfd52fe0fb8eba16e6f82ff66a Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 7 Apr 2018 12:49:00 +0200 Subject: [PATCH 15/32] fixed series are expanded when sorting * fixed series are expanded when sorting * fixed null pointer exception when sorting --- .../application/MainWindowController.java | 28 +++++++++++++------ .../HomeFlix/controller/DBController.java | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 59f9e0b..f6d918b 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -363,7 +363,7 @@ public class MainWindowController { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { ObservableList helpData; - filterData.removeAll(filterData); + filterData.clear(); filmRoot.getChildren().removeAll(filmRoot.getChildren()); helpData = filmsList; @@ -440,31 +440,33 @@ public class MainWindowController { /** * FIXME fix bug when sort by ASCENDING, wrong order - * FIXME when sorting, series are expanded */ columnFavorite.sortTypeProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue paramObservableValue, SortType paramT1, SortType paramT2) { filmRoot.getChildren().clear(); + filterData.clear(); if (paramT2.equals(SortType.DESCENDING)) { for (FilmTabelDataType film : filmsList) { if (film.getFavorite()) { - filmRoot.getChildren().add(0, new TreeItem(film)); + filterData.add(0, film); } else { - filmRoot.getChildren().add(new TreeItem(film)); + filterData.add(film); } } } else { System.out.println("ascending"); for (FilmTabelDataType film : filmsList) { if (!film.getFavorite()) { - filmRoot.getChildren().add(new TreeItem(film)); + filterData.add(0, film); } else { - filmRoot.getChildren().add(new TreeItem(film)); + filterData.add(film); } } } + + addDataUI(filterData); } }); @@ -472,9 +474,17 @@ public class MainWindowController { filmsTreeTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Object oldVal, Object newVal) { + if (filmsTreeTable.getSelectionModel().getSelectedItem() == null) { + return; + } + currentTableFilm = filmsTreeTable.getSelectionModel().getSelectedItem().getValue(); // set the current film object - indexList = filmsList.indexOf(currentTableFilm); // get selected items list index 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; next = indexTable + 1; @@ -681,9 +691,9 @@ public class MainWindowController { /** * add data from films-list to films-table */ - public void addDataUI() { + public void addDataUI(ObservableList elementsList) { - for (FilmTabelDataType element : filmsList) { + for (FilmTabelDataType element : elementsList) { // only if the entry contains a season and a episode it's a valid series if (!element.getSeason().isEmpty() && !element.getEpisode().isEmpty()) { diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 1d05e7b..b91d970 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -232,7 +232,7 @@ public class DBController { } LOGGER.info("loading data to the GUI ..."); - mainWindowController.addDataUI(); + mainWindowController.addDataUI(mainWindowController.getFilmsList()); } /** From 87b3eae9fbacccd8481f2e1c314fd8b508303b9c Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 7 Apr 2018 14:11:51 +0200 Subject: [PATCH 16/32] set time to hide controlls to 1 second --- .../java/kellerkinder/HomeFlix/player/PlayerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 6a25342..fdad932 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -175,7 +175,7 @@ public class PlayerController { // hide controls timer init final Timer timer = new Timer(); TimerTask controlAnimationTask = null; // task to execute save operation - final long delayTime = 5000; + final long delayTime = 1000; @Override public void handle(MouseEvent mouseEvent) { From ffa7de49dd149a6bf7af91f6ea0deb11f9ed442b Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 7 Apr 2018 17:14:35 +0200 Subject: [PATCH 17/32] added autoplay option * added a toggle button to enable autoplay * the table, text area and imageview are now on a separate anchorpane "TableModel" --- .../application/MainWindowController.java | 52 +++++-- .../kellerkinder/HomeFlix/player/Player.java | 18 +-- .../HomeFlix/player/PlayerController.java | 130 +++++++++--------- src/main/resources/fxml/MainWindow.fxml | 128 ++++++++++------- .../locals/HomeFlix-Local_de_DE.properties | 1 + .../locals/HomeFlix-Local_en_US.properties | 1 + 6 files changed, 197 insertions(+), 133 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index f6d918b..93e75ad 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -104,6 +104,9 @@ public class MainWindowController { @FXML private AnchorPane mainAnchorPane; + @FXML + private AnchorPane tableModeAnchorPane; + @FXML private ScrollPane settingsScrollPane; @@ -147,7 +150,7 @@ public class MainWindowController { private JFXButton debugBtn; @FXML - public JFXButton updateBtn; + private JFXButton updateBtn; @FXML private JFXButton addDirectoryBtn; @@ -161,6 +164,9 @@ public class MainWindowController { @FXML private JFXToggleButton autoUpdateToggleBtn; + @FXML + private JFXToggleButton autoplayToggleBtn; + @FXML private JFXTextField searchTextField; @@ -228,6 +234,7 @@ public class MainWindowController { private boolean settingsTrue = false; private boolean autoUpdate = false; private boolean useBeta = false; + private boolean autoplay = false; private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; @@ -513,6 +520,7 @@ public class MainWindowController { updateBtn.setFont(Font.font("System", 12)); autoUpdateToggleBtn.setSelected(isAutoUpdate()); + autoplayToggleBtn.setSelected(isAutoplay()); languageChoisBox.setItems(languages); branchChoisBox.setItems(branches); @@ -529,7 +537,7 @@ public class MainWindowController { @FXML private void playbtnclicked() { if (isSupportedFormat(currentTableFilm)) { - new Player(currentTableFilm, dbController); + new Player(mainWindowController); } else { LOGGER.error("using fallback player!"); @@ -669,7 +677,7 @@ public class MainWindowController { @FXML private void autoUpdateToggleBtnAction(){ - if (autoUpdate) { + if (isAutoUpdate()) { setAutoUpdate(false); } else { setAutoUpdate(true); @@ -677,14 +685,18 @@ public class MainWindowController { saveSettings(); } + @FXML + private void autoplayToggleBtnAction(){ + if (isAutoplay()) { + setAutoplay(false); + } else { + setAutoplay(true); + } + saveSettings(); + } + // refresh the selected child of the root node private void refreshTable() { - System.out.println("refresh"); - System.out.println(filmRoot.getChildren().get(indexTable).getValue()); - System.out.println(currentTableFilm); - -// filmRoot.getChildren().get() - filmRoot.getChildren().get(indexTable).setValue(filmsList.get(indexList)); } @@ -755,7 +767,6 @@ 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 @@ -853,6 +864,7 @@ public class MainWindowController { fontsizeLbl.setText(getBundle().getString("fontsizeLbl")); languageLbl.setText(getBundle().getString("languageLbl")); autoUpdateToggleBtn.setText(getBundle().getString("autoUpdate")); + autoplayToggleBtn.setText(getBundle().getString("autoplay")); branchLbl.setText(getBundle().getString("branchLbl")); columnStreamUrl.setText(getBundle().getString("columnStreamUrl")); columnTitle.setText(getBundle().getString("columnName")); @@ -908,6 +920,7 @@ public class MainWindowController { props.setProperty("color", getColor()); props.setProperty("autoUpdate", String.valueOf(isAutoUpdate())); props.setProperty("useBeta", String.valueOf(isUseBeta())); + props.setProperty("autoplay", String.valueOf(isAutoplay())); props.setProperty("size", getSize().toString()); props.setProperty("local", getLocal()); props.setProperty("ratingSortType", columnFavorite.getSortType().toString()); @@ -958,6 +971,13 @@ public class MainWindowController { LOGGER.error("cloud not load autoUpdate", e); setUseBeta(false); } + + try { + setAutoplay(Boolean.parseBoolean(props.getProperty("autoplay"))); + } catch (Exception e) { + LOGGER.error("cloud not load autoplay", e); + setAutoplay(false); + } try { setLocal(props.getProperty("local")); @@ -1032,6 +1052,10 @@ public class MainWindowController { public String getColor() { return color; } + + public FilmTabelDataType getCurrentTableFilm() { + return currentTableFilm; + } public String getCurrentTitle() { return currentTableFilm.getTitle(); @@ -1072,6 +1096,14 @@ public class MainWindowController { public void setUseBeta(boolean useBeta) { this.useBeta = useBeta; } + + public boolean isAutoplay() { + return autoplay; + } + + public void setAutoplay(boolean autoplay) { + this.autoplay = autoplay; + } public void setLocal(String input) { this.local = input; diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java index 5bbc3c2..33e6c5d 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/Player.java +++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java @@ -30,24 +30,23 @@ import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; import javafx.stage.WindowEvent; import kellerkinder.HomeFlix.application.Main; -import kellerkinder.HomeFlix.controller.DBController; +import kellerkinder.HomeFlix.application.MainWindowController; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class Player { + private MainWindowController mainWindowController; private PlayerController playerController; - private DBController dbController; private Stage stage; private AnchorPane pane; private Scene scene; /** * generate a new PlayerWindow - * @param entry the film object - * @param dbController the dbController object + * @param mainWindowController the MainWindowController */ - public Player(FilmTabelDataType film, DBController dbController) { - this.dbController = dbController; + public Player(MainWindowController mainWindowController) { + this.mainWindowController = mainWindowController; try { FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); pane = (AnchorPane) fxmlLoader.load(); @@ -58,14 +57,15 @@ public class Player { stage.getIcons().add(new Image(Main.class.getResourceAsStream("/icons/Homeflix_Icon_64x64.png"))); stage.setOnCloseRequest(new EventHandler() { public void handle(WindowEvent we) { - dbController.setCurrentTime(film.getStreamUrl(), playerController.getCurrentTime()); + mainWindowController.getDbController().setCurrentTime(mainWindowController.getCurrentStreamUrl(), + playerController.getCurrentTime()); playerController.getMediaPlayer().stop(); stage.close(); } }); playerController = fxmlLoader.getController(); - playerController.init(film, this, dbController); + playerController.init(mainWindowController, this, mainWindowController.getCurrentTableFilm()); stage.setFullScreen(true); stage.show(); @@ -75,7 +75,7 @@ public class Player { } public void playNewFilm(FilmTabelDataType film) { - playerController.init(film, this, dbController); + playerController.init(mainWindowController, this, film); } public Stage getStage() { diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index fdad932..7156aca 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -46,14 +46,14 @@ import javafx.scene.media.MediaPlayer; import javafx.scene.media.MediaPlayer.Status; import javafx.scene.media.MediaView; import javafx.util.Duration; -import kellerkinder.HomeFlix.controller.DBController; +import kellerkinder.HomeFlix.application.MainWindowController; import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class PlayerController { @FXML private MediaView mediaView; - + @FXML private VBox bottomVBox; @@ -62,10 +62,10 @@ public class PlayerController { @FXML private JFXSlider timeSlider; - + @FXML private JFXButton stopBtn; - + @FXML private JFXButton playBtn; @@ -73,10 +73,10 @@ public class PlayerController { private JFXButton fullscreenBtn; private Player player; - private DBController dbController; + private MainWindowController mainWCon; private Media media; private MediaPlayer mediaPlayer; - + private FilmTabelDataType film; private double currentTime = 0; private double seekTime = 0; @@ -84,8 +84,8 @@ public class PlayerController { private double duration = 0; private boolean mousePressed = false; private boolean showControls = true; - private boolean autoplay = 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")); @@ -94,23 +94,26 @@ public class PlayerController { /** * initialize the new PlayerWindow - * @param entry the film object + * @param entry the film object * @param player the player object (needed for closing action) * @param dbController the dbController object */ - public void init(FilmTabelDataType film, Player player, DBController dbController) { - this.film = film; + public void init(MainWindowController mainWCon, Player player, FilmTabelDataType film) { + this.mainWCon = mainWCon; this.player = player; - this.dbController = dbController; + 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 = dbController.getCurrentTime(film.getStreamUrl()); - + startTime = mainWCon.getDbController().getCurrentTime(film.getStreamUrl()); + autoplay = mainWCon.isAutoplay(); + mediaPlayer = new MediaPlayer(media); mediaView.setPreserveRatio(true); mediaView.setMediaPlayer(mediaPlayer); @@ -121,56 +124,59 @@ public class PlayerController { 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); + @Override + public void run() { + duration = media.getDuration().toMillis(); - mediaPlayer.play(); - mediaPlayer.seek(Duration.millis(startTime)); - } - }); - + timeSlider.setMax((duration / 1000) / 60); + + mediaPlayer.play(); + mediaPlayer.seek(Duration.millis(startTime)); + } + }); + + // every time the play time changes execute this + // TODO rework autoplay mediaPlayer.currentTimeProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { - currentTime = newValue.toMillis(); - int episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 0; - - if ((duration - currentTime) < 10000 && episode != 0 && autoplay) { - autoplay = false; - dbController.setCurrentTime(film.getStreamUrl(), 0); // reset old video start time - - //start the new film - FilmTabelDataType nextFilm = dbController.getNextEpisode(film.getTitle(), episode + 1); - if (nextFilm != null) { - mediaPlayer.stop(); - player.playNewFilm(nextFilm); - autoplay = true; + @Override + public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { + currentTime = newValue.toMillis(); // set the current time + int episode = !film.getEpisode().isEmpty() ? Integer.parseInt(film.getEpisode()) : 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 + 1)); + if (nextFilm != null) { + mediaPlayer.stop(); + player.playNewFilm(nextFilm); + autoplay = true; } } else if ((duration - currentTime) < 100) { mediaPlayer.stop(); } - if (!mousePressed) { - timeSlider.setValue((currentTime/1000)/60); + 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() { // hide controls timer init final Timer timer = new Timer(); @@ -179,13 +185,13 @@ public class PlayerController { @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(); @@ -202,40 +208,40 @@ public class PlayerController { } }); + // if the mouse on the timeSlider is released seek to the new position timeSlider.setOnMouseReleased(new EventHandler() { - @Override - public void handle(MouseEvent event) { - mediaPlayer.seek(new Duration(seekTime)); - mousePressed = false; - } + @Override + public void handle(MouseEvent event) { + mediaPlayer.seek(new Duration(seekTime)); + mousePressed = false; + } }); - + timeSlider.setOnMousePressed(new EventHandler() { @Override public void handle(MouseEvent event) { mousePressed = true; - } + } }); - + + // get the new seek time timeSlider.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, Number old_val, Number new_val) { - seekTime = (double) new_val*1000*60; + seekTime = (double) new_val * 1000 * 60; } }); } - + @FXML void stopBtnAction(ActionEvent event) { - - dbController.setCurrentTime(film.getStreamUrl(), currentTime); - + mainWCon.getDbController().setCurrentTime(film.getStreamUrl(), currentTime); mediaPlayer.stop(); player.getStage().close(); } @FXML - void fullscreenBtnAction(ActionEvent event) { + void fullscreenBtnAction(ActionEvent event) { if (player.getStage().isFullScreen()) { player.getStage().setFullScreen(false); fullscreenBtn.setGraphic(fullscreen_black); diff --git a/src/main/resources/fxml/MainWindow.fxml b/src/main/resources/fxml/MainWindow.fxml index cec24f0..43f47e8 100644 --- a/src/main/resources/fxml/MainWindow.fxml +++ b/src/main/resources/fxml/MainWindow.fxml @@ -24,58 +24,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + @@ -139,10 +119,26 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/locals/HomeFlix-Local_de_DE.properties b/src/main/resources/locals/HomeFlix-Local_de_DE.properties index f8c6279..d821e66 100644 --- a/src/main/resources/locals/HomeFlix-Local_de_DE.properties +++ b/src/main/resources/locals/HomeFlix-Local_de_DE.properties @@ -20,6 +20,7 @@ updateBtnChecking = Es wird nach Updates gesucht... updateBtnUpdateAvailable = Update verf\u00FCgbar updateBtnNoUpdateAvailable = Kein Update verf\u00FCgbar autoUpdate = beim Start nach Updates suchen: +autoplay = autoplay branchLbl = Updatezweig #column translations diff --git a/src/main/resources/locals/HomeFlix-Local_en_US.properties b/src/main/resources/locals/HomeFlix-Local_en_US.properties index 9df7ff2..6082c9d 100644 --- a/src/main/resources/locals/HomeFlix-Local_en_US.properties +++ b/src/main/resources/locals/HomeFlix-Local_en_US.properties @@ -20,6 +20,7 @@ updateBtnChecking = checking for updates... updateBtnUpdateAvailable = update available updateBtnNoUpdateAvailable = no update available autoUpdate = check at startup for updates: +autoplay = autoplay branchLbl = Branch #column translations From 4b5c9482c8436bfc9cf1d967ac9f6e7b09dc8091 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 7 Apr 2018 17:26:56 +0200 Subject: [PATCH 18/32] code cleanup --- .../HomeFlix/application/Main.java | 17 ++------ .../application/MainWindowController.java | 40 ++++++------------- .../HomeFlix/controller/DBController.java | 7 ++-- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/Main.java b/src/main/java/kellerkinder/HomeFlix/application/Main.java index ec61e95..d9012c4 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/Main.java +++ b/src/main/java/kellerkinder/HomeFlix/application/Main.java @@ -55,15 +55,12 @@ public class Main extends Application { private static String osVers = System.getProperty("os.version"); private static String javaVers = System.getProperty("java.version"); private static String javaVend = System.getProperty("java.vendor"); + private static String local = System.getProperty("user.language") + "_" + System.getProperty("user.country"); 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 configFile; private File posterCache; - - 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 static Logger LOGGER; @@ -123,7 +120,7 @@ public class Main extends Application { directory.mkdir(); addFirstSource(); mainWindowController.setColor("ee3523"); - mainWindowController.setSize(FONT_SIZE); + mainWindowController.setFontSize(17.0); mainWindowController.setAutoUpdate(false); mainWindowController.setLocal(local); mainWindowController.saveSettings(); @@ -146,7 +143,7 @@ public class Main extends Application { * sources.json, if the user ends the file-/directory-chooser the program will exit */ private void addFirstSource() { - switch (System.getProperty("user.language") + "_" + System.getProperty("user.country")) { + switch (local) { case "en_US": bundle = ResourceBundle.getBundle("locals.HomeFlix-Local", Locale.US); // us_english break; @@ -229,14 +226,6 @@ public class Main extends Application { return pane; } - public String getFONT_FAMILY() { - return FONT_FAMILY; - } - - public void setFONT_FAMILY(String FONT_FAMILY) { - this.FONT_FAMILY = FONT_FAMILY; - } - public File getDirectory() { return directory; } diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 93e75ad..cf22a8d 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -243,7 +243,6 @@ public class MainWindowController { private String versionName = "glowing vampire"; private String dialogBtnStyle; private String color; - private String ratingSortType; private String local; private String omdbAPIKey; @@ -254,7 +253,7 @@ public class MainWindowController { private String infoText; private String vlcNotInstalled; - public double size; + private double fontSize; private int last; private int indexTable; private int indexList; @@ -273,8 +272,8 @@ public class MainWindowController { 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_black = new ImageView(new Image("icons/ic_play_arrow_black_18dp_1x.png")); - private MenuItem like = new MenuItem("like"); - private MenuItem dislike = new MenuItem("dislike"); //TODO one option (like or dislike) + private MenuItem like = new MenuItem("like"); + private MenuItem dislike = new MenuItem("dislike"); // TODO one option (like or dislike) private ContextMenu menu = new ContextMenu(like, dislike); private Properties props = new Properties(); @@ -418,7 +417,7 @@ public class MainWindowController { fontsizeSlider.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, Number old_val, Number new_val) { - setSize(fontsizeSlider.getValue()); + setFontSize(fontsizeSlider.getValue()); if (!getCurrentTitle().isEmpty()) { dbController.readCache(getCurrentStreamUrl()); } @@ -515,7 +514,7 @@ public class MainWindowController { debugBtn.setVisible(false); versionLbl.setText("Version: " + version + " (Build: " + buildNumber + ")"); - fontsizeSlider.setValue(getSize()); + fontsizeSlider.setValue(getFontSize()); colorPicker.setValue(Color.valueOf(getColor())); updateBtn.setFont(Font.font("System", 12)); @@ -921,7 +920,7 @@ public class MainWindowController { props.setProperty("autoUpdate", String.valueOf(isAutoUpdate())); props.setProperty("useBeta", String.valueOf(isUseBeta())); props.setProperty("autoplay", String.valueOf(isAutoplay())); - props.setProperty("size", getSize().toString()); + props.setProperty("size", getFontSize().toString()); props.setProperty("local", getLocal()); props.setProperty("ratingSortType", columnFavorite.getSortType().toString()); @@ -952,10 +951,10 @@ public class MainWindowController { } try { - setSize(Double.parseDouble(props.getProperty("size"))); + setFontSize(Double.parseDouble(props.getProperty("size"))); } catch (Exception e) { LOGGER.error("cloud not load fontsize", e); - setSize(17.0); + setFontSize(17.0); } try { @@ -986,13 +985,6 @@ public class MainWindowController { 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(); } catch (IOException e) { LOGGER.error(errorSave, e); @@ -1065,12 +1057,12 @@ public class MainWindowController { return currentTableFilm.getStreamUrl(); } - public void setSize(Double input) { - this.size = input; + public void setFontSize(Double input) { + this.fontSize = input; } - public Double getSize() { - return size; + public Double getFontSize() { + return fontSize; } public int getIndexTable() { @@ -1125,14 +1117,6 @@ public class MainWindowController { return sourcesList; } - public String getRatingSortType() { - return ratingSortType; - } - - public void setRatingSortType(String ratingSortType) { - this.ratingSortType = ratingSortType; - } - public ResourceBundle getBundle() { return bundle; } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index b91d970..219d088 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -550,9 +550,8 @@ public class DBController { ResultSet rs = stmt.executeQuery("SELECT * FROM cache WHERE streamUrl=\"" + streamUrl + "\";"); ArrayList nameText = new ArrayList(); ArrayList responseText = new ArrayList(); - String fontFamily = main.getFONT_FAMILY(); Image im; - int fontSize = (int) Math.round(mainWindowController.size); + int fontSize = (int) Math.round(mainWindowController.getFontSize()); int j = 2; nameText.add(0, new Text(mainWindowController.getBundle().getString("title") + ": ")); @@ -583,8 +582,8 @@ public class DBController { rs.close(); for (int i = 0; i < nameText.size(); i++) { - nameText.get(i).setFont(Font.font(fontFamily, FontWeight.BOLD, fontSize)); - responseText.get(i).setFont(Font.font(fontFamily, fontSize)); + nameText.get(i).setFont(Font.font("System", FontWeight.BOLD, fontSize)); + responseText.get(i).setFont(Font.font("System", fontSize)); } mainWindowController.getTextFlow().getChildren().remove(0, From 96e3d9e3accfe44154e63137e983393f2fba2c30 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 8 Apr 2018 13:22:20 +0200 Subject: [PATCH 19/32] code cleanup --- .../HomeFlix/application/MainWindowController.java | 2 +- src/main/java/kellerkinder/HomeFlix/player/Player.java | 7 ------- .../kellerkinder/HomeFlix/player/PlayerController.java | 5 ++--- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index cf22a8d..acddd4c 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -103,7 +103,7 @@ public class MainWindowController { @FXML private AnchorPane mainAnchorPane; - + @FXML private AnchorPane tableModeAnchorPane; diff --git a/src/main/java/kellerkinder/HomeFlix/player/Player.java b/src/main/java/kellerkinder/HomeFlix/player/Player.java index 33e6c5d..1c8d946 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/Player.java +++ b/src/main/java/kellerkinder/HomeFlix/player/Player.java @@ -31,11 +31,9 @@ import javafx.stage.Stage; import javafx.stage.WindowEvent; import kellerkinder.HomeFlix.application.Main; import kellerkinder.HomeFlix.application.MainWindowController; -import kellerkinder.HomeFlix.datatypes.FilmTabelDataType; public class Player { - private MainWindowController mainWindowController; private PlayerController playerController; private Stage stage; private AnchorPane pane; @@ -46,7 +44,6 @@ public class Player { * @param mainWindowController the MainWindowController */ public Player(MainWindowController mainWindowController) { - this.mainWindowController = mainWindowController; try { FXMLLoader fxmlLoader = new FXMLLoader(ClassLoader.getSystemResource("fxml/PlayerWindow.fxml")); pane = (AnchorPane) fxmlLoader.load(); @@ -73,10 +70,6 @@ public class Player { e.printStackTrace(); } } - - public void playNewFilm(FilmTabelDataType film) { - playerController.init(mainWindowController, this, film); - } public Stage getStage() { return stage; diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 7156aca..538ad95 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -138,7 +138,6 @@ public class PlayerController { }); // every time the play time changes execute this - // TODO rework autoplay mediaPlayer.currentTimeProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Duration oldValue, Duration newValue) { @@ -152,7 +151,7 @@ public class PlayerController { FilmTabelDataType nextFilm = mainWCon.getDbController().getNextEpisode(film.getTitle(), (episode + 1)); if (nextFilm != null) { mediaPlayer.stop(); - player.playNewFilm(nextFilm); + init(mainWCon, player, nextFilm); autoplay = true; } } else if ((duration - currentTime) < 100) { @@ -178,7 +177,7 @@ public class PlayerController { private void initActions() { player.getScene().addEventFilter(MouseEvent.MOUSE_MOVED, new EventHandler() { - // hide controls timer init + // hide controls timer initialization final Timer timer = new Timer(); TimerTask controlAnimationTask = null; // task to execute save operation final long delayTime = 1000; From 78fa84758db75cc612221e1ffa860d1e0d219e8a Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 8 Apr 2018 13:23:47 +0200 Subject: [PATCH 20/32] cleanup --- .../application/MainWindowController.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index acddd4c..7b220e3 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -139,40 +139,40 @@ public class MainWindowController { @FXML private JFXButton forwardBtn; - - @FXML - private JFXButton aboutBtn; - - @FXML - private JFXButton settingsBtn; - - @FXML - private JFXButton debugBtn; - - @FXML - private JFXButton updateBtn; - - @FXML - private JFXButton addDirectoryBtn; - - @FXML - private JFXButton addStreamSourceBtn; - - @FXML - private JFXHamburger menuHam; - - @FXML - private JFXToggleButton autoUpdateToggleBtn; - - @FXML - private JFXToggleButton autoplayToggleBtn; - - @FXML - private JFXTextField searchTextField; - - @FXML - public JFXColorPicker colorPicker; - + + @FXML + private JFXButton aboutBtn; + + @FXML + private JFXButton settingsBtn; + + @FXML + private JFXButton debugBtn; + + @FXML + private JFXButton updateBtn; + + @FXML + private JFXButton addDirectoryBtn; + + @FXML + private JFXButton addStreamSourceBtn; + + @FXML + private JFXHamburger menuHam; + + @FXML + private JFXToggleButton autoUpdateToggleBtn; + + @FXML + private JFXToggleButton autoplayToggleBtn; + + @FXML + private JFXTextField searchTextField; + + @FXML + public JFXColorPicker colorPicker; + @FXML public ChoiceBox languageChoisBox = new ChoiceBox<>(); From e12da3d116bee39a137bb1ed479d0d8d9aafb431 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 8 Apr 2018 13:30:55 +0200 Subject: [PATCH 21/32] code cleanup & processbuilder * use a processBuilder to start the new application after updating --- .../application/MainWindowController.java | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 7b220e3..956fbd4 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -181,34 +181,34 @@ public class MainWindowController { @FXML public JFXSlider fontsizeSlider; - - @FXML - private Label homeflixSettingsLbl; - - @FXML - private Label mainColorLbl; - + + @FXML + private Label homeflixSettingsLbl; + + @FXML + private Label mainColorLbl; + @FXML private Label fontsizeLbl; - - @FXML - private Label languageLbl; - + + @FXML + private Label languageLbl; + @FXML private Label updateLbl; - + @FXML private Label branchLbl; - + @FXML private Label sourcesLbl; @FXML private Label versionLbl; - @FXML + @FXML private ImageView posterImageView; - private ImageView imv1; + private ImageView imv1; @FXML private TreeItem filmRoot = new TreeItem<>(new FilmTabelDataType("", "", "", "", false, false, imv1)); @@ -222,22 +222,22 @@ public class MainWindowController { private TreeTableColumn columnEpisode = new TreeTableColumn<>("Episode"); @FXML private TreeTableColumn columnFavorite = new TreeTableColumn<>("Favorite"); - - @FXML - private TreeItem sourceRoot =new TreeItem<>(new SourceDataType("", "")); - @FXML - private TableColumn sourceColumn; - @FXML - private TableColumn modeColumn; - + + @FXML + private TreeItem sourceRoot = new TreeItem<>(new SourceDataType("", "")); + @FXML + private TableColumn sourceColumn; + @FXML + private TableColumn modeColumn; + private boolean menuTrue = false; private boolean settingsTrue = false; private boolean autoUpdate = 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 String version = "0.6.99"; private String buildNumber = "147"; private String versionName = "glowing vampire"; @@ -331,18 +331,18 @@ public class MainWindowController { filmsTreeTable.getColumns().add(columnFavorite); filmsTreeTable.getColumns().add(columnSeason); filmsTreeTable.getColumns().add(columnEpisode); - filmsTreeTable.getColumns().get(0).setVisible(false); //hide columnStreamUrl (important) - - // context menu for treeTableViewfilm + filmsTreeTable.getColumns().get(0).setVisible(false); // hide columnStreamUrl (important) + + // context menu for treeTableViewfilm filmsTreeTable.setContextMenu(menu); - - // sourcesTreeTable - sourceColumn.setCellValueFactory(cellData -> cellData.getValue().pathProperty()); - modeColumn.setCellValueFactory(cellData -> cellData.getValue().modeProperty()); - sourcesTable.setItems(sourcesList); + + // sourcesTreeTable + sourceColumn.setCellValueFactory(cellData -> cellData.getValue().pathProperty()); + modeColumn.setCellValueFactory(cellData -> cellData.getValue().modeProperty()); + sourcesTable.setItems(sourcesList); } - - //Initializing the actions + + // Initializing the actions private void initActions() { HamburgerBackArrowBasicTransition burgerTask = new HamburgerBackArrowBasicTransition(menuHam); From e3feebcbb44f6d502579396b26b74f33ca955346 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 8 Apr 2018 13:31:27 +0200 Subject: [PATCH 22/32] UpdateController update --- .../kellerkinder/HomeFlix/controller/UpdateController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java b/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java index 150f3d4..bab08ae 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java @@ -148,8 +148,8 @@ public class UpdateController implements Runnable { 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.deleteQuietly(new File("ProjectHomeFlix_update.jar")); // delete update - Runtime.getRuntime().exec("java -jar ProjectHomeFlix.jar"); // start again TODO consider ProcessBuilder to execute - System.exit(0); // finishes itself + new ProcessBuilder("java", "-jar", "ProjectHomeFlix.jar").start(); // start the new application + System.exit(0); // close the current application } catch (IOException e) { Platform.runLater(() -> { LOGGER.info("could not download update files", e); From 2c1ce233154b5278d6f137816abc414ec825ff83 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 8 Apr 2018 22:06:39 +0200 Subject: [PATCH 23/32] maven cleanup --- pom.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index a31f960..5977fc7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.kellerkinder Project-HomeFlix - 0.6.1 + 0.6.99 jar Project-HomeFlix @@ -78,21 +78,21 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.1.1 + + true + + + kellerkinder.HomeFlix.application.Main + + + package shade - - true - - - kellerkinder.HomeFlix.application.Main - - - From 913513a23769dd1d200ecd6ec4058d4f5104dc21 Mon Sep 17 00:00:00 2001 From: Jannik Date: Fri, 13 Apr 2018 11:11:25 +0200 Subject: [PATCH 24/32] series work --- .../application/MainWindowController.java | 56 +++++++------------ .../HomeFlix/controller/DBController.java | 26 ++++++++- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 956fbd4..28d5651 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -103,13 +103,11 @@ public class MainWindowController { @FXML private AnchorPane mainAnchorPane; - @FXML private AnchorPane tableModeAnchorPane; @FXML private ScrollPane settingsScrollPane; - @FXML private ScrollPane textScrollPane; @@ -130,40 +128,30 @@ public class MainWindowController { @FXML private JFXButton playbtn; - @FXML private JFXButton openfolderbtn; - @FXML private JFXButton returnBtn; - @FXML private JFXButton forwardBtn; - @FXML private JFXButton aboutBtn; - @FXML private JFXButton settingsBtn; - @FXML private JFXButton debugBtn; - @FXML private JFXButton updateBtn; - @FXML private JFXButton addDirectoryBtn; - @FXML private JFXButton addStreamSourceBtn; - + @FXML private JFXHamburger menuHam; @FXML private JFXToggleButton autoUpdateToggleBtn; - @FXML private JFXToggleButton autoplayToggleBtn; @@ -171,38 +159,30 @@ public class MainWindowController { private JFXTextField searchTextField; @FXML - public JFXColorPicker colorPicker; + private JFXColorPicker colorPicker; @FXML - public ChoiceBox languageChoisBox = new ChoiceBox<>(); + private ChoiceBox languageChoisBox = new ChoiceBox<>(); + @FXML + private ChoiceBox branchChoisBox = new ChoiceBox<>(); @FXML - public ChoiceBox branchChoisBox = new ChoiceBox<>(); - - @FXML - public JFXSlider fontsizeSlider; + private JFXSlider fontsizeSlider; @FXML private Label homeflixSettingsLbl; - @FXML private Label mainColorLbl; - @FXML private Label fontsizeLbl; - @FXML private Label languageLbl; - @FXML private Label updateLbl; - @FXML private Label branchLbl; - @FXML private Label sourcesLbl; - @FXML private Label versionLbl; @@ -578,8 +558,9 @@ public class MainWindowController { } } - /** TODO improve function + /** TODO add all other supported mime types * 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 */ @@ -708,29 +689,32 @@ public class MainWindowController { // only if the entry contains a season and a episode it's a valid series 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++) { if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) { // if a root node exists, add element as child // System.out.println("Found a root node to add child"); // System.out.println("Adding: " + element.getStreamUrl()); - TreeItem episodeNode = new TreeItem<>(new FilmTabelDataType(element.getStreamUrl(), - element.getTitle(), element.getSeason(), element.getEpisode(), element.getFavorite(), - element.getCached(), element.getImage())); + TreeItem episodeNode = new TreeItem<>(new FilmTabelDataType( + element.getStreamUrl(), element.getTitle(), element.getSeason(), element.getEpisode(), + element.getFavorite(), element.getCached(), element.getImage())); filmRoot.getChildren().get(i).getChildren().add(episodeNode); - } else if (i == filmRoot.getChildren().size() - 1) { + } else if (filmRoot.getChildren().get(i).nextSibling() == null) { // if no root node exists, create one and add element as child // System.out.println("Create a root node to add child"); // System.out.println("Adding: " + element.getStreamUrl()); - // TODO get the last watched episode, the first one with currentTime != 0 - TreeItem seriesRootNode = new TreeItem<>(new FilmTabelDataType(element.getStreamUrl(), + // TODO set episode and season + // FIXME if the streamUrl hasen't been cached we get an exception + TreeItem seriesRootNode = new TreeItem<>(new FilmTabelDataType( + dbController.getLastWatchedEpisode(element.getTitle()), element.getTitle(), "", "", element.getFavorite(), element.getCached(), element.getImage())); filmRoot.getChildren().add(seriesRootNode); } } } else { - filmRoot.getChildren().add(new TreeItem(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(element)); } } } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 219d088..d8f8b01 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -546,6 +546,7 @@ public class DBController { */ public void readCache(String streamUrl) { try { + Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM cache WHERE streamUrl=\"" + streamUrl + "\";"); ArrayList nameText = new ArrayList(); @@ -575,6 +576,7 @@ public class DBController { responseText.add(new Text(rs.getString(j) + "\n")); j++; } + responseText.add(new Text(rs.getString(19) + "\n")); im = new Image(new File(rs.getString(20)).toURI().toString()); @@ -620,7 +622,7 @@ public class DBController { rs.close(); stmt.close(); } catch (Exception e) { - LOGGER.error("Ups! error while refreshing mwc!", e); + LOGGER.error("Ups! error while getting the current time!", e); } return currentTime; @@ -673,6 +675,28 @@ public class DBController { return nextFilm; } + + public String getLastWatchedEpisode(String title) { + LOGGER.info("last watched episode of: " + title); + String lastEpisodeStreamUrl = ""; + double lastCurrentTime = -1; + + try { + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\";"); + while (rs.next()) { + if (rs.getDouble("currentTime") > lastCurrentTime) { + lastCurrentTime = rs.getDouble("currentTime"); + lastEpisodeStreamUrl = rs.getString("streamUrl"); + } + } + } catch (Exception e) { + LOGGER.error("Ups! error while getting the last watched episode!", e); + } + + return lastEpisodeStreamUrl; + } + // removes the ending private String cutOffEnd(String str) { if (str == null) return null; From 94e32b938a8cf7238f78babcf248384e1ea62086 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 14 Apr 2018 16:14:10 +0200 Subject: [PATCH 25/32] saving the progress you mad on series by now * added a function to save the progress you made watching a series * fixed a bug where refreshing the data element didn't work * added a searchCache methode to search if a film has been added to cach but the chace flag hasn't been set --- .../application/MainWindowController.java | 28 ++++---- .../HomeFlix/controller/DBController.java | 70 +++++++++++++++---- 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 28d5651..121bab7 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -475,10 +475,10 @@ public class MainWindowController { last = indexTable - 1; next = indexTable + 1; - if (currentTableFilm.getCached()) { + if (currentTableFilm.getCached() || dbController.searchCache(getCurrentStreamUrl())) { LOGGER.info("loading from cache: " + getCurrentTitle()); dbController.readCache(getCurrentStreamUrl()); - } else { + } else { omdbAPIController = new OMDbAPIController(mainWindowController, dbController, main); Thread omdbAPIThread = new Thread(omdbAPIController); omdbAPIThread.setName("OMDbAPI"); @@ -514,12 +514,16 @@ public class MainWindowController { } @FXML - private void playbtnclicked() { + private void playbtnclicked() { + 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")) { String line; String output = ""; @@ -558,15 +562,15 @@ public class MainWindowController { } } - /** TODO add all other supported mime types + /** * 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"); + String mimeType = URLConnection.guessContentTypeFromName(film.getStreamUrl()); + return mimeType != null && (mimeType.contains("mp4") || mimeType.contains("vp6")); } @FXML @@ -694,21 +698,15 @@ public class MainWindowController { for (int i = 0; i < filmRoot.getChildren().size(); i++) { if (filmRoot.getChildren().get(i).getValue().getTitle().equals(element.getTitle())) { // if a root node exists, add element as child -// System.out.println("Found a root node to add child"); -// System.out.println("Adding: " + element.getStreamUrl()); TreeItem episodeNode = new TreeItem<>(new FilmTabelDataType( element.getStreamUrl(), element.getTitle(), element.getSeason(), element.getEpisode(), element.getFavorite(), element.getCached(), element.getImage())); filmRoot.getChildren().get(i).getChildren().add(episodeNode); } else if (filmRoot.getChildren().get(i).nextSibling() == null) { // if no root node exists, create one and add element as child -// System.out.println("Create a root node to add child"); -// System.out.println("Adding: " + element.getStreamUrl()); - // TODO set episode and season - // FIXME if the streamUrl hasen't been cached we get an exception TreeItem seriesRootNode = new TreeItem<>(new FilmTabelDataType( - dbController.getLastWatchedEpisode(element.getTitle()), - element.getTitle(), "", "", element.getFavorite(), element.getCached(), element.getImage())); + element.getTitle() + "_rootNode", element.getTitle(), "", "", element.getFavorite(), + false, element.getImage())); filmRoot.getChildren().add(seriesRootNode); } } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index d8f8b01..e761d03 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -246,16 +246,17 @@ public class DBController { Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE streamUrl = \"" + streamUrl + "\";"); - if (rs.getBoolean("favorite") == true) { - mainWindowController.getFilmsList().set(indexList, 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 { - mainWindowController.getFilmsList().set(indexList, 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))); + while (rs.next()) { + if (rs.getBoolean("favorite") == true) { + mainWindowController.getFilmsList().set(indexList, 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 { + mainWindowController.getFilmsList().set(indexList, 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))); + } } - rs.close(); stmt.close(); } catch (Exception e) { @@ -540,6 +541,21 @@ public class DBController { } } + 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 * @param streamUrl URL of the film @@ -675,26 +691,50 @@ public class DBController { return nextFilm; } - - public String getLastWatchedEpisode(String title) { + /** + * 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); - String lastEpisodeStreamUrl = ""; - double lastCurrentTime = -1; + 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"); - lastEpisodeStreamUrl = rs.getString("streamUrl"); + 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 lastEpisodeStreamUrl; + return nextFilm; } // removes the ending From 0c1b21ac0589f4af6da94b8e3fc8fd19db0fc350 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 15 Apr 2018 21:30:26 +0200 Subject: [PATCH 26/32] series work if there is more than one season of a series homeflix should manage that too --- .../application/MainWindowController.java | 6 +-- .../HomeFlix/controller/DBController.java | 40 ++++++++++++++----- .../HomeFlix/player/PlayerController.java | 3 +- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 121bab7..ce4f8c6 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -218,9 +218,9 @@ public class MainWindowController { private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; - private String version = "0.6.99"; - private String buildNumber = "147"; - private String versionName = "glowing vampire"; + private String version = "0.6.100"; + private String buildNumber = "149"; + private String versionName = "toothless dragon RC"; private String dialogBtnStyle; private String color; private String local; diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index e761d03..8ee32af 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -541,6 +541,11 @@ 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 { @@ -661,37 +666,52 @@ public class DBController { } } - /** + /** TODO check if we relay need to separate between favorites and none favorites * 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 nextEp) { + public FilmTabelDataType getNextEpisode(String title, int nextEp, int season) { FilmTabelDataType nextFilm = null; try { Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND episode = \"" + nextEp + "\";"); - while (rs.next()) { + ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND episode = \"" + + nextEp + "\" AND season = \"" + season + "\";"); + if (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"), + 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"), + 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)); } + } else { + rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + + "\" AND episode = \"1\" AND season = \"" + (season + 1) + "\";"); + 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)); + } + } } 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 diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 538ad95..2a3324f 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -143,12 +143,13 @@ public class PlayerController { public void changed(ObservableValue 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 + 1)); + FilmTabelDataType nextFilm = mainWCon.getDbController().getNextEpisode(film.getTitle(), (episode + 1), season); if (nextFilm != null) { mediaPlayer.stop(); init(mainWCon, player, nextFilm); From 7631169d26c29ca60787e8c45782039410956193 Mon Sep 17 00:00:00 2001 From: Jannik Date: Wed, 18 Apr 2018 14:00:36 +0200 Subject: [PATCH 27/32] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a798c0..2491954 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ sqlite-jdbc: https://github.com/xerial/sqlite-jdbc apache commons io : https://commons.apache.org/proper/commons-io/ ## 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)) www.kellerkinder.xyz From 75ad13734621821720c3f39b995df5cf487727f8 Mon Sep 17 00:00:00 2001 From: Jannik Date: Wed, 18 Apr 2018 21:04:14 +0200 Subject: [PATCH 28/32] minor player improvements --- .../HomeFlix/application/MainWindowController.java | 9 +++++---- .../kellerkinder/HomeFlix/player/PlayerController.java | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index ce4f8c6..1c40a3a 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -218,9 +218,9 @@ public class MainWindowController { private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; - private String version = "0.6.100"; - private String buildNumber = "149"; - private String versionName = "toothless dragon RC"; + private final String version = "0.6.100"; + private final String buildNumber = "151"; + private final String versionName = "toothless dragon RC"; private String dialogBtnStyle; private String color; private String local; @@ -274,8 +274,9 @@ public class MainWindowController { omdbAPIController = new OMDbAPIController(this, dbController, this.main); } - // call all init methods + // call all initialize methods void init() { + LOGGER.info("Initializing Project-HomeFlix build " + buildNumber); loadSettings(); checkAutoUpdate(); initTabel(); diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index 2a3324f..e6b090d 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -92,7 +92,7 @@ public class PlayerController { 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) @@ -144,7 +144,7 @@ public class PlayerController { 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; @@ -155,8 +155,10 @@ public class PlayerController { init(mainWCon, player, nextFilm); autoplay = true; } - } else if ((duration - currentTime) < 100) { + } 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) { @@ -181,7 +183,7 @@ public class PlayerController { // hide controls timer initialization final Timer timer = new Timer(); TimerTask controlAnimationTask = null; // task to execute save operation - final long delayTime = 1000; + final long delayTime = 2000; // hide the controls after 2 seconds @Override public void handle(MouseEvent mouseEvent) { From d3ea1b1956c863bf15688c491e0ac1eccd30a678 Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 19 Apr 2018 11:45:11 +0200 Subject: [PATCH 29/32] fixed api arror if title dosent exist at omdbAPI --- .../controller/OMDbAPIController.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index db0ee80..0a77f19 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -61,7 +61,7 @@ public class OMDbAPIController implements Runnable { String output = null; String posterPath = null; - // get by title, TODO implement search FIXME set correct info if film dosen't exist + // get information by title try { URL apiUrl = new URL(URL + mainWindowController.getOmdbAPIKey() + "&t=" + mainWindowController.getCurrentTitle().replace(" ", "%20")); @@ -78,6 +78,35 @@ public class OMDbAPIController implements Runnable { JsonObject object = Json.parse(output).asObject(); + if (object.getString("Error", "").equals("Movie not found!")) { + // if the movie was not found try to search it + // TODO split the name intelligent as it may contain the film title + // query the api + 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(); + System.out.println(apiUrl); + LOGGER.info("response from search " + URL + " was valid"); + LOGGER.info(output); + } catch (Exception e) { + LOGGER.error("error while making api request or reading response"); + LOGGER.error("response from search" + URL + " was: \n" + output, e); + return; + } + + JsonObject searchObject = Json.parse(output).asObject(); + // TODO new query with the actual title + if (object.getString("Response", "").equals("True")) { + System.out.println(searchObject.getString("Title", "")); + } + + System.out.println("Movie not found, not setting cache"); + return; + } + responseString[0] = object.getString("Title", ""); responseString[1] = object.getString("Year", ""); responseString[2] = object.getString("Rated", ""); From 23e46b7913507357df27b8b4033ff2386f4ac536 Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 19 Apr 2018 12:13:18 +0200 Subject: [PATCH 30/32] cleanup * onlay add files with mime type == video --- .../application/MainWindowController.java | 64 ++----------------- .../HomeFlix/controller/DBController.java | 13 ++-- .../controller/OMDbAPIController.java | 7 ++ .../HomeFlix/controller/UpdateController.java | 3 + src/main/resources/fxml/MainWindow.fxml | 7 +- .../locals/HomeFlix-Local_de_DE.properties | 1 - .../locals/HomeFlix-Local_en_US.properties | 1 - 7 files changed, 23 insertions(+), 73 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 1c40a3a..74bcdd1 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -32,8 +32,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; import java.io.Writer; import java.math.BigInteger; import java.net.URLConnection; @@ -64,8 +62,6 @@ import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ChoiceBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; @@ -73,7 +69,6 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.ScrollPane; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; -import javafx.scene.control.TextArea; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableColumn.SortType; @@ -82,9 +77,7 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; @@ -139,8 +132,6 @@ public class MainWindowController { @FXML private JFXButton settingsBtn; @FXML - private JFXButton debugBtn; - @FXML private JFXButton updateBtn; @FXML private JFXButton addDirectoryBtn; @@ -227,7 +218,6 @@ public class MainWindowController { private String omdbAPIKey; // text strings - private String errorPlay; private String errorLoad; private String errorSave; private String infoText; @@ -443,7 +433,7 @@ public class MainWindowController { } } } else { - System.out.println("ascending"); +// System.out.println("ascending"); for (FilmTabelDataType film : filmsList) { if (!film.getFavorite()) { filterData.add(0, film); @@ -491,9 +481,6 @@ public class MainWindowController { // initialize UI elements private void initUI() { - debugBtn.setDisable(true); // debugging button for tests - debugBtn.setVisible(false); - versionLbl.setText("Version: " + version + " (Build: " + buildNumber + ")"); fontsizeSlider.setValue(getFontSize()); colorPicker.setValue(Color.valueOf(getColor())); @@ -546,16 +533,16 @@ public class MainWindowController { } else { try { new ProcessBuilder("vlc", getCurrentStreamUrl()).start(); - } catch (IOException e1) { - showErrorMsg(errorPlay, e1); + } catch (IOException e) { + LOGGER.warn("An error has occurred while opening the file!", e); } } } else if (System.getProperty("os.name").contains("Windows") || System.getProperty("os.name").contains("Mac OS X")) { try { Desktop.getDesktop().open(new File(getCurrentStreamUrl())); - } catch (IOException e1) { - showErrorMsg(errorPlay, e1); + } catch (IOException e) { + LOGGER.warn("An error has occurred while opening the file!", e); } } else { LOGGER.error(System.getProperty("os.name") + ", OS is not supported, please contact a developer! "); @@ -616,11 +603,6 @@ public class MainWindowController { } } - @FXML - private void debugBtnclicked(){ - //for testing - } - @FXML private void addDirectoryBtnAction(){ DirectoryChooser directoryChooser = new DirectoryChooser(); @@ -768,7 +750,6 @@ public class MainWindowController { dialogBtnStyle = btnStyleWhite; settingsBtn.setStyle("-fx-text-fill: WHITE;"); aboutBtn.setStyle("-fx-text-fill: WHITE;"); - debugBtn.setStyle("-fx-text-fill: WHITE;"); addDirectoryBtn.setStyle(btnStyleWhite); addStreamSourceBtn.setStyle(btnStyleWhite); updateBtn.setStyle(btnStyleWhite); @@ -784,7 +765,6 @@ public class MainWindowController { dialogBtnStyle = btnStyleBlack; settingsBtn.setStyle("-fx-text-fill: BLACK;"); aboutBtn.setStyle("-fx-text-fill: BLACK;"); - debugBtn.setStyle("-fx-text-fill: BLACK;"); addDirectoryBtn.setStyle(btnStyleBlack); addStreamSourceBtn.setStyle(btnStyleBlack); updateBtn.setStyle(btnStyleBlack); @@ -853,46 +833,12 @@ public class MainWindowController { columnSeason.setText(getBundle().getString("columnSeason")); columnEpisode.setText(getBundle().getString("columnEpisode")); columnFavorite.setText(getBundle().getString("columnFavorite")); - errorPlay = getBundle().getString("errorPlay"); errorLoad = getBundle().getString("errorLoad"); errorSave = getBundle().getString("errorSave"); infoText = getBundle().getString("infoText"); vlcNotInstalled = getBundle().getString("vlcNotInstalled"); } - // TODO rework after #19 has landed - public void showErrorMsg(String msg, Exception exception) { - 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 the configuration to the config.xml file */ diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 8ee32af..6c74049 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -68,8 +68,8 @@ public class DBController { /** * constructor for DBController - * @param main the main object - * @param mainWindowController the mainWindowController object + * @param main the Main object + * @param mainWindowController the MainWindowController object */ public DBController(Main main, MainWindowController mainWindowController) { this.main = main; @@ -300,11 +300,11 @@ public class DBController { */ private void checkRemoveEntry() { LOGGER.info("checking for entrys to remove to DB ..."); - try { Statement stmt = connection.createStatement(); for (String entry : filmsdbStreamURL) { + // if the directory doen't contain the entry form the db, remove it if (!filmsStreamURL.contains(entry)) { stmt.executeUpdate("delete from films where streamUrl = \"" + entry + "\""); connection.commit(); @@ -334,8 +334,9 @@ public class DBController { // if it's a local source check the folder for new film if (source.getMode().equals("local")) { for (File file : new File(source.getPath()).listFiles()) { - - if (file.isFile()) { + String mimeType = URLConnection.guessContentTypeFromName(file.getPath()); + // if file is file and has mime type "video" TODO needs testing + if (file.isFile() && mimeType != null && mimeType.contains("video")) { // get all files (films) if (!filmsdbStreamURL.contains(file.getPath())) { stmt.executeUpdate("insert into films values (" @@ -346,7 +347,7 @@ public class DBController { LOGGER.info("Added \"" + file.getName() + "\" to database"); filmsdbStreamURL.add(file.getPath()); } - } else { + } else if (file.isDirectory()) { // get all folders (series) int sn = 1; for (File season : file.listFiles()) { diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index 0a77f19..e60db8f 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -48,6 +48,12 @@ public class OMDbAPIController implements Runnable { private String URL = "https://www.omdbapi.com/?apikey="; 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){ this.mainWindowController = mainWindowController; this.dbController = dbController; @@ -107,6 +113,7 @@ public class OMDbAPIController implements Runnable { return; } + // add the response to the responseString[] responseString[0] = object.getString("Title", ""); responseString[1] = object.getString("Year", ""); responseString[2] = object.getString("Rated", ""); diff --git a/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java b/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java index bab08ae..efa3ffe 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/UpdateController.java @@ -60,6 +60,9 @@ public class UpdateController implements Runnable { /** * 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) { mainWindowController = mwc; diff --git a/src/main/resources/fxml/MainWindow.fxml b/src/main/resources/fxml/MainWindow.fxml index 43f47e8..45b120a 100644 --- a/src/main/resources/fxml/MainWindow.fxml +++ b/src/main/resources/fxml/MainWindow.fxml @@ -22,7 +22,7 @@ - + @@ -190,11 +190,6 @@ - - - - - diff --git a/src/main/resources/locals/HomeFlix-Local_de_DE.properties b/src/main/resources/locals/HomeFlix-Local_de_DE.properties index d821e66..166e686 100644 --- a/src/main/resources/locals/HomeFlix-Local_de_DE.properties +++ b/src/main/resources/locals/HomeFlix-Local_de_DE.properties @@ -33,7 +33,6 @@ columnFavorite = Favorit #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 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 errorOpenStream = Beim \u00F6ffnen des Streams ist ein Fehler aufgetreten! errorLoad = Beim laden der Einstellungen ist ein Fehler aufgetreten! diff --git a/src/main/resources/locals/HomeFlix-Local_en_US.properties b/src/main/resources/locals/HomeFlix-Local_en_US.properties index 6082c9d..8b16294 100644 --- a/src/main/resources/locals/HomeFlix-Local_en_US.properties +++ b/src/main/resources/locals/HomeFlix-Local_en_US.properties @@ -33,7 +33,6 @@ columnFavorite = Favorite #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 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 errorOpenStream = An error has occurred during opening the stream! errorLoad = An error occurred while loading the settings! From 9a4eae0be9eda798db3b3417faaf1ec181f9acd9 Mon Sep 17 00:00:00 2001 From: Jannik Date: Thu, 26 Apr 2018 15:13:15 +0200 Subject: [PATCH 31/32] autoplay fixes * HomeFlix should atoplay the next episode evene the jump between episodes or seasons is greater than 1 * if a movie is not found at the omdb we are searching for it, this shoul work for the most movies --- .../HomeFlix/controller/DBController.java | 65 ++++++++++++------- .../controller/OMDbAPIController.java | 21 ++++-- .../HomeFlix/player/PlayerController.java | 2 +- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java index 6c74049..8ef2aac 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/DBController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/DBController.java @@ -335,7 +335,7 @@ public class DBController { if (source.getMode().equals("local")) { for (File file : new File(source.getPath()).listFiles()) { String mimeType = URLConnection.guessContentTypeFromName(file.getPath()); - // if file is file and has mime type "video" TODO needs testing + // if file is file and has mime type "video" if (file.isFile() && mimeType != null && mimeType.contains("video")) { // get all files (films) if (!filmsdbStreamURL.contains(file.getPath())) { @@ -667,40 +667,59 @@ public class DBController { } } - /** TODO check if we relay need to separate between favorites and none favorites + /** * 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 nextEp, int season) { + public FilmTabelDataType getNextEpisode(String title, int episode, int season) { FilmTabelDataType nextFilm = null; + ResultSet rs; + int nextEpisode = 3000; + try { Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title + "\" AND episode = \"" - + nextEp + "\" AND season = \"" + season + "\";"); - if (rs.next()) { - if (rs.getBoolean("favorite") == true) { + + 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)); - } 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)); } - } else { - rs = stmt.executeQuery("SELECT * FROM films WHERE title = \"" + title - + "\" AND episode = \"1\" AND season = \"" + (season + 1) + "\";"); - 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 (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)); + } } } } diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index e60db8f..a02d6fb 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -34,6 +34,7 @@ import org.apache.logging.log4j.Logger; import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; +import com.eclipsesource.json.JsonValue; import javafx.application.Platform; import kellerkinder.HomeFlix.application.Main; @@ -75,6 +76,7 @@ public class OMDbAPIController implements Runnable { output = ina.readLine(); ina.close(); LOGGER.info("response from " + URL + " was valid"); + LOGGER.info("Title was: " + mainWindowController.getCurrentTitle()); LOGGER.info(output); } catch (IOException e) { LOGGER.error("error while making api request or reading response"); @@ -86,6 +88,7 @@ public class OMDbAPIController implements Runnable { 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 // query the api try { @@ -94,8 +97,8 @@ public class OMDbAPIController implements Runnable { BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream())); output = ina.readLine(); ina.close(); - System.out.println(apiUrl); LOGGER.info("response from search " + URL + " was valid"); + LOGGER.info("Title was: " + mainWindowController.getCurrentTitle()); LOGGER.info(output); } catch (Exception e) { LOGGER.error("error while making api request or reading response"); @@ -104,13 +107,17 @@ public class OMDbAPIController implements Runnable { } JsonObject searchObject = Json.parse(output).asObject(); - // TODO new query with the actual title - if (object.getString("Response", "").equals("True")) { - System.out.println(searchObject.getString("Title", "")); + if (searchObject.getString("Response", "").equals("True")) { + for (JsonValue movie : searchObject.get("Search").asArray()) { + // get first entry from the array and set object = movie + // TODO probably we have a NullPointerException here! + object = (JsonObject) movie; + System.out.println(movie.toString()); + break; + + } + System.out.println(object.getString("Title", "")); } - - System.out.println("Movie not found, not setting cache"); - return; } // add the response to the responseString[] diff --git a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java index e6b090d..40fcee6 100644 --- a/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java +++ b/src/main/java/kellerkinder/HomeFlix/player/PlayerController.java @@ -149,7 +149,7 @@ public class PlayerController { 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 + 1), season); + FilmTabelDataType nextFilm = mainWCon.getDbController().getNextEpisode(film.getTitle(), episode, season); if (nextFilm != null) { mediaPlayer.stop(); init(mainWCon, player, nextFilm); From 535efd98ee7b16b9d6d64130fffb56cc0837dd98 Mon Sep 17 00:00:00 2001 From: Jannik Date: Fri, 27 Apr 2018 15:06:40 +0200 Subject: [PATCH 32/32] release 0.7.0 * version 0.6.100 -> 0.7.0 * fixed a nullpointer if there is a false response from omdbapi --- pom.xml | 2 +- .../application/MainWindowController.java | 4 ++-- .../controller/OMDbAPIController.java | 24 ++++++++++--------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 5977fc7..95f22a2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.kellerkinder Project-HomeFlix - 0.6.99 + 0.7.0 jar Project-HomeFlix diff --git a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java index 74bcdd1..45cb8b0 100644 --- a/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java +++ b/src/main/java/kellerkinder/HomeFlix/application/MainWindowController.java @@ -209,9 +209,9 @@ public class MainWindowController { private static final Logger LOGGER = LogManager.getLogger(MainWindowController.class.getName()); private int hashA = -647380320; - private final String version = "0.6.100"; + private final String version = "0.7.0"; private final String buildNumber = "151"; - private final String versionName = "toothless dragon RC"; + private final String versionName = "toothless dragon"; private String dialogBtnStyle; private String color; private String local; diff --git a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java index a02d6fb..bc4db09 100644 --- a/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java +++ b/src/main/java/kellerkinder/HomeFlix/controller/OMDbAPIController.java @@ -75,12 +75,11 @@ public class OMDbAPIController implements Runnable { BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream())); output = ina.readLine(); ina.close(); - LOGGER.info("response from " + URL + " was valid"); - LOGGER.info("Title was: " + mainWindowController.getCurrentTitle()); - LOGGER.info(output); + System.out.println(apiUrl); + LOGGER.info("response from '" + URL + "&t=" + mainWindowController.getCurrentTitle() + "' was:" + output); } catch (IOException e) { 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; } @@ -89,20 +88,21 @@ public class OMDbAPIController implements Runnable { 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 - // query the api + /** 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 search " + URL + " was valid"); - LOGGER.info("Title was: " + mainWindowController.getCurrentTitle()); - LOGGER.info(output); + 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 search" + URL + " was: \n" + output, e); + LOGGER.error("response from '" + URL + "&s=" + mainWindowController.getCurrentTitle() + "' was:" + output, e); return; } @@ -110,13 +110,15 @@ public class OMDbAPIController implements Runnable { if (searchObject.getString("Response", "").equals("True")) { for (JsonValue movie : searchObject.get("Search").asArray()) { // get first entry from the array and set object = movie - // TODO probably we have a NullPointerException here! 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; } }