diff --git a/XR3PlayerUpdatePage.html b/XR3PlayerUpdatePage.html index 668f8966..6ac13313 100644 --- a/XR3PlayerUpdatePage.html +++ b/XR3PlayerUpdatePage.html @@ -716,23 +716,52 @@

1.8.0_111

+
+ +
+

+ --Update 67-- Important update!
+

+

+ ChangeLog : +

+

+
*80% of application settings are being saved [ Until now only ~25% was being saved ] +
*Important Bug Fixes +
*User Interface Improvements +
*Maximum allowed characters for rename extended from 150 -> 250 +
*More advanced settings have been added +
*Search Songs Using Countries and Tags is coming soon :) +

+

+ Released Date : +

+

13/05/2017

+

+ Minimum Java[JRE] Version : +

+

1.8.0_111

+
+

- //TODO in next updates +
*Absolute Re-Implementation of Speech Recognition Mechanism which is not used until now +
*Ability to search media using different Countries [ Example. I want only English and Greek songs ] +
*Players must have history of played songs +
*Mechanism for saving all the application settings [ 70% implemented since 12/05/2017 using ->Properties + JSON] +
*Add bar charts about different topics [Example categories of music that user prefers to listen ]
*Media needs to have an advanced information window
*More advanced search on playlists [ More options ]
*Updates must be queued on the PlayLists using an external Thread
*User must be capable of downloading Files from WebBrowser
*Web Browser must open new tabs when scroll is clicked
*User must be capable of downloading Files using external URL's -
*Ability to search media using different Countries [ Example. I want only English and Greek songs ] -
*Players must have history of played songs
*Players must have the ability to play songs in row using their own playlists

-

02/05/2017

+

13/05/2017 by Alex :)

diff --git a/resources/fxml/ApplicationSettingsController.fxml b/resources/fxml/ApplicationSettingsController.fxml index 1165744b..2e316c62 100644 --- a/resources/fxml/ApplicationSettingsController.fxml +++ b/resources/fxml/ApplicationSettingsController.fxml @@ -8,13 +8,15 @@ - +
- + + +
diff --git a/resources/fxml/GeneralSettingsController.fxml b/resources/fxml/GeneralSettingsController.fxml new file mode 100644 index 00000000..685028ab --- /dev/null +++ b/resources/fxml/GeneralSettingsController.fxml @@ -0,0 +1,44 @@ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/resources/fxml/LoginScreenController.fxml b/resources/fxml/LoginScreenController.fxml index 5c2f785c..1935c225 100644 --- a/resources/fxml/LoginScreenController.fxml +++ b/resources/fxml/LoginScreenController.fxml @@ -4,6 +4,7 @@ + @@ -23,7 +24,7 @@ - +
@@ -76,7 +77,7 @@ - + @@ -174,11 +175,20 @@ @@ -239,22 +249,9 @@ - -
- -
- - - - - + + + @@ -293,7 +290,7 @@ - + + + - -
+ + +
diff --git a/resources/fxml/PlayListsSettingsController.fxml b/resources/fxml/PlayListsSettingsController.fxml index 92cb33ae..3bfabe76 100644 --- a/resources/fxml/PlayListsSettingsController.fxml +++ b/resources/fxml/PlayListsSettingsController.fxml @@ -13,7 +13,7 @@ - + @@ -34,7 +34,10 @@ - + + + + - + + + + - + + + + @@ -104,7 +119,10 @@ - + + + +
diff --git a/resources/fxml/TopBar.fxml b/resources/fxml/TopBar.fxml index ca700326..c40dee9c 100644 --- a/resources/fxml/TopBar.fxml +++ b/resources/fxml/TopBar.fxml @@ -98,7 +98,7 @@
-
+ +
+ diff --git a/resources/fxml/VisualizerWindowController.fxml b/resources/fxml/VisualizerWindowController.fxml index cba8ae48..5ac9cc77 100644 --- a/resources/fxml/VisualizerWindowController.fxml +++ b/resources/fxml/VisualizerWindowController.fxml @@ -122,6 +122,9 @@ + + +
diff --git a/resources/fxml/WebBrowserTabController.fxml b/resources/fxml/WebBrowserTabController.fxml index 02d9de45..6e6a8329 100644 --- a/resources/fxml/WebBrowserTabController.fxml +++ b/resources/fxml/WebBrowserTabController.fxml @@ -57,12 +57,12 @@ - + - + diff --git a/resources/fxml/XPlayerExtraSettingsController.fxml b/resources/fxml/XPlayerExtraSettingsController.fxml new file mode 100644 index 00000000..1c5f8065 --- /dev/null +++ b/resources/fxml/XPlayerExtraSettingsController.fxml @@ -0,0 +1,35 @@ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/resources/fxml/XPlayerSettingsController.fxml b/resources/fxml/XPlayerSettingsController.fxml deleted file mode 100644 index 0d473de8..00000000 --- a/resources/fxml/XPlayerSettingsController.fxml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
diff --git a/resources/fxml/XPlayersSettingsController.fxml b/resources/fxml/XPlayersSettingsController.fxml new file mode 100644 index 00000000..4c04b32c --- /dev/null +++ b/resources/fxml/XPlayersSettingsController.fxml @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+ + + + + + + +
+
diff --git a/resources/image/Add User Group Woman Man-32.png b/resources/image/Add User Group Woman Man-32.png new file mode 100644 index 00000000..a3fdf974 Binary files /dev/null and b/resources/image/Add User Group Woman Man-32.png differ diff --git a/resources/image/DJ-32.png b/resources/image/DJ-32.png deleted file mode 100644 index 1315276f..00000000 Binary files a/resources/image/DJ-32.png and /dev/null differ diff --git a/resources/image/Domain-32.png b/resources/image/Domain-32.png index a90483e5..855361c1 100644 Binary files a/resources/image/Domain-32.png and b/resources/image/Domain-32.png differ diff --git a/resources/image/Library-32.png b/resources/image/Library-32.png index 396d25e0..c11897f1 100644 Binary files a/resources/image/Library-32.png and b/resources/image/Library-32.png differ diff --git a/resources/image/MusicRecord-32.png b/resources/image/MusicRecord-32.png new file mode 100644 index 00000000..0357d348 Binary files /dev/null and b/resources/image/MusicRecord-32.png differ diff --git a/resources/image/User Location-32.png b/resources/image/User Location-32.png deleted file mode 100644 index 096906da..00000000 Binary files a/resources/image/User Location-32.png and /dev/null differ diff --git a/resources/image/UserGroupManWoman-32.png b/resources/image/UserGroupManWoman-32.png new file mode 100644 index 00000000..f84d2143 Binary files /dev/null and b/resources/image/UserGroupManWoman-32.png differ diff --git a/resources/image/application_background.jpg b/resources/image/application_background.jpg new file mode 100644 index 00000000..aab555c2 Binary files /dev/null and b/resources/image/application_background.jpg differ diff --git a/resources/image/flag 24.png b/resources/image/flag 24.png new file mode 100644 index 00000000..4827d385 Binary files /dev/null and b/resources/image/flag 24.png differ diff --git a/resources/image/home.png b/resources/image/home.png deleted file mode 100644 index e3039ef0..00000000 Binary files a/resources/image/home.png and /dev/null differ diff --git a/resources/image/noMusic.png b/resources/image/noMusic.png index bffc04ca..b38a725c 100644 Binary files a/resources/image/noMusic.png and b/resources/image/noMusic.png differ diff --git a/resources/image/visualizer.jpg b/resources/image/visualizer.jpg deleted file mode 100644 index 94d6134d..00000000 Binary files a/resources/image/visualizer.jpg and /dev/null differ diff --git a/resources/style/application.css b/resources/style/application.css index 58341203..b6338581 100644 --- a/resources/style/application.css +++ b/resources/style/application.css @@ -6,7 +6,6 @@ - /* .icon{ -fx-text-fill: #FE774D; -fx-padding: 10.0; @@ -28,6 +27,21 @@ } */ +.chart-pie-label { + -fx-fill: white; + /*-fx-font-weight:bold;*/ + -fx-font-size: 1em; +} + +.chart .chart-title .text{ + -fx-font-weight:bold; + -fx-fill:white; +} + +.chart .chart-content .chart-pie-label-line { + -fx-stroke: #8b4513; + -fx-fill: #8b4513; +} /******************************************************************************* @@ -674,7 +688,7 @@ .context-menu { - -fx-background-color:rgb(0,0,0,0.95); + -fx-background-color:rgb(0.0,0.0,0.0,0.95); -fx-background-radius:4.0; /*-fx-border-width:2.0; -fx-border-style:segments(4.0); */ @@ -684,7 +698,7 @@ .menu-item .label{ -fx-text-fill:white; -fx-font-weight:bold; - -fx-font-size:13; + -fx-font-size:13.0; } .menu-item:focused { @@ -1239,13 +1253,19 @@ } .menu-button .label:hover{ - -fx-text-fill:orange; + -fx-background-color:rgb(0.0,0.0,0.0,0.7); + -fx-text-fill:white; } .visWindowMenuButton .label{ -fx-text-fill:white; } +.visWindowMenuButton .label:hover{ + -fx-background-color:rgb(0.0,0.0,0.0,0.7); + -fx-text-fill:white; +} + /******************************************************************************* @@ -1277,65 +1297,47 @@ ******************************************************************************/ +/* Universal */ +.leftPane:hover , .rightPane:hover , .topPane:hover , .bottomPane:hover , .topLeftPane:hover , .topRightPane:hover , .bottomRightPane:hover , .bottomLeftPane:hover { + -fx-background-color:rgb(255,0,0,0.8); + -fx-border-width:2.0; + /*-fx-border-style:dotted ; */ +} /* Sides */ -.leftPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; +.leftPane:hover{ -fx-border-color:transparent transparent transparent black; } .rightPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; -fx-border-color:transparent black transparent transparent; } .topPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; -fx-border-color:black transparent transparent transparent; } .bottomPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; -fx-border-color:transparent transparent black transparent; } /* Corners */ .topLeftPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; -fx-border-color:black transparent transparent black; } .topRightPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; -fx-border-color:black black transparent transparent; } -.bottomRightPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; +.bottomRightPane:hover{ -fx-border-color:transparent black black transparent; } -.bottomLeftPane:hover{ - -fx-background-color:white; - -fx-border-width:2.0; - -fx-border-style:dotted ; +.bottomLeftPane:hover{ -fx-border-color:transparent transparent black black; } diff --git a/src/aaTester/GroovyTester.groovy b/src/aaTester/GroovyTester.groovy deleted file mode 100644 index 8a7b0446..00000000 --- a/src/aaTester/GroovyTester.groovy +++ /dev/null @@ -1,31 +0,0 @@ -/** - * - */ -package aaTester - -/** - * @author GOXR3PLUS - * - */ -public class GroovyTester { - - def i = -1 - - public GroovyTester() { - println"Hello from Groovy!!!" - def list = 4 .. 1 - //list.sort(true) - //list.forEach( - //list.each{ println l } - def list2 = ["Lars", "Ben", "Jack"] - - list2.each { print "Fuck yo mama $it \n"} - } - - - // O MY GOD IT'S GROOVY!!!!!!!!!!!! - //The future language of XR3Player!! - static def main(args) { - new InternetConnectionTester() - } -} diff --git a/src/aaTester/PropertiesTesting.java b/src/aaTester/PropertiesTesting.java new file mode 100644 index 00000000..91813895 --- /dev/null +++ b/src/aaTester/PropertiesTesting.java @@ -0,0 +1,69 @@ +package aaTester; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; + +public class PropertiesTesting { + Properties properties = new Properties(); + + public PropertiesTesting() { + writeSomething(); + writeSomething2(); + } + + public void writeSomething() { + + try (InputStream inStream = new FileInputStream("config.properties"); OutputStream outStream = new FileOutputStream("config.properties")) { + + properties.load(inStream); + + // set the properties value + + properties.setProperty("database", "localhost"); + properties.setProperty("dbuser", "mkyong"); + properties.setProperty("dbpassword", "password"); + + System.out.println(properties.getProperty("bitch")); + + // save properties to project root folder + properties.store(outStream, null); + + } catch (IOException io) { + io.printStackTrace(); + } + + System.out.println("Write Something finished..."); + } + + public void writeSomething2() { + try (InputStream inStream = new FileInputStream("config.properties"); OutputStream outStream = new FileOutputStream("config.properties")) { + + properties.load(inStream); + + // set the properties value + + properties.setProperty("database2", "localhost"); + properties.setProperty("dbuser", "O_O"); + properties.setProperty("dbpassword3", "password"); + + // save properties to project root folder + properties.store(outStream, null); + + } catch (IOException io) { + io.printStackTrace(); + } + + System.out.println("Write Something 2 finished..."); + } + + public static void main(String[] args) { + + new PropertiesTesting(); + + } + +} \ No newline at end of file diff --git a/src/application/Main.java b/src/application/Main.java index 7270f792..63d11402 100644 --- a/src/application/Main.java +++ b/src/application/Main.java @@ -10,6 +10,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Optional; +import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; @@ -23,7 +25,7 @@ import application.users.User; import application.users.UserMode; import borderless.BorderlessScene; -import database.LocalDBManager; +import database.DbManager; import javafx.animation.PauseTransition; import javafx.application.Application; import javafx.application.Platform; @@ -52,6 +54,7 @@ import smartcontroller.SmartControllerSearcher.AdvancedSearch; import tools.ActionTool; import tools.InfoTool; +import tools.JavaFXTools; import tools.NotificationType; import treeview.TreeViewManager; import webBrowser.WebBrowserController; @@ -184,12 +187,12 @@ public class Main extends Application { /** * The current update of XR3Player */ - public static final int currentVersion = 66; + public static final int currentVersion = 67; /** * This application version release date */ - public static final String releaseDate = "09/05/2017"; + public static final String releaseDate = "13/05/2017"; /** The can save data. */ public static boolean canSaveData = true; @@ -199,7 +202,7 @@ public class Main extends Application { // --------------START: The below have depencities on others------------------------ /** The Constant dbManager. */ - public static LocalDBManager dbManager; + public static DbManager dbManager; /** The Constant libraryMode. */ public static LibraryMode libraryMode = new LibraryMode(); @@ -247,7 +250,7 @@ public void start(Stage primaryStage) throws Exception { //applicationBorderPane.setStyle("-fx-background-color:black;") // applicationBorderPane.setCenter(root) - //LoginMode + //LoginMode loginMode.setLeft(sideBar); sideBar.prepareForLoginMode(true); @@ -371,7 +374,7 @@ public void start(Stage primaryStage) throws Exception { @Override public void init() { - System.out.println("Hello from init"); + System.out.println("JavaFX Init Method Called"); } /** @@ -458,7 +461,7 @@ private static void determineBackgroundImage() { if (backgroundFound) return; - Image img = new Image("/image/visualizer.jpg"); + Image img = new Image("/image/application_background.jpg"); BackgroundImage bgImg = new BackgroundImage(img, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, new BackgroundSize(window.getWidth(), window.getHeight(), true, true, true, true)); root.setBackground(new Background(bgImg)); @@ -502,7 +505,7 @@ public static void startAppWithUser(User u) { //----------------START:initialize everything needed------------------------------------------ //Create this in a Thread - Thread s = new Thread(() -> dbManager = new LocalDBManager(u.getUserName())); + Thread s = new Thread(() -> dbManager = new DbManager(u.getUserName())); s.start(); //Do the below until the database is initialized @@ -555,6 +558,9 @@ public static void startAppWithUser(User u) { } catch (InterruptedException ex) { ex.printStackTrace(); } + + loadApplicationSettings(); + dbManager.loadApplicationDataBase(); // dbManager.recreateJSonDataBase() @@ -751,6 +757,77 @@ public static void restartTheApplication(boolean askUser) { }, "Restart Application Thread").start(); } + /** + * Loads all the application settings from the property file + */ + public static void loadApplicationSettings() { + try { + + //Start + System.out.println("\n\n-----App Settings--------------\n"); + + Properties settings = dbManager.getPropertiesDb().getProperties(); + settings.forEach((key, value) -> System.out.println(key + ":" + value)); + + //Example + Optional.ofNullable(settings.getProperty("")).ifPresent(s -> { + System.out.println(s); + + }); + + //---------- -------------------- + + //--General-Settings + Optional.ofNullable(settings.getProperty("General-SideBarSide")).ifPresent(s -> JavaFXTools + .selectToggleOnIndex(Main.settingsWindow.getGeneralSettingsController().getSideBarSideGroup(), Integer.valueOf(s))); + + //--Libraries-Settings + Optional.ofNullable(settings.getProperty("Libraries-ShowWidgets")) + .ifPresent(s -> Main.settingsWindow.getLibrariesSettingsController().getShowWidgets().setSelected(Boolean.parseBoolean(s))); + + //--Playlists-Settings-Search + Optional.ofNullable(settings.getProperty("PlayLists-Search-InstantSearch")) + .ifPresent(s -> Main.settingsWindow.getPlayListsSettingsController().getInstantSearch().setSelected(Boolean.parseBoolean(s))); + + Optional.ofNullable(settings.getProperty("PlayLists-Search-FileSearchUsing")).ifPresent(s -> JavaFXTools + .selectToggleOnIndex(Main.settingsWindow.getPlayListsSettingsController().getFileSearchGroup(), Integer.valueOf(s))); + + //--Playlists-Settings-General + + Optional.ofNullable(settings.getProperty("PlayLists-General-PlayedFilesDetection")).ifPresent(s -> JavaFXTools + .selectToggleOnIndex(Main.settingsWindow.getPlayListsSettingsController().getPlayedFilesDetectionGroup(), Integer.valueOf(s))); + + Optional.ofNullable(settings.getProperty("PlayLists-General-TotalFilesShown")).ifPresent(s -> JavaFXTools + .selectToggleOnIndex(Main.settingsWindow.getPlayListsSettingsController().getTotalFilesShownGroup(), Integer.valueOf(s))); + + //--XPlayers-Visualizer-Settings + Optional.ofNullable(settings.getProperty("XPlayers-Visualizer-ShowFPS")).ifPresent(s -> { + + //Set the Value to the CheckBox + Main.settingsWindow.getxPlayersSettingsController().getShowFPS().setSelected(Boolean.parseBoolean(s)); + + //Update all the players + Main.xPlayersList.getList().forEach(xPlayerController -> xPlayerController.visualizer.setShowFPS(Boolean.parseBoolean(s))); + + }); + + //--XPlayers-General-Settings + Optional.ofNullable(settings.getProperty("XPlayers-General-StartAtOnce")) + .ifPresent(s -> Main.settingsWindow.getxPlayersSettingsController().getStartImmediately().setSelected(Boolean.parseBoolean(s))); + + Optional.ofNullable(settings.getProperty("XPlayers-General-AskSecurityQuestion")).ifPresent( + s -> Main.settingsWindow.getxPlayersSettingsController().getAskSecurityQuestion().setSelected(Boolean.parseBoolean(s))); + + //---------- -------------------- + + //Finish + System.out.println("\n-----App Settings Finish--------------\n\n"); + + } catch (Exception ex) { + ex.printStackTrace(); + } + } + /** * Main Method. * diff --git a/src/application/SideBar.java b/src/application/SideBar.java index 55fce8dc..3683d4d3 100644 --- a/src/application/SideBar.java +++ b/src/application/SideBar.java @@ -17,6 +17,7 @@ import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.geometry.NodeOrientation; import javafx.scene.control.Label; import javafx.scene.control.MenuButton; import javafx.scene.control.MenuItem; @@ -191,6 +192,25 @@ public void toogleBar() { hideBar(); } + /** + * Changes the side of the SideBar + * + * @param orientation + */ + public void changeSide(NodeOrientation orientation) { + + Main.root.getChildren().remove(this); + + //Check the orientation + if (orientation == NodeOrientation.LEFT_TO_RIGHT) + Main.root.setLeft(this); + else if (orientation == NodeOrientation.RIGHT_TO_LEFT) + Main.root.setRight(this); + + //Set the orientation + this.setNodeOrientation(orientation); + } + String style = "-fx-background-radius: 15 0 0 15; -fx-background-color:black; -fx-border-width:0 4 0 0;"; // /** @@ -288,7 +308,7 @@ private void initialize() { hideSideBar.setOnAction(a -> toogleBar()); //applicationSettings - applicationSettings.setOnAction(a -> Main.settingsWindow.showWindow(SettingsTab.ANYONE)); + applicationSettings.setOnAction(a -> Main.settingsWindow.showWindow(SettingsTab.GENERERAL)); //applicationConverter applicationConverter.setOnAction(a -> ActionTool.openWebSite("https://www.onlinevideoconverter.com/en/video-converter")); diff --git a/src/application/settings/window/ApplicationSettingsController.java b/src/application/settings/window/ApplicationSettingsController.java index 98384a7c..eab70e34 100644 --- a/src/application/settings/window/ApplicationSettingsController.java +++ b/src/application/settings/window/ApplicationSettingsController.java @@ -29,19 +29,24 @@ public class ApplicationSettingsController extends BorderPane { * */ public enum SettingsTab { - LIBRARIES, PLAYLISTS, SHORTCUTS, ANYONE; + GENERERAL, LIBRARIES, PLAYLISTS, SHORTCUTS, XPLAYERS, ANYONE; } - @FXML - private Tab librariesTab; + private Tab generalTab; @FXML private Tab playListsTab; + @FXML + private Tab librariesTab; + @FXML private Tab shortCutsTab; + @FXML + private Tab xPlayersTab; + @FXML private Button doneButton; @@ -55,9 +60,11 @@ public enum SettingsTab { */ private Stage window = new Stage(); - private KeyBindingsController nativeKeyBindings = new KeyBindingsController(); + private GeneralSettingsController generalSettingsController = new GeneralSettingsController(); + private KeyBindingsController nativeKeyBindingsController = new KeyBindingsController(); private PlaylistsSettingsController playListsSettingsController = new PlaylistsSettingsController(); private LibrariesSettingsController librariesSettingsController = new LibrariesSettingsController(); + private XPlayersSettingsController xPlayersSettingsController = new XPlayersSettingsController(); /** * Constructor @@ -93,12 +100,16 @@ public ApplicationSettingsController() { */ public void showWindow(SettingsTab settingsTab) { - if (settingsTab == SettingsTab.LIBRARIES) + if (settingsTab == SettingsTab.GENERERAL) librariesTab.getTabPane().getSelectionModel().select(0); else if (settingsTab == SettingsTab.PLAYLISTS) librariesTab.getTabPane().getSelectionModel().select(1); - else if (settingsTab == SettingsTab.SHORTCUTS) + else if (settingsTab == SettingsTab.LIBRARIES) librariesTab.getTabPane().getSelectionModel().select(2); + else if (settingsTab == SettingsTab.SHORTCUTS) + librariesTab.getTabPane().getSelectionModel().select(3); + else if (settingsTab == SettingsTab.XPLAYERS) + librariesTab.getTabPane().getSelectionModel().select(4); window.show(); } @@ -122,9 +133,12 @@ public Stage getWindow() { */ @FXML private void initialize() { + + generalTab.setContent(generalSettingsController); librariesTab.setContent(librariesSettingsController); playListsTab.setContent(playListsSettingsController); - shortCutsTab.setContent(nativeKeyBindings); + shortCutsTab.setContent(nativeKeyBindingsController); + xPlayersTab.setContent(xPlayersSettingsController); //doneButton doneButton.setOnAction(a -> hideWindow()); @@ -141,7 +155,7 @@ public PlaylistsSettingsController getPlayListsSettingsController() { * @return the nativeKeyBindings */ public KeyBindingsController getNativeKeyBindings() { - return nativeKeyBindings; + return nativeKeyBindingsController; } /** @@ -151,4 +165,18 @@ public LibrariesSettingsController getLibrariesSettingsController() { return librariesSettingsController; } + /** + * @return the generalSettingsController + */ + public GeneralSettingsController getGeneralSettingsController() { + return generalSettingsController; + } + + /** + * @return the xPlayersSettingsController + */ + public XPlayersSettingsController getxPlayersSettingsController() { + return xPlayersSettingsController; + } + } diff --git a/src/application/settings/window/GeneralSettingsController.java b/src/application/settings/window/GeneralSettingsController.java new file mode 100644 index 00000000..3b7675fe --- /dev/null +++ b/src/application/settings/window/GeneralSettingsController.java @@ -0,0 +1,80 @@ +/** + * + */ +package application.settings.window; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import application.Main; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.geometry.NodeOrientation; +import javafx.scene.control.ToggleGroup; +import javafx.scene.layout.BorderPane; +import tools.InfoTool; +import tools.JavaFXTools; + +/** + * @author GOXR3PLUS + * + */ +public class GeneralSettingsController extends BorderPane { + + //----------------------------------------------------- + + @FXML + private ToggleGroup sideBarSideGroup; + + // ------------------------------------------------------------- + + /** The logger. */ + private final Logger logger = Logger.getLogger(getClass().getName()); + + /** + * Constructor. + */ + public GeneralSettingsController() { + + // ------------------------------------FXMLLOADER ---------------------------------------- + FXMLLoader loader = new FXMLLoader(getClass().getResource(InfoTool.FXMLS + "GeneralSettingsController.fxml")); + loader.setController(this); + loader.setRoot(this); + + try { + loader.load(); + } catch (IOException ex) { + logger.log(Level.SEVERE, "", ex); + } + + } + + /** + * Called as soon as .fxml is initialized + */ + @FXML + private void initialize() { + + //sideBarSideGroup + sideBarSideGroup.selectedToggleProperty().addListener(listener -> { + + //Update the properties file + Main.dbManager.getPropertiesDb().updateProperty("General-SideBarSide", + Integer.toString(JavaFXTools.getIndexOfSelectedToggle(sideBarSideGroup))); + + //Fix the side bar position + Main.sideBar.changeSide( + JavaFXTools.getIndexOfSelectedToggle(sideBarSideGroup) == 0 ? NodeOrientation.LEFT_TO_RIGHT : NodeOrientation.RIGHT_TO_LEFT); + }); + + } + + /** + * @return the sideBarSideGroup + */ + public ToggleGroup getSideBarSideGroup() { + return sideBarSideGroup; + } + +} diff --git a/src/application/settings/window/LibrariesSettingsController.java b/src/application/settings/window/LibrariesSettingsController.java index 9a3482e4..bd8da0fd 100644 --- a/src/application/settings/window/LibrariesSettingsController.java +++ b/src/application/settings/window/LibrariesSettingsController.java @@ -6,13 +6,14 @@ import com.jfoenix.controls.JFXCheckBox; +import application.Main; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.layout.BorderPane; import tools.InfoTool; /** - * This class is used as the SideBar of the application. + * * * @author GOXR3PLUS */ @@ -52,6 +53,9 @@ public LibrariesSettingsController() { @FXML private void initialize() { + //Listener + showWidgets.selectedProperty() + .addListener(l -> Main.dbManager.getPropertiesDb().updateProperty("Libraries-ShowWidgets", String.valueOf(showWidgets.isSelected()))); } /** diff --git a/src/application/settings/window/PlaylistsSettingsController.java b/src/application/settings/window/PlaylistsSettingsController.java index 9836f1f6..b3aa2e85 100644 --- a/src/application/settings/window/PlaylistsSettingsController.java +++ b/src/application/settings/window/PlaylistsSettingsController.java @@ -17,10 +17,11 @@ import javafx.util.Duration; import tools.ActionTool; import tools.InfoTool; +import tools.JavaFXTools; import tools.NotificationType; /** - * This class is used as the SideBar of the application. + * * * @author GOXR3PLUS */ @@ -75,9 +76,33 @@ public PlaylistsSettingsController() { @FXML private void initialize() { + //accordion + accordion.setExpandedPane(accordion.getPanes().get(1)); + + //--Playlists-Settings-Search-------------- + + //instantSearch + instantSearch.selectedProperty().addListener( + l -> Main.dbManager.getPropertiesDb().updateProperty("PlayLists-Search-InstantSearch", String.valueOf(instantSearch.isSelected()))); + + //fileSearchGroup + fileSearchGroup.selectedToggleProperty().addListener(listener -> Main.dbManager.getPropertiesDb() + .updateProperty("PlayLists-Search-FileSearchUsing", Integer.toString(JavaFXTools.getIndexOfSelectedToggle(fileSearchGroup)))); + + //--Playlists-Settings-General-------------- + + //playedFilesDetectionGroup + playedFilesDetectionGroup.selectedToggleProperty() + .addListener(listener -> Main.dbManager.getPropertiesDb().updateProperty("PlayLists-General-PlayedFilesDetection", + Integer.toString(JavaFXTools.getIndexOfSelectedToggle(playedFilesDetectionGroup)))); + //totalFilesShownGroup totalFilesShownGroup.selectedToggleProperty().addListener(listener -> { + //Update the properties file + Main.dbManager.getPropertiesDb().updateProperty("PlayLists-General-TotalFilesShown", + Integer.toString(JavaFXTools.getIndexOfSelectedToggle(totalFilesShownGroup))); + //First Update all the Libraries Main.libraryMode.teamViewer.getViewer().getItemsObservableList().forEach(library -> library.getSmartController() .setNewMaximumPerPage(Integer.parseInt(((Labeled) totalFilesShownGroup.getSelectedToggle()).getText()), true)); @@ -98,8 +123,6 @@ private void initialize() { NotificationType.ERROR); }); - //accordion - accordion.setExpandedPane(accordion.getPanes().get(0)); } /** diff --git a/src/application/settings/window/XPlayersSettingsController.java b/src/application/settings/window/XPlayersSettingsController.java new file mode 100644 index 00000000..bb54bb20 --- /dev/null +++ b/src/application/settings/window/XPlayersSettingsController.java @@ -0,0 +1,106 @@ +/** + * + */ +package application.settings.window; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jfoenix.controls.JFXCheckBox; + +import application.Main; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.layout.BorderPane; +import tools.InfoTool; + +/** + * @author GOXR3PLUS + * + */ +public class XPlayersSettingsController extends BorderPane { + + //----------------------------------------------------- + + @FXML + private JFXCheckBox showFPS; + + @FXML + private JFXCheckBox startImmediately; + + @FXML + private JFXCheckBox askSecurityQuestion; + + // ------------------------------------------------------------- + + /** The logger. */ + private final Logger logger = Logger.getLogger(getClass().getName()); + + /** + * Constructor. + */ + public XPlayersSettingsController() { + + // ------------------------------------FXMLLOADER ---------------------------------------- + FXMLLoader loader = new FXMLLoader(getClass().getResource(InfoTool.FXMLS + "XPlayersSettingsController.fxml")); + loader.setController(this); + loader.setRoot(this); + + try { + loader.load(); + } catch (IOException ex) { + logger.log(Level.SEVERE, "", ex); + } + + } + + /** + * Called as soon as .fxml is initialized + */ + @FXML + private void initialize() { + + // ShowFPS + showFPS.setOnAction(a -> { + + //Update the properties file + Main.dbManager.getPropertiesDb().updateProperty("XPlayers-Visualizer-ShowFPS", String.valueOf(showFPS.isSelected())); + + //Update all the players + Main.xPlayersList.getList().forEach(xPlayerController -> xPlayerController.visualizer.setShowFPS(showFPS.isSelected())); + + }); + + // StartImmediately + startImmediately.selectedProperty().addListener( + l -> Main.dbManager.getPropertiesDb().updateProperty("XPlayers-General-StartAtOnce", String.valueOf(startImmediately.isSelected()))); + + // AskSecurityQuestion + askSecurityQuestion.selectedProperty().addListener(l -> Main.dbManager.getPropertiesDb() + .updateProperty("XPlayers-General-AskSecurityQuestion", String.valueOf(askSecurityQuestion.isSelected()))); + + } + + /** + * @return the showFPS + */ + public JFXCheckBox getShowFPS() { + return showFPS; + } + + /** + * @return the startImmediately + */ + public JFXCheckBox getStartImmediately() { + return startImmediately; + } + + /** + * @return the askSecurityQuestion + */ + public JFXCheckBox getAskSecurityQuestion() { + return askSecurityQuestion; + } + +} diff --git a/src/application/users/LoginMode.java b/src/application/users/LoginMode.java index e0916860..a5ef62da 100644 --- a/src/application/users/LoginMode.java +++ b/src/application/users/LoginMode.java @@ -16,6 +16,7 @@ import com.jfoenix.controls.JFXToggleButton; import application.Main; +import javafx.animation.Animation; import javafx.animation.Animation.Status; import javafx.animation.Interpolator; import javafx.animation.KeyFrame; @@ -39,11 +40,11 @@ import javafx.scene.Cursor; import javafx.scene.Group; import javafx.scene.Node; +import javafx.scene.chart.PieChart; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ScrollBar; import javafx.scene.control.ToolBar; -import javafx.scene.input.KeyCode; import javafx.scene.input.MouseButton; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; @@ -108,6 +109,9 @@ public class LoginMode extends BorderPane { @FXML private Button loginButton; + @FXML + private PieChart pieChart; + @FXML private Label createdByLabel; @@ -217,6 +221,9 @@ public LoginMode() { @FXML private void initialize() { + //Set PieChartData + pieChart.setData(pieChartData); + //Below is some coded i used with javafxsvg Library to Display SVG images although i changed it //to using WebView due to the cost of many external libraries // HttpURLConnection httpcon = (HttpURLConnection) new URL( @@ -472,12 +479,12 @@ else if (scroll.getDeltaX() > 0) }); // -- KeyListeners -// setOnKeyReleased(key -> { -// if (key.getCode() == KeyCode.RIGHT) -// next(); -// else if (key.getCode() == KeyCode.LEFT) -// previous(); -// }); + // setOnKeyReleased(key -> { + // if (key.getCode() == KeyCode.RIGHT) + // next(); + // else if (key.getCode() == KeyCode.LEFT) + // previous(); + // }); // this.setOnMouseMoved(m -> { // @@ -942,8 +949,17 @@ public void update() { } + /** + * @return The Timeline + */ + public Animation getTimeline() { + return timeline; + } + } + ObservableList pieChartData = FXCollections.observableArrayList(); + /** * @author GOXR3PLUS * @@ -1011,8 +1027,16 @@ protected Boolean call() throws Exception { Thread.sleep(500); // Refresh the text - Platform.runLater(() -> user.getTotalLibrariesLabel().setText(Integer.toString(totalLibraries[0]))); - System.out.println("User:" + user.getUserName() + " contains : " + totalLibraries + " Libraries"); + Platform.runLater(() -> { + + //Add Pie Chart Data + pieChartData.add(new PieChart.Data(InfoTool.getMinString(user.getUserName(), 4), totalLibraries[0])); + + //Update User Label + user.getTotalLibrariesLabel().setText(Integer.toString(totalLibraries[0])); + + }); + //System.out.println("User:" + user.getUserName() + " contains : " + totalLibraries + " Libraries"); updateProgress(++counter[0], totalUsers); } catch (Exception ex) { diff --git a/src/application/users/User.java b/src/application/users/User.java index 6fb66807..d394f01f 100644 --- a/src/application/users/User.java +++ b/src/application/users/User.java @@ -13,6 +13,7 @@ import java.util.stream.Stream; import application.Main; +import javafx.animation.Animation.Status; import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.Observable; @@ -24,6 +25,7 @@ import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; import javafx.scene.layout.StackPane; import javafx.scene.shape.Rectangle; import javafx.util.Duration; @@ -182,6 +184,11 @@ private void initialize() { //Name nameField.setText(getUserName()); nameField.getTooltip().setText(getUserName()); + nameField.setOnMouseReleased(m -> { + if (m.getButton() == MouseButton.PRIMARY && m.getClickCount() == 2 + && Main.loginMode.teamViewer.getTimeline().getStatus() != Status.RUNNING) + renameUser(nameField); + }); } /** @@ -220,7 +227,8 @@ public Label getNameField() { } /** - * @param nameField the nameField to set + * @param nameField + * the nameField to set */ public void setNameField(Label nameField) { this.nameField = nameField; diff --git a/src/application/users/UserMode.java b/src/application/users/UserMode.java index a9ebb5e6..4d59b452 100644 --- a/src/application/users/UserMode.java +++ b/src/application/users/UserMode.java @@ -8,8 +8,11 @@ import java.util.logging.Logger; import javafx.beans.binding.Bindings; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.scene.chart.PieChart; import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.layout.BorderPane; @@ -21,12 +24,17 @@ */ public class UserMode extends BorderPane { + // ---------------------- + @FXML - private ImageView userImageView; + private PieChart pieChart; @FXML private Label userNameLabel; + @FXML + private ImageView userImageView; + // ---------------------- /** The logger. */ @@ -57,8 +65,8 @@ public UserMode() { @FXML private void initialize() { - // //goBack - // goBack.setOnAction(a -> Main.sideBar.goMainMode()); + pieChart.setData(FXCollections.observableArrayList(new PieChart.Data("Grapefruit", 13), new PieChart.Data("Oranges", 25), + new PieChart.Data("Plums", 10), new PieChart.Data("Pears", 22), new PieChart.Data("Apples", 30))); } /** diff --git a/src/customNodes/Marquee.java b/src/customNodes/Marquee.java index b20c31fd..0230560a 100644 --- a/src/customNodes/Marquee.java +++ b/src/customNodes/Marquee.java @@ -55,9 +55,9 @@ public Marquee() { */ @FXML private void initialize() { - - //Clip - Rectangle rectangle = new Rectangle(25,25); + + //Clip + Rectangle rectangle = new Rectangle(25, 25); rectangle.widthProperty().bind(widthProperty()); rectangle.heightProperty().bind(heightProperty()); setClip(rectangle); @@ -113,8 +113,7 @@ public void handle(ActionEvent event) { text.setLayoutX(OFFSET); timeline.stop(); } else { - if ((rightMovement && layoutX >= OFFSET) - || (!rightMovement && layoutX + textWidth + OFFSET <= paneWidth)) { + if ((rightMovement && layoutX >= OFFSET) || (!rightMovement && layoutX + textWidth + OFFSET <= paneWidth)) { // invert movement, if bounds are reached rightMovement = !rightMovement; } @@ -137,6 +136,7 @@ public void handle(ActionEvent event) { InvalidationListener listener = o -> { double textWidth = text.getLayoutBounds().getWidth(); double paneWidth = getWidth(); + text.setLayoutX(5); if (textWidth + 2 * OFFSET > paneWidth && timeline.getStatus() != Animation.Status.RUNNING) timeline.play(); }; diff --git a/src/database/DbManager.java b/src/database/DbManager.java new file mode 100644 index 00000000..b6ce0c31 --- /dev/null +++ b/src/database/DbManager.java @@ -0,0 +1,421 @@ +/* + * + */ +package database; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Level; + +import application.Main; +import javafx.animation.PauseTransition; +import javafx.application.Platform; +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import javafx.util.Duration; +import librarysystema.Library; +import smartcontroller.Operation; +import tools.ActionTool; +import tools.InfoTool; +import tools.NotificationType; + +/** + * This class is managing the database of the application. + * + * @author GOXR3PLUS + */ +public class DbManager { + + /** The connection 1. */ + public Connection connection1; + + /** The data loader. */ + // Important Tasks + private DataLoader dataLoader = new DataLoader(); + + /** The database file. */ + // -Constructor- + private String dbFileAbsolutePath; + + /** The images folder relative path */ + private String imagesFolderRelativePath; + + /** The images folder absolute path */ + public String imagesFolderAbsolutePath; + + /** The name of the logged in user */ + private String userName; + + /** This executor does the commit job. */ + private final ExecutorService commitExecutor = Executors.newSingleThreadExecutor(); + + /** If true -> The database notifications are shown */ + final boolean showNotifications = false; + + //---------------------- + + /** + * The KeyValueDb + */ + private KeyValueDb keyValueDb; + + /** + * The PropertiesDb + */ + private PropertiesDb propertiesDb; + + //------------------------- + + /** The runnable of the commit executor. */ + private Runnable commitRunnable = () -> { + try { + connection1.commit(); + } catch (SQLException ex) { + Main.logger.log(Level.WARNING, ex.getMessage(), ex); + } finally { + if (showNotifications) + ActionTool.showNotification("Commited", "Changes saved successfully", Duration.millis(150), NotificationType.INFORMATION); + } + + }; + + /** The runnable of the commit executor. */ + private Runnable vacuumRunnable = () -> { + try { + // close + open connection + connection1.commit(); + manageConnection(Operation.CLOSE); + manageConnection(Operation.OPEN); + + // vacuum + connection1.createStatement().executeUpdate("VACUUM"); + + // close connection + manageConnection(Operation.CLOSE); + + // exit + System.exit(0); + } catch (SQLException ex) { + Main.logger.log(Level.WARNING, ex.getMessage(), ex); + System.exit(-1); + } finally { + System.exit(0); + } + + }; + + //----------------------------------------------------------- + + /** + * Constructor. + * + * @param userName + * the user name + */ + public DbManager(String userName) { + // the userName + this.userName = userName; + keyValueDb = new KeyValueDb(this); + propertiesDb = new PropertiesDb(this); + propertiesDb.loadProperties(); + + // user folder + File userFolder = new File(InfoTool.getAbsoluteDatabasePathWithSeparator() + userName); + if (!userFolder.exists()) + userFolder.mkdir(); + + //--images folder + imagesFolderRelativePath = InfoTool.getDatabaseFolderNameWithSeparator() + userName + File.separator + "Images"; + imagesFolderAbsolutePath = InfoTool.getAbsoluteDatabaseParentFolderPathWithSeparator() + imagesFolderRelativePath; + //-- + File imagesFolder = new File(imagesFolderAbsolutePath); + if (!imagesFolder.exists()) + imagesFolder.mkdir(); + + // database file(.db) + dbFileAbsolutePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + userName + File.separator + "dbFile.db"; + boolean data1Exist = new File(dbFileAbsolutePath).exists(); + + try { + // connection1 + connection1 = DriverManager.getConnection("jdbc:sqlite:" + dbFileAbsolutePath); + connection1.setAutoCommit(false); + + if (!data1Exist) + recreateDataBase(); + + keyValueDb.recreateJSonDataBase(); + + } catch (SQLException ex) { + Main.logger.log(Level.SEVERE, "", ex); + } + } + + //------------------- Getters --------------------------------------------------------------- + + /** + * @return the userName + */ + public String getUserName() { + return userName; + } + + /** + * @return the keyValueDb + */ + public KeyValueDb getKeyValueDb() { + return keyValueDb; + } + + /** + * @return the propertiesDb + */ + public PropertiesDb getPropertiesDb() { + return propertiesDb; + } + + //------------------- Setters -------------------------------------------------------------- + /** + * @param userName + * the userName to set + */ + public void setUserName(String userName) { + this.userName = userName; + } + + //------------------- Methods -------------------------------------------------------------- + + /** + * Open or close the connection. + * + * @param action + * the action + */ + public void manageConnection(Operation action) { + try { + // OPEN + if (action == Operation.OPEN && connection1.isClosed()) + connection1 = DriverManager.getConnection("jdbc:sqlite:" + dbFileAbsolutePath); + // CLOSE + else if (action == Operation.CLOSE && !connection1.isClosed()) + connection1.close(); + } catch (SQLException ex) { + Main.logger.log(Level.WARNING, "", ex); + } + } + + /** + * Using this methods to control commits across the application so not to have unexpected lags. + */ + public void commit() { + commitExecutor.execute(commitRunnable); + } + + /** + * Using this methods to control commit + vacuum across the application so not to have unexpected lags. + * + */ + public void commitAndVacuum() { + commitExecutor.execute(vacuumRunnable); + } + + /** + * Stops the executorService. + */ + public void shutdownCommitExecutor() { + commitExecutor.shutdown(); + } + + /** + * Checks if this table exists in the SQL DataBase + * + * @param tableName + * the table name + * @return true, if successful + */ + public boolean doesTableExist(String tableName) { + // SQLite table names are case insensitive, but comparison is case + // sensitive by default. To make this work properly in all cases you + // need to add COLLATE NOCASE + try (ResultSet r = connection1.createStatement() + .executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='" + tableName + "' COLLATE NOCASE ")) { + int total = r.getInt(1); + return total == 0 ? false : true; + } catch (SQLException ex) { + Main.logger.log(Level.INFO, "", ex); + } + + return false; + } + + /** + * Recreates the database if it doesn't exist. + */ + public void recreateDataBase() { + + Main.logger.info("1-->Recreating the database.."); + + try (Statement statement = connection1.createStatement()) { + + // ----------Libraries Table ----------------// + statement.executeUpdate("CREATE TABLE IF NOT EXISTS LIBRARIES (NAME TEXT PRIMARY KEY NOT NULL," + "TABLENAME TEXT NOT NULL," + + "STARS DOUBLE NOT NULL," + "DATECREATED TEXT NOT NULL," + "TIMECREATED TEXT NOT NULL," + + "DESCRIPTION TEXT NOT NULL," + "SAVEMODE INT NOT NULL," + "POSITION INT NOT NULL," + + "LIBRARYIMAGE TEXT," + "OPENED BOOLEAN NOT NULL )"); + + // -----------Radio Stations Table ------------// + // statement.executeUpdate("CREATE TABLE '" + InfoTool.RADIO_STATIONS_DATABASE_TABLE_NAME + "'(NAME TEXT PRIMARY KEY NOT NULL," + // + "STREAMURL TEXT NOT NULL," + "TAGS TEXT NOT NULL," + "DESCRIPTION TEXT," + "STARS DOUBLE NOT NULL)"); + + // ----------XPlayers PlayLists Tables ----------// + // for (int i = 0; i < 3; i++) + // createXPlayListTable(statement, i); + + commit(); + } catch (SQLException ex) { + Main.logger.log(Level.SEVERE, "", ex); + } + } + + /** + * Create a database table for the specific XPlayer. + * + * @param statement + * the statement + * @param key + * the key + * @throws SQLException + * the SQL exception + */ + // private void createXPlayListTable(Statement statement, int key) throws SQLException { + // statement.executeUpdate("CREATE TABLE XPPL" + key + "(PATH TEXT PRIMARY KEY NOT NULL ," + "STARS DOUBLE NOT NULL," + // + "TIMESPLAYED INT NOT NULL," + "DATE TEXT NOT NULL," + "HOUR TEXT NOT NULL)"); + // } + + /** + * This method loads the application database. + */ + public void loadApplicationDataBase() { + Main.updateScreen.setVisible(true); + Main.updateScreen.getProgressBar().progressProperty().bind(dataLoader.progressProperty()); + dataLoader.restart(); + } + + /** + * DataLoader. + * + * @author GOXR3PLUS STUDIO + */ + public class DataLoader extends Service { + + /** The total. */ + int total; + + /** + * Constructor. + */ + public DataLoader() { + + // -------------------if succeeded + setOnSucceeded(s -> { + + //----------------Do the animation with rectangles--------------------- + Main.updateScreen.closeUpdateScreen(); + + //----------------Finall Settings--------------------- + // update library viewer + Main.libraryMode.teamViewer.getViewer().update(); + //Main.libraryMode.libraryViewer.goOnSelectionMode(false) + + // set libraries tree expanded + //Main.treeManager.librariesTree.setExpanded(true) + + //---------------Set the update Screen invisible--------------------- + PauseTransition pause1 = new PauseTransition(Duration.seconds(1)); + pause1.setOnFinished(f -> { + Main.updateScreen.setVisible(false); + Main.updateScreen.getProgressBar().progressProperty().unbind(); + }); + pause1.playFromStart(); + + }); + + // ---------------------if failed + setOnFailed(fail -> { + Main.updateScreen.getProgressBar().progressProperty().unbind(); + ActionTool.showNotification("Fatal Error!", "DataLoader failed during loading dataBase!!Application will exit...", + Duration.millis(1500), NotificationType.ERROR); + System.exit(0); + }); + } + + //TODO-------------------Needs modification cause sometimes it violates JavaFX THREAD!!!!!!!!!!!! + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + int counter; + int total = 1; + updateProgress(0, total); + + // -------------------------- Load all the libraries + try (ResultSet resultSet = connection1.createStatement().executeQuery("SELECT* FROM LIBRARIES;"); + ResultSet dbCounter = connection1.createStatement().executeQuery("SELECT COUNT(*) FROM LIBRARIES;");) { + + total += dbCounter.getInt(1); + Main.logger.info("Loading Libraries...."); + + // Refresh the text + Platform.runLater(() -> Main.updateScreen.getLabel().setText("Loading Libraries...")); + updateProgress(1, 2); + + //Kepp a List of all Libraries + final List libraries = new ArrayList<>(total); + + // Load all the libraries + while (resultSet.next()) { + libraries.add(new Library(resultSet.getString("NAME"), resultSet.getString("TABLENAME"), resultSet.getDouble("STARS"), + resultSet.getString("DATECREATED"), resultSet.getString("TIMECREATED"), resultSet.getString("DESCRIPTION"), + resultSet.getInt("SAVEMODE"), resultSet.getInt("POSITION"), resultSet.getString("LIBRARYIMAGE"), + resultSet.getBoolean("OPENED"))); + + updateProgress(resultSet.getRow() - 1, total); + } + + //Add all the Libraries to the Library Viewer + Platform.runLater(() -> Main.libraryMode.teamViewer.getViewer().addMultipleLibraries(libraries)); + + //Load the Opened Libraries + Platform.runLater(() -> Main.updateScreen.getLabel().setText("Loading Opened Libraries...")); + keyValueDb.loadOpenedLibraries(); + //Calculate opened libraries + Platform.runLater(() -> Main.libraryMode.calculateOpenedLibraries()); + + //Load PlayerMediaList + Platform.runLater(() -> Main.updateScreen.getLabel().setText("Loading previous data...")); + Main.playedSongs.uploadFromDataBase(); + + //--FINISH + updateProgress(total, total); + + } catch (Exception ex) { + Main.logger.log(Level.SEVERE, "", ex); + } + + return null; + } + }; + } + + } + +} diff --git a/src/database/KeyValueDb.java b/src/database/KeyValueDb.java new file mode 100644 index 00000000..b1b09767 --- /dev/null +++ b/src/database/KeyValueDb.java @@ -0,0 +1,292 @@ +/** + * + */ +package database; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.json.simple.DeserializationException; +import org.json.simple.JsonArray; +import org.json.simple.JsonObject; +import org.json.simple.Jsoner; + +import application.Main; +import javafx.application.Platform; +import javafx.collections.ObservableList; +import javafx.scene.control.Tab; +import javafx.util.Duration; +import smartcontroller.SmartController; +import tools.ActionTool; +import tools.InfoTool; +import tools.NotificationType; + +/** + * This class is managing a key-value database + * + * @author GOXR3PLUS + * + */ +public class KeyValueDb { + + /** This executor does the commit job. */ + private static final ExecutorService jSONUpdateExecutor = Executors.newSingleThreadExecutor(); + + DbManager localDBManager; + + /** + * Constructor + * + * @param localDBManager + */ + public KeyValueDb(DbManager localDBManager) { + this.localDBManager = localDBManager; + } + + /** + * Creates the JSONDatabase if it doesn't exitst + * + * @return True if succedeed or False if not + */ + public boolean recreateJSonDataBase() { + String jsonFilePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + localDBManager.getUserName() + File.separator + "settings.json"; + + //File already exists? + if (new File(jsonFilePath).exists()) + return true; + + //JSON Array [ROOT] + JsonObject json = new JsonObject(); + + //-----------Libraries Array------------------ + JsonObject librariesSystem = new JsonObject(); + + //Latest Library that was selected + Opened + JsonObject lastSelectedLibrary = new JsonObject(); + + //Libraries that where opened + JsonArray openedLibraries = new JsonArray(); + // for (int i = 0; i < 2; i++) { + // JsonObject object = new JsonObject(); + // object.put("name", "library->" + i); + // openedLibraries.add(object); + // } + + librariesSystem.put("openedLibraries", openedLibraries); + librariesSystem.put("lastSelectedLibrary", lastSelectedLibrary); + + //--------------XPlayers Array-------------- + + JsonArray xPlayers = new JsonArray(); + for (int i = 0; i < 3; i++) { + JsonObject object = new JsonObject(); + object.put("name", "xPlayer" + i); + xPlayers.add(object); + } + + json.put("librariesSystem", librariesSystem); + json.put("xPlayers", xPlayers); + + //Write to File + try (FileWriter file = new FileWriter(jsonFilePath)) { + file.write(Jsoner.prettyPrint(json.toJson())); + file.flush(); + } catch (IOException e) { + e.printStackTrace(); + //logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ + return false; + } + + return true; + } + + /** + * Loads the Libraries information into the application + * + * @return True if succedeed or False if not + */ + public boolean loadOpenedLibraries() { + + String jsonFilePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + localDBManager.getUserName() + File.separator + "settings.json"; + + //Check if the file exists + if (!new File(jsonFilePath).exists()) + return false; + + //Read the JSON File + try (FileReader fileReader = new FileReader(jsonFilePath)) { + + //JSON Array [ROOT] + JsonObject json = (JsonObject) Jsoner.deserialize(fileReader); + + //Opened Libraries Array + JsonArray openedLibraries = (JsonArray) ((JsonObject) json.get("librariesSystem")).get("openedLibraries"); + + //For each Library + openedLibraries.forEach(libraryObject -> Platform.runLater(() -> + + //Get the Library and Open it! + Main.libraryMode.getLibraryWithName(((JsonObject) libraryObject).get("name").toString()).libraryOpenClose(true, true) + + //Print its name + //System.out.println(((JsonObject) libraryObject).get("name")) + )); + + //Last selected library Array + JsonObject lastSelectedLibrary = (JsonObject) ((JsonObject) json.get("librariesSystem")).get("lastSelectedLibrary"); + + //Add the Listener to multipleLibs + Platform.runLater(() -> { + Main.libraryMode.multipleLibs.getTabPane().getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> { + + // Give a refresh to the newly selected ,!! ONLY IF IT HAS NO ITEMS !! + if (!Main.libraryMode.multipleLibs.getTabPane().getTabs().isEmpty() && ((SmartController) newTab.getContent()).isFree(false) + && ((SmartController) newTab.getContent()).getItemsObservableList().isEmpty()) { + + ((SmartController) newTab.getContent()).loadService.startService(false, true); + + updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabPane().getTabs(), false); + + } + + // //Do an animation + // if (oldTab != null && newTab != null) { + // Node oldContent = oldTab.getContent(); //tabContent.get(oldTab) + // Node newContent = newTab.getContent(); //tabContent.get(newTab) + // + // newTab.setContent(oldContent); + // ScaleTransition fadeOut = new ScaleTransition(Duration.millis(50), oldContent); + // fadeOut.setFromX(1); + // fadeOut.setFromY(1); + // fadeOut.setToX(0); + // fadeOut.setToY(0); + // + // ScaleTransition fadeIn = new ScaleTransition(Duration.millis(50), newContent); + // fadeIn.setFromX(0); + // fadeIn.setFromY(0); + // fadeIn.setToX(1); + // fadeIn.setToY(1); + // + // fadeOut.setOnFinished(event -> newTab.setContent(newContent)); + // + // SequentialTransition crossFade = new SequentialTransition(fadeOut, fadeIn); + // crossFade.play(); + // } + }); + }); + + //If not empty... + if (!lastSelectedLibrary.isEmpty()) { + Platform.runLater(() -> { + + //Select the correct library inside the TabPane + Main.libraryMode.multipleLibs.getTabPane().getSelectionModel() + .select(Main.libraryMode.multipleLibs.getTab(lastSelectedLibrary.get("name").toString())); + + //This will change in future update when user can change the default position of Libraries + Main.libraryMode.teamViewer.getViewer().setCenterIndex(Main.libraryMode.multipleLibs.getSelectedLibrary().getPosition()); + + //System.out.println("Entered !lastSelectedLibrary.isEmpty()") + }); + } + + //Do an Update on the selected Library SmartController + Platform.runLater(() -> { + //Check if empty and if not update the selected library + if (!Main.libraryMode.multipleLibs.getTabs().isEmpty() + && Main.libraryMode.multipleLibs.getSelectedLibrary().getSmartController().isFree(false)) + Main.libraryMode.multipleLibs.getSelectedLibrary().getSmartController().loadService.startService(false, true); + }); + + } catch (IOException | DeserializationException e) { + e.printStackTrace(); + // logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ + return false; + } + + return true; + } + + /** + * Stores the informations about the opened libraries , in the order they are opened + * + * @param observableList + * @param updateOpenedLibraries + * + * @return True if succedeed or False if not + */ + public boolean updateLibrariesInformation(ObservableList observableList, boolean updateOpenedLibraries) { + String jsonFilePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + localDBManager.getUserName() + File.separator + "settings.json"; + + if (!new File(jsonFilePath).exists()) + return false; + + //Update the JSON File on an external Thread + jSONUpdateExecutor.execute(() -> { + try (FileReader fileReader = new FileReader(jsonFilePath)) { + Object obj = Jsoner.deserialize(fileReader); + + //JSON Array [ROOT] + JsonObject json = (JsonObject) obj; + + //Last selected library Array + JsonObject lastSelectedLibrary = (JsonObject) ((JsonObject) json.get("librariesSystem")).get("lastSelectedLibrary"); + + if (observableList.isEmpty()) + lastSelectedLibrary.clear(); + else + observableList.forEach(tab -> { + if (tab.isSelected()) + lastSelectedLibrary.put("name", tab.getTooltip().getText()); + }); + + //Update the opened libraries? + if (updateOpenedLibraries) { + + //Opened Libraries Array + JsonArray openedLibraries = (JsonArray) ((JsonObject) json.get("librariesSystem")).get("openedLibraries"); + openedLibraries.clear(); + + //Add the Libraries to the Libraries Array + //System.out.println() + observableList.forEach(tab -> { + + //Add it to opened libraries + JsonObject object = new JsonObject(); + object.put("name", tab.getTooltip().getText()); + openedLibraries.add(object); + + //System.out.println(tab.getTooltip().getText()) + }); + + } + + //Write to File + try (FileWriter file = new FileWriter(jsonFilePath)) { + file.write(Jsoner.prettyPrint(json.toJson())); + file.flush(); + } catch (IOException e) { + e.printStackTrace(); + //logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ + //return false + } + + } catch (IOException | DeserializationException e) { + e.printStackTrace(); + // logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ + // return false + } finally { + if (localDBManager.showNotifications) + ActionTool.showNotification("JSON Updated", "JSON File Updated...", Duration.millis(150), NotificationType.INFORMATION); + } + }); + + //Returns always true needs to be fixed!!! + return true; + } + +} diff --git a/src/database/LocalDBManager.java b/src/database/LocalDBManager.java deleted file mode 100644 index 83c76276..00000000 --- a/src/database/LocalDBManager.java +++ /dev/null @@ -1,632 +0,0 @@ -/* - * - */ -package database; - -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Level; - -import org.json.simple.DeserializationException; -import org.json.simple.JsonArray; -import org.json.simple.JsonObject; -import org.json.simple.Jsoner; - -import application.Main; -import javafx.animation.PauseTransition; -import javafx.application.Platform; -import javafx.collections.ObservableList; -import javafx.concurrent.Service; -import javafx.concurrent.Task; -import javafx.scene.control.Tab; -import javafx.util.Duration; -import librarysystema.Library; -import smartcontroller.Operation; -import smartcontroller.SmartController; -import tools.ActionTool; -import tools.InfoTool; -import tools.NotificationType; - -/** - * This class is managing the database of the application. - * - * @author SuperGoliath - */ -public class LocalDBManager { - - /** The connection 1. */ - public Connection connection1; - - /** The data loader. */ - // Important Tasks - private DataLoader dataLoader = new DataLoader(); - - /** The database file. */ - // -Constructor- - private String dbFileAbsolutePath; - - /** The images folder relative path */ - private String imagesFolderRelativePath; - - /** The images folder absolute path */ - public String imagesFolderAbsolutePath; - - /** The name of the logged in user */ - public String userName; - - /** This executor does the commit job. */ - private static final ExecutorService commitExecutor = Executors.newSingleThreadExecutor(); - /** This executor does the commit job. */ - private static final ExecutorService jSONUpdateExecutor = Executors.newSingleThreadExecutor(); - - /** If true -> The database notifications are shown */ - private final boolean showNotifications = false; - - /** The runnable of the commit executor. */ - private Runnable commitRunnable = () -> { - try { - connection1.commit(); - } catch (SQLException ex) { - Main.logger.log(Level.WARNING, ex.getMessage(), ex); - } finally { - if (showNotifications) - ActionTool.showNotification("Commited", "Changes saved successfully", Duration.millis(150), NotificationType.INFORMATION); - } - - }; - - /** The runnable of the commit executor. */ - private Runnable vacuumRunnable = () -> { - try { - // close + open connection - connection1.commit(); - manageConnection(Operation.CLOSE); - manageConnection(Operation.OPEN); - - // vacuum - connection1.createStatement().executeUpdate("VACUUM"); - - // close connection - manageConnection(Operation.CLOSE); - - // exit - System.exit(0); - } catch (SQLException ex) { - Main.logger.log(Level.WARNING, ex.getMessage(), ex); - System.exit(-1); - } finally { - System.exit(0); - } - - }; - - //----------------------------------------------------------- - - /** - * Constructor. - * - * @param userName - * the user name - */ - public LocalDBManager(String userName) { - - try { - - // !!! Not needed in Java8 !!!! - // load the sqlite-JDBC driver using the current class loader - // Class.forName("org.sqlite.JDBC") - - // the userName - this.userName = userName; - - // user folder - File userFolder = new File(InfoTool.getAbsoluteDatabasePathWithSeparator() + userName); - if (!userFolder.exists()) - userFolder.mkdir(); - - //--images folder - imagesFolderRelativePath = InfoTool.getDatabaseFolderNameWithSeparator() + userName + File.separator + "Images"; - imagesFolderAbsolutePath = InfoTool.getAbsoluteDatabaseParentFolderPathWithSeparator() + imagesFolderRelativePath; - //-- - File imagesFolder = new File(imagesFolderAbsolutePath); - if (!imagesFolder.exists()) - imagesFolder.mkdir(); - - // database file(.db) - dbFileAbsolutePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + userName + File.separator + "dbFile.db"; - boolean data1Exist = new File(dbFileAbsolutePath).exists(); - - // connection1 - connection1 = DriverManager.getConnection("jdbc:sqlite:" + dbFileAbsolutePath); - connection1.setAutoCommit(false); - - if (!data1Exist) - recreateDataBase(); - - recreateJSonDataBase(); - - } catch (SQLException ex) { - Main.logger.log(Level.SEVERE, "", ex); - } - } - - /** - * Open or close the connection. - * - * @param action - * the action - */ - public void manageConnection(Operation action) { - try { - // OPEN - if (action == Operation.OPEN && connection1.isClosed()) - connection1 = DriverManager.getConnection("jdbc:sqlite:" + dbFileAbsolutePath); - // CLOSE - else if (action == Operation.CLOSE && !connection1.isClosed()) - connection1.close(); - } catch (SQLException ex) { - Main.logger.log(Level.WARNING, "", ex); - } - } - - /** - * Using this methods to control commits across the application so not to have unexpected lags. - */ - public void commit() { - commitExecutor.execute(commitRunnable); - } - - /** - * Using this methods to control commit + vacuum across the application so not to have unexpected lags. - * - */ - public void commitAndVacuum() { - commitExecutor.execute(vacuumRunnable); - } - - /** - * Stops the executorService. - */ - public void shutdownCommitExecutor() { - commitExecutor.shutdown(); - } - - /** - * Checks if this table exists in dataBase. - * - * @param tableName - * the table name - * @return true, if successful - */ - public static boolean tableExists(String tableName) { - // SQLite table names are case insensitive, but comparison is case - // sensitive by default. To make this work properly in all cases you - // need to add COLLATE NOCASE - try (ResultSet r = Main.dbManager.connection1.createStatement() - .executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='" + tableName + "' COLLATE NOCASE ")) { - int total = r.getInt(1); - return total == 0 ? false : true; - } catch (SQLException ex) { - Main.logger.log(Level.INFO, "", ex); - } - - return false; - } - - /** - * Recreates the database if it doesn't exist. - */ - public void recreateDataBase() { - - Main.logger.info("1-->Recreating the database.."); - - try (Statement statement = connection1.createStatement()) { - - // ----------Libraries Table ----------------// - statement.executeUpdate("CREATE TABLE LIBRARIES(NAME TEXT PRIMARY KEY NOT NULL," + "TABLENAME TEXT NOT NULL," - + "STARS DOUBLE NOT NULL," + "DATECREATED TEXT NOT NULL," + "TIMECREATED TEXT NOT NULL," - + "DESCRIPTION TEXT NOT NULL," + "SAVEMODE INT NOT NULL," + "POSITION INT NOT NULL," - + "LIBRARYIMAGE TEXT," + "OPENED BOOLEAN NOT NULL )"); - - // -----------Radio Stations Table ------------// - statement.executeUpdate("CREATE TABLE '" + InfoTool.RADIO_STATIONS_DATABASE_TABLE_NAME + "'(NAME TEXT PRIMARY KEY NOT NULL," - + "STREAMURL TEXT NOT NULL," + "TAGS TEXT NOT NULL," + "DESCRIPTION TEXT," + "STARS DOUBLE NOT NULL)"); - - // ----------XPlayers PlayLists Tables ----------// - for (int i = 0; i < 3; i++) - createXPlayListTable(statement, i); - - commit(); - } catch (SQLException ex) { - Main.logger.log(Level.SEVERE, "", ex); - } - } - - /** - * Create a database table for the specific XPlayer. - * - * @param statement - * the statement - * @param key - * the key - * @throws SQLException - * the SQL exception - */ - private void createXPlayListTable(Statement statement, int key) throws SQLException { - statement.executeUpdate("CREATE TABLE XPPL" + key + "(PATH TEXT PRIMARY KEY NOT NULL ," + "STARS DOUBLE NOT NULL," - + "TIMESPLAYED INT NOT NULL," + "DATE TEXT NOT NULL," + "HOUR TEXT NOT NULL)"); - } - - /** - * This method loads the application database. - */ - public void loadApplicationDataBase() { - Main.updateScreen.setVisible(true); - Main.updateScreen.getProgressBar().progressProperty().bind(dataLoader.progressProperty()); - dataLoader.restart(); - } - - /** - * DataLoader. - * - * @author SuperGoliath - */ - public class DataLoader extends Service { - - /** The total. */ - int total; - - /** - * Constructor. - */ - public DataLoader() { - - // -------------------if succeeded - setOnSucceeded(s -> { - - //----------------Do the animation with rectangles--------------------- - Main.updateScreen.closeUpdateScreen(); - - //----------------Finall Settings--------------------- - // update library viewer - Main.libraryMode.teamViewer.getViewer().update(); - //Main.libraryMode.libraryViewer.goOnSelectionMode(false) - - // set libraries tree expanded - //Main.treeManager.librariesTree.setExpanded(true) - - //---------------Set the update Screen invisible--------------------- - PauseTransition pause1 = new PauseTransition(Duration.seconds(1)); - pause1.setOnFinished(f -> { - Main.updateScreen.setVisible(false); - Main.updateScreen.getProgressBar().progressProperty().unbind(); - }); - pause1.playFromStart(); - - }); - - // ---------------------if failed - setOnFailed(fail -> { - Main.updateScreen.getProgressBar().progressProperty().unbind(); - ActionTool.showNotification("Fatal Error!", "DataLoader failed during loading dataBase!!Application will exit...", - Duration.millis(1500), NotificationType.ERROR); - System.exit(0); - }); - } - - //-------------------Needs modification cause it violates JavaFX THREAD!!!!!!!!!!!! - @Override - protected Task createTask() { - return new Task() { - @Override - protected Void call() throws Exception { - int counter; - int total = 1; - updateProgress(0, total); - - // -------------------------- Load all the libraries - try (ResultSet resultSet = connection1.createStatement().executeQuery("SELECT* FROM LIBRARIES;"); - ResultSet dbCounter = connection1.createStatement().executeQuery("SELECT COUNT(*) FROM LIBRARIES;");) { - - total += dbCounter.getInt(1); - Main.logger.info("Loading Libraries...."); - - // Refresh the text - Platform.runLater(() -> Main.updateScreen.getLabel().setText("Loading Libraries...")); - updateProgress(1, 2); - - //Kepp a List of all Libraries - final List libraries = new ArrayList<>(total); - - // Load all the libraries - while (resultSet.next()) { - libraries.add(new Library(resultSet.getString("NAME"), resultSet.getString("TABLENAME"), resultSet.getDouble("STARS"), - resultSet.getString("DATECREATED"), resultSet.getString("TIMECREATED"), resultSet.getString("DESCRIPTION"), - resultSet.getInt("SAVEMODE"), resultSet.getInt("POSITION"), resultSet.getString("LIBRARYIMAGE"), - resultSet.getBoolean("OPENED"))); - - updateProgress(resultSet.getRow() - 1, total); - } - - //Add all the Libraries to the Library Viewer - Platform.runLater(() -> Main.libraryMode.teamViewer.getViewer().addMultipleLibraries(libraries)); - - //Load the Opened Libraries - Platform.runLater(() -> Main.updateScreen.getLabel().setText("Loading Opened Libraries...")); - loadOpenedLibraries(); - //Calculate opened libraries - Platform.runLater(() -> Main.libraryMode.calculateOpenedLibraries()); - - //Load PlayerMediaList - Platform.runLater(() -> Main.updateScreen.getLabel().setText("Loading previous data...")); - Main.playedSongs.uploadFromDataBase(); - - //--FINISH - updateProgress(total, total); - - } catch (Exception ex) { - Main.logger.log(Level.SEVERE, "", ex); - } - - return null; - } - }; - } - - } - - //-------------------------------------JSON---------------------------------------- - - /** - * Loads the Libraries information into the application - * - * @return True if succedeed or False if not - */ - public boolean loadOpenedLibraries() { - - String jsonFilePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + userName + File.separator + "settings.json"; - - //Check if the file exists - if (!new File(jsonFilePath).exists()) - return false; - - //Read the JSON File - try (FileReader fileReader = new FileReader(jsonFilePath)) { - - //JSON Array [ROOT] - JsonObject json = (JsonObject) Jsoner.deserialize(fileReader); - - //Opened Libraries Array - JsonArray openedLibraries = (JsonArray) ((JsonObject) json.get("librariesSystem")).get("openedLibraries"); - - //For each Library - openedLibraries.forEach(libraryObject -> Platform.runLater(() -> - - //Get the Library and Open it! - Main.libraryMode.getLibraryWithName(((JsonObject) libraryObject).get("name").toString()).libraryOpenClose(true, true) - - //Print its name - //System.out.println(((JsonObject) libraryObject).get("name")) - )); - - //Last selected library Array - JsonObject lastSelectedLibrary = (JsonObject) ((JsonObject) json.get("librariesSystem")).get("lastSelectedLibrary"); - - //Add the Listener to multipleLibs - Platform.runLater(() -> { - Main.libraryMode.multipleLibs.getTabPane().getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> { - - // Give a refresh to the newly selected ,!! ONLY IF IT HAS NO ITEMS !! - if (!Main.libraryMode.multipleLibs.getTabPane().getTabs().isEmpty() && ((SmartController) newTab.getContent()).isFree(false) - && ((SmartController) newTab.getContent()).getItemsObservableList().isEmpty()) { - - ((SmartController) newTab.getContent()).loadService.startService(false, true); - - Main.dbManager.updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabPane().getTabs(), false); - - } - - // //Do an animation - // if (oldTab != null && newTab != null) { - // Node oldContent = oldTab.getContent(); //tabContent.get(oldTab) - // Node newContent = newTab.getContent(); //tabContent.get(newTab) - // - // newTab.setContent(oldContent); - // ScaleTransition fadeOut = new ScaleTransition(Duration.millis(50), oldContent); - // fadeOut.setFromX(1); - // fadeOut.setFromY(1); - // fadeOut.setToX(0); - // fadeOut.setToY(0); - // - // ScaleTransition fadeIn = new ScaleTransition(Duration.millis(50), newContent); - // fadeIn.setFromX(0); - // fadeIn.setFromY(0); - // fadeIn.setToX(1); - // fadeIn.setToY(1); - // - // fadeOut.setOnFinished(event -> newTab.setContent(newContent)); - // - // SequentialTransition crossFade = new SequentialTransition(fadeOut, fadeIn); - // crossFade.play(); - // } - }); - }); - - //If not empty... - if (!lastSelectedLibrary.isEmpty()) { - Platform.runLater(() -> { - - //Select the correct library inside the TabPane - Main.libraryMode.multipleLibs.getTabPane().getSelectionModel() - .select(Main.libraryMode.multipleLibs.getTab(lastSelectedLibrary.get("name").toString())); - - //This will change in future update when user can change the default position of Libraries - Main.libraryMode.teamViewer.getViewer().setCenterIndex(Main.libraryMode.multipleLibs.getSelectedLibrary().getPosition()); - - //System.out.println("Entered !lastSelectedLibrary.isEmpty()") - }); - } - - //Do an Update on the selected Library SmartController - Platform.runLater(() -> { - //Check if empty and if not update the selected library - if (!Main.libraryMode.multipleLibs.getTabs().isEmpty() - && Main.libraryMode.multipleLibs.getSelectedLibrary().getSmartController().isFree(false)) - Main.libraryMode.multipleLibs.getSelectedLibrary().getSmartController().loadService.startService(false, true); - }); - - } catch (IOException | DeserializationException e) { - e.printStackTrace(); - // logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ - return false; - } - - return true; - } - - /** - * Stores the informations about the opened libraries , in the order they are opened - * - * @param observableList - * @param updateOpenedLibraries - * - * @return True if succedeed or False if not - */ - public boolean updateLibrariesInformation(ObservableList observableList, boolean updateOpenedLibraries) { - String jsonFilePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + userName + File.separator + "settings.json"; - - if (!new File(jsonFilePath).exists()) - return false; - - //Update the JSON File on an external Thread - jSONUpdateExecutor.execute(() -> { - try (FileReader fileReader = new FileReader(jsonFilePath)) { - Object obj = Jsoner.deserialize(fileReader); - - //JSON Array [ROOT] - JsonObject json = (JsonObject) obj; - - //Last selected library Array - JsonObject lastSelectedLibrary = (JsonObject) ((JsonObject) json.get("librariesSystem")).get("lastSelectedLibrary"); - - if (observableList.isEmpty()) - lastSelectedLibrary.clear(); - else - observableList.forEach(tab -> { - if (tab.isSelected()) - lastSelectedLibrary.put("name", tab.getTooltip().getText()); - }); - - //Update the opened libraries? - if (updateOpenedLibraries) { - - //Opened Libraries Array - JsonArray openedLibraries = (JsonArray) ((JsonObject) json.get("librariesSystem")).get("openedLibraries"); - openedLibraries.clear(); - - //Add the Libraries to the Libraries Array - //System.out.println() - observableList.forEach(tab -> { - - //Add it to opened libraries - JsonObject object = new JsonObject(); - object.put("name", tab.getTooltip().getText()); - openedLibraries.add(object); - - //System.out.println(tab.getTooltip().getText()) - }); - - } - - //Write to File - try (FileWriter file = new FileWriter(jsonFilePath)) { - file.write(Jsoner.prettyPrint(json.toJson())); - file.flush(); - } catch (IOException e) { - e.printStackTrace(); - //logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ - //return false - } - - } catch (IOException | DeserializationException e) { - e.printStackTrace(); - // logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ - // return false - } finally { - if (showNotifications) - ActionTool.showNotification("JSON Updated", "JSON File Updated...", Duration.millis(150), NotificationType.INFORMATION); - } - }); - - //Returns always true needs to be fixed!!! - return true; - } - - /** - * Creates the JSONDatabase if it doesn't exitst - * - * @return True if succedeed or False if not - */ - public boolean recreateJSonDataBase() { - String jsonFilePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + userName + File.separator + "settings.json"; - - //File already exists? - if (new File(jsonFilePath).exists()) - return true; - - //JSON Array [ROOT] - JsonObject json = new JsonObject(); - - //-----------Libraries Array------------------ - JsonObject librariesSystem = new JsonObject(); - - //Latest Library that was selected + Opened - JsonObject lastSelectedLibrary = new JsonObject(); - - //Libraries that where opened - JsonArray openedLibraries = new JsonArray(); - // for (int i = 0; i < 2; i++) { - // JsonObject object = new JsonObject(); - // object.put("name", "library->" + i); - // openedLibraries.add(object); - // } - - librariesSystem.put("openedLibraries", openedLibraries); - librariesSystem.put("lastSelectedLibrary", lastSelectedLibrary); - - //--------------XPlayers Array-------------- - - JsonArray xPlayers = new JsonArray(); - for (int i = 0; i < 3; i++) { - JsonObject object = new JsonObject(); - object.put("name", "xPlayer" + i); - xPlayers.add(object); - } - - json.put("librariesSystem", librariesSystem); - json.put("xPlayers", xPlayers); - - //Write to File - try (FileWriter file = new FileWriter(jsonFilePath)) { - file.write(Jsoner.prettyPrint(json.toJson())); - file.flush(); - } catch (IOException e) { - e.printStackTrace(); - //logger.severe("SettingsWindowController - exception: " + e); //$NON-NLS-1$ - return false; - } - - return true; - } -} diff --git a/src/database/PropertiesDb.java b/src/database/PropertiesDb.java new file mode 100644 index 00000000..b44b57d6 --- /dev/null +++ b/src/database/PropertiesDb.java @@ -0,0 +1,120 @@ +/** + * + */ +package database; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javafx.util.Duration; +import tools.ActionTool; +import tools.InfoTool; +import tools.NotificationType; + +/** + * This class is saving all the XR3Player Settings to a property file + * + * @author GOXR3PLUS + * + */ +public class PropertiesDb { + + private final Properties properties; + + /** This executor does the commit job. */ + private static final ExecutorService updateExecutorService = Executors.newSingleThreadExecutor(); + + DbManager localDbManager; + + /** + * Constructor + * + * @param localDbManager + */ + public PropertiesDb(DbManager localDbManager) { + this.localDbManager = localDbManager; + properties = new Properties(); + + } + + /** + * Updates or Creates the given key + * + * @param key + * @param value + */ + public void updateProperty(String key, String value) { + String propertiesAbsolutePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + "config.properties"; + + //Check if exists [ Create if Not ] + if (!new File(propertiesAbsolutePath).exists()) + try { + new File(propertiesAbsolutePath).createNewFile(); + } catch (IOException ex) { + ex.printStackTrace(); + } + + //Submit it to the executors Service + updateExecutorService.submit(() -> { + try (InputStream inStream = new FileInputStream(propertiesAbsolutePath); + OutputStream outStream = new FileOutputStream(propertiesAbsolutePath)) { + + //load properties + properties.load(inStream); + + // set the properties value + properties.setProperty(key, value); + + // save properties + properties.store(outStream, null); + + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + // if (showNotifications) + ActionTool.showNotification("Properties Updated", "Changes saved successfully", Duration.millis(550), NotificationType.INFORMATION); + } + }); + } + + /** + * Loads the Properties + */ + public void loadProperties() { + String propertiesAbsolutePath = InfoTool.getAbsoluteDatabasePathWithSeparator() + "config.properties"; + + //Check if exists [ Create if Not ] + if (!new File(propertiesAbsolutePath).exists()) + try { + new File(propertiesAbsolutePath).createNewFile(); + } catch (IOException ex) { + ex.printStackTrace(); + } + + //Load the properties file + try (InputStream inStream = new FileInputStream(propertiesAbsolutePath)) { + + //load properties + properties.load(inStream); + + } catch (IOException ex) { + ex.printStackTrace(); + } + + } + + /** + * @return the properties + */ + public Properties getProperties() { + return properties; + } + +} diff --git a/src/librarysystema/Library.java b/src/librarysystema/Library.java index 4dafa38e..50fe010d 100644 --- a/src/librarysystema/Library.java +++ b/src/librarysystema/Library.java @@ -232,7 +232,7 @@ public void invalidated(Observable observable) { //Update the JSONFile if (isOpened()) - Main.dbManager.updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabs(), true); + Main.dbManager.getKeyValueDb().updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabs(), true); } else { // duplicate resetTheName(); ActionTool.showNotification("Dublicate Name", "Name->" + newName + " is already used from another Library...", @@ -889,7 +889,7 @@ public void deleteLibrary(Node owner) { //Update the JSONFile if (isOpened()) - Main.dbManager.updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabs(), true); + Main.dbManager.getKeyValueDb().updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabs(), true); } catch (SQLException sql) { logger.log(Level.WARNING, "\n", sql); @@ -922,7 +922,7 @@ else if (!open && isOpened() && controller.isFree(true)) { } //Update the JSONFile - Main.dbManager.updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabs(), true); + Main.dbManager.getKeyValueDb().updateLibrariesInformation(Main.libraryMode.multipleLibs.getTabs(), true); //Calculate opened libraries Main.libraryMode.calculateOpenedLibraries(); diff --git a/src/librarysystema/LibraryMode.java b/src/librarysystema/LibraryMode.java index f9793ccd..b963c18a 100644 --- a/src/librarysystema/LibraryMode.java +++ b/src/librarysystema/LibraryMode.java @@ -10,7 +10,6 @@ import application.Main; import application.settings.window.ApplicationSettingsController.SettingsTab; -import database.LocalDBManager; import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.binding.Bindings; @@ -164,7 +163,7 @@ public void invalidated(Observable observable) { // Until the randomName doesn't already exists do { tableName = ActionTool.returnRandomTableName(); - validName = !LocalDBManager.tableExists(tableName); + validName = !Main.dbManager.doesTableExist(tableName); } while (!validName); final String dataBaseTableName = tableName; //add it to a final variable diff --git a/src/librarysystema/MultipleLibraries.java b/src/librarysystema/MultipleLibraries.java index 085ce171..c399dcf3 100644 --- a/src/librarysystema/MultipleLibraries.java +++ b/src/librarysystema/MultipleLibraries.java @@ -33,7 +33,7 @@ /** * Mechanism of showing the opened libraries each opened library is represented by a Tab. * - * @author SuperGoliath + * @author GOXR3PLUS STUDIO */ public class MultipleLibraries extends StackPane { diff --git a/src/services/FilesFilterService.java b/src/services/FilesFilterService.java index 0d0b12e8..cedfa60e 100644 --- a/src/services/FilesFilterService.java +++ b/src/services/FilesFilterService.java @@ -6,21 +6,26 @@ import static application.Main.libraryMode; import java.io.File; +import java.io.IOException; import java.nio.file.Paths; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; +import org.apache.commons.io.FileUtils; + import application.Main; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.util.Duration; +import media.Media; import smartcontroller.SmartController; import streamplayer.ThreadFactoryWithNamePrefix; import tools.ActionTool; import tools.InfoTool; +import tools.JavaFXTools; import tools.NotificationType; /** @@ -120,7 +125,12 @@ private void filterController(SmartController controller) { //System.out.println("Checking elements.....") // controller is free && threadIsRunning? - if (controllerIsFree[0] && threadIsRunning) + if (controllerIsFree[0] && threadIsRunning) { + + //Check the settings + int mode = JavaFXTools.getIndexOfSelectedToggle(Main.settingsWindow.getPlayListsSettingsController().getPlayedFilesDetectionGroup()); + + //For each media File of the Controller controller.getItemsObservableList().stream().forEach(media -> { if (!threadIsRunning) return; @@ -128,28 +138,42 @@ private void filterController(SmartController controller) { // File exists? Platform.runLater(() -> media.fileExistsProperty().set(Paths.get(media.getFilePath()).toFile().exists())); - // Item has been played? - if (Main.settingsWindow.getPlayListsSettingsController().getPlayedFilesDetectionGroup().getToggles().get(0).isSelected()) { - // System.out.println("Entered 1") - //Check bases on File Absolute Path - if (Main.playedSongs.containsFile(media.getFilePath())) - Platform.runLater(() -> media.setMediaPlayed(true)); - else - Platform.runLater(() -> media.setMediaPlayed(false)); - } else { - // System.out.println("Entered 2") - String mediaName = InfoTool.getFileName(media.getFilePath()); + if (mode == 0) { // Check based on File Content [ The content must be absolutely the same ] + + //Go + File mediaPath = new File(media.getFilePath()); + setMediaPlayed(media, Main.playedSongs.getSet().stream().anyMatch(playedFileAbsolutePath -> { + try { + return FileUtils.contentEquals(new File(playedFileAbsolutePath), mediaPath); + } catch (IOException ex) { + ex.printStackTrace(); + } + return false; + })); + } else if (mode == 1) { //Check based on FileName and FileLength -> both must be equal + + //Go + String mediaName = InfoTool.getFileName(media.getFilePath()).toLowerCase(); + // String mediaPath = media.getFilePath().toLowerCase() long mediaFileLength = new File(media.getFilePath()).length(); - //Check based on FileName and FileLength -> both must be equal - if (Main.playedSongs.getSet().stream().filter(file -> file.contains(mediaName)) - .anyMatch(file -> new File(file).length() == mediaFileLength)) - Platform.runLater(() -> media.setMediaPlayed(true)); - else - Platform.runLater(() -> media.setMediaPlayed(false)); + setMediaPlayed(media, + Main.playedSongs.getSet().stream() + .filter(playedFileAbsolutePath -> playedFileAbsolutePath.toLowerCase().contains(mediaName)) // || mediaPath.toLowerCase().contains(InfoTool.getFileName(playedFileAbsolutePath)) + .anyMatch(playedFile -> new File(playedFile).length() == mediaFileLength)); } }); + } } + /** + * Set's the Media Played or Not [ Using JavaFX Thread ] + * + * @param played + */ + private static void setMediaPlayed(Media m, boolean played) { + Platform.runLater(() -> m.setMediaPlayed(played)); + } + } diff --git a/src/smartcontroller/MediaContextMenu.java b/src/smartcontroller/MediaContextMenu.java index 2783c577..49f99213 100644 --- a/src/smartcontroller/MediaContextMenu.java +++ b/src/smartcontroller/MediaContextMenu.java @@ -123,8 +123,11 @@ public class MediaContextMenu extends ContextMenu { MenuItem lyricFinderOrg = new MenuItem("LyricFinder.org", InfoTool.getImageViewFromDocuments("Lyrics-24.png")); MenuItem lyricsCom = new MenuItem("Lyrics.com", InfoTool.getImageViewFromDocuments("Lyrics-24.png")); + /** Search by country */ + Menu searchByCountry = new Menu("Search by country[Coming...]", InfoTool.getImageViewFromDocuments("flag 24.png")); + /** Show Info (I) */ - MenuItem showInfo = new MenuItem("Show Info[Comming..]", InfoTool.getImageViewFromDocuments("tag.png")); + MenuItem showInfo = new MenuItem("Show Info[Coming..]", InfoTool.getImageViewFromDocuments("tag.png")); //-------------------------------- @@ -158,8 +161,9 @@ public class MediaContextMenu extends ContextMenu { public MediaContextMenu() { //Add all the items + searchByCountry.setDisable(true); showInfo.setDisable(true); - getItems().addAll(new TitleMenuItem("Basic"), startPlayer, stopPlayer, new TitleMenuItem("Search"), searchOnWeb, findLyrics, + getItems().addAll(new TitleMenuItem("Basic"), startPlayer, stopPlayer, new TitleMenuItem("Search"), searchOnWeb, findLyrics, searchByCountry, new TitleMenuItem("More"), stars, showFile, showInfo, new TitleMenuItem("File Edit"), rename, simpleDelete, storageDelete, new TitleMenuItem("Organize"), copy); @@ -219,25 +223,23 @@ public MediaContextMenu() { * the e * @param controller1 * the controller - * @param node + * @param node */ public void showContextMenu(Media media1, Genre genre, double x, double y, SmartController controller1, Node node) { // Don't waste resources - if (previousGenre != genre) { - if (media1.getGenre() == Genre.LIBRARYMEDIA) { + if (previousGenre != genre) + if (media1.getGenre() == Genre.LIBRARYMEDIA) getItems().forEach(item -> item.setVisible(true)); - } else if (media1.getGenre() == Genre.SEARCHWINDOW) { + else if (media1.getGenre() == Genre.SEARCHWINDOW) simpleDelete.setVisible(false); - } - } //Determine the image for (int i = 0; i <= 2; i++) { - boolean b = Main.xPlayersList.getXPlayer(i).isOpened() || Main.xPlayersList.getXPlayer(i).isPausedOrPlaying() + boolean playerEnergized = Main.xPlayersList.getXPlayer(i).isOpened() || Main.xPlayersList.getXPlayer(i).isPausedOrPlaying() || Main.xPlayersList.getXPlayer(i).isSeeking(); - ((ImageView) startPlayer.getItems().get(i).getGraphic()).setImage(b ? soundWave : null); - ((ImageView) stopPlayer.getItems().get(i).getGraphic()).setImage(b ? soundWave : null); + ((ImageView) startPlayer.getItems().get(i).getGraphic()).setImage(!playerEnergized ? null : soundWave); + ((ImageView) stopPlayer.getItems().get(i).getGraphic()).setImage(!playerEnergized ? null : soundWave); } this.node = node; @@ -245,8 +247,7 @@ public void showContextMenu(Media media1, Genre genre, double x, double y, Smart this.controller = controller1; // Show it - show(genre != Genre.SEARCHWINDOW ? Main.window : Main.searchWindow.getWindow(), x - 5 - super.getWidth() + super.getWidth() * 14 / 100, - y - 1); + show(genre != Genre.SEARCHWINDOW ? Main.window : Main.searchWindow.getWindow(), x - super.getWidth(), y - 1); previousGenre = genre; //Y axis diff --git a/src/smartcontroller/PlayedMediaList.java b/src/smartcontroller/PlayedMediaList.java index 5d11a061..da1d834b 100644 --- a/src/smartcontroller/PlayedMediaList.java +++ b/src/smartcontroller/PlayedMediaList.java @@ -11,7 +11,6 @@ import java.util.logging.Level; import application.Main; -import database.LocalDBManager; import tools.InfoTool; /** @@ -39,7 +38,7 @@ private void prepareMediaListTable() { try { //Check if it does already exists - if (!LocalDBManager.tableExists(dataBaseTableName)) + if (!Main.dbManager.doesTableExist(dataBaseTableName)) Main.dbManager.connection1.createStatement() .executeUpdate("CREATE TABLE '" + dataBaseTableName + "'" + "(PATH TEXT PRIMARY KEY NOT NULL ," diff --git a/src/smartcontroller/SmartController.java b/src/smartcontroller/SmartController.java index dba39bb5..bd492a0d 100644 --- a/src/smartcontroller/SmartController.java +++ b/src/smartcontroller/SmartController.java @@ -1548,6 +1548,7 @@ public void done() { //Fix the vertical scroll bar position if (searchService.isActive() || genre == Genre.SEARCHWINDOW) { + System.out.println("Search is active"); getVerticalScrollBar().setValue(getVerticalScrollValueWithSearch()); setVerticalScrollValueWithSearch(0.0); } else { diff --git a/src/smartcontroller/SmartControllerSearcher.java b/src/smartcontroller/SmartControllerSearcher.java index 92cc8588..92fd5563 100644 --- a/src/smartcontroller/SmartControllerSearcher.java +++ b/src/smartcontroller/SmartControllerSearcher.java @@ -71,7 +71,9 @@ public class SmartControllerSearcher extends HBox { public SmartControllerSearcher(SmartController control) { controller = control; - super.setAlignment(Pos.CENTER); + //Super + setAlignment(Pos.CENTER); + getChildren().add(searchField); getStyleClass().add("search-box"); // searchField @@ -80,6 +82,11 @@ public SmartControllerSearcher(SmartController control) { searchField.setMaxWidth(Integer.MAX_VALUE); searchField.setPromptText("Search....."); searchField.textProperty().addListener((observable, newValue, oldValue) -> { + + //Check if the controller is free + if (!controller.isFree(false)) + return; + if (searchField.getText().isEmpty()) { saveSettingBeforeSearch = true; @@ -90,17 +97,9 @@ public SmartControllerSearcher(SmartController control) { //continue controller.getNavigationHBox().setDisable(false); controller.loadService.startService(false, false); - //Main.advancedSearch.searchOnFlySelected() - - } else if (controller.isFree(false) && Main.settingsWindow.getPlayListsSettingsController().getInstantSearch().isSelected()) { - //Save the Settings before the first search - if (saveSettingBeforeSearch) { - service.pageBeforeSearch = controller.getCurrentPage().get(); - controller.setVerticalScrollValueWithoutSearch(controller.getVerticalScrollBar().getValue()); - - saveSettingBeforeSearch = false; - } + } else if (Main.settingsWindow.getPlayListsSettingsController().getInstantSearch().isSelected()) { + saveSettingsBeforeSearch(); service.search(); } }); @@ -111,19 +110,31 @@ public SmartControllerSearcher(SmartController control) { searchField.editableProperty().bind(service.runningProperty().not()); //searchField.disableProperty().bind(Main.advancedSearch.showingProperty()) searchField.setOnAction(ac -> { - if (controller.isFree(false)) + if (controller.isFree(false)) { + saveSettingsBeforeSearch(); service.search(); + } }); - // searchField.setOnMouseClicked(m -> { - // if (m.getButton() == MouseButton.SECONDARY) - // Main.advancedSearch.show(searchField, controller); - // }) + //Override the default context menu searchField.setContextMenu(new ContextMenu()); - getChildren().add(searchField); } + /** + * //Save the Settings before the first search -> [ ScrollBar position and current page of the SmartController ] + */ + private void saveSettingsBeforeSearch() { + + //lock it so no override happens during the search + if (!saveSettingBeforeSearch) + return; + + service.pageBeforeSearch = controller.getCurrentPage().get(); + controller.setVerticalScrollValueWithoutSearch(controller.getVerticalScrollBar().getValue()); + saveSettingBeforeSearch = false; + } + /** * Returns true if the Search service is currently activated(if reset button is still visible). * diff --git a/src/streamplayer/StreamPlayerEventLauncher.java b/src/streamplayer/StreamPlayerEventLauncher.java index 0aef2aa8..c7b1ea0a 100644 --- a/src/streamplayer/StreamPlayerEventLauncher.java +++ b/src/streamplayer/StreamPlayerEventLauncher.java @@ -78,7 +78,7 @@ public String call() throws Exception { .statusUpdated(new StreamPlayerEvent(source, playerState, encodedStreamPosition, description))); } - System.out.println("State Updated to: " + playerState); + System.out.println("Stream player Status -> " + playerState); return "OK"; } } diff --git a/src/tools/JavaFXTools.java b/src/tools/JavaFXTools.java new file mode 100644 index 00000000..0df4c06c --- /dev/null +++ b/src/tools/JavaFXTools.java @@ -0,0 +1,39 @@ +/** + * + */ +package tools; + +import javafx.scene.control.ToggleGroup; + +/** + * This class has some functions that are not there by default in JavaFX 8 + * + * @author GOXR3PLUS + * + */ +public class JavaFXTools { + + private JavaFXTools() { + } + + /** + * Returns the Index of the Selected Toggle inside the ToggleGroup (counting from 0) + * + * @param g + * @return The index of the Selected Toggle + */ + public static int getIndexOfSelectedToggle(ToggleGroup g) { + return g.getToggles().indexOf(g.getSelectedToggle()); + } + + /** + * Selects the Toggle in position Index inside the toggle group (counting from 0 ) + * + * @param g + * @param index + */ + public static void selectToggleOnIndex(ToggleGroup g, int index) { + g.selectToggle(g.getToggles().get(index)); + } + +} diff --git a/src/windows/RenameWindow.java b/src/windows/RenameWindow.java index 910a8bc3..2fa83d68 100644 --- a/src/windows/RenameWindow.java +++ b/src/windows/RenameWindow.java @@ -135,9 +135,9 @@ private void initialize() { //Check newValue if (newValue != null) { - // Allow until 150 characters - if (newValue.length() > 150) - inputField.setText(newValue.substring(0, 150)); + // Allow until 200 characters + if (newValue.length() > 200) + inputField.setText(newValue.substring(0, 200)); // Strict Mode for (String character : notAllow) diff --git a/src/windows/StarWindow.java b/src/windows/StarWindow.java index 0230494c..421d3d97 100644 --- a/src/windows/StarWindow.java +++ b/src/windows/StarWindow.java @@ -89,7 +89,6 @@ public StarWindow() { */ @FXML private void initialize() { - System.out.println("StarWindow Initialized...."); // Window window = new Stage(); diff --git a/src/xplayer/presenter/XPlayerController.java b/src/xplayer/presenter/XPlayerController.java index 1f403a05..10feb6b6 100644 --- a/src/xplayer/presenter/XPlayerController.java +++ b/src/xplayer/presenter/XPlayerController.java @@ -184,10 +184,13 @@ public class XPlayerController extends StackPane implements DJDiscListener, Stre // -------------------------ETC -------------------------- + /** + * + */ public XPlayerWindow xPlayerWindow; /** The x player settings controller. */ - public XPlayerSettingsController xPlayerSettingsController; + public XPlayerExtraSettings playerExtraSettings; /** The x player model. */ public XPlayerModel xPlayerModel; @@ -284,7 +287,7 @@ private void initialize() { radialMenu = new XPlayerRadialMenu(this); //xPlayList = new XPlayerPlaylist(25, this) visualizerWindow = new VisualizerWindowController(this); - xPlayerSettingsController = new XPlayerSettingsController(this); + playerExtraSettings = new XPlayerExtraSettings(this); // Styling //setStyle("-fx-background-image:url('/image/deckBackground.jpg'); -fx-background-size:stretch;") @@ -327,7 +330,7 @@ private void initialize() { //flipPane flipPane.setFlipTime(150); flipPane.getFront().getChildren().addAll(container); - flipPane.getBack().getChildren().addAll(xPlayerSettingsController); + flipPane.getBack().getChildren().addAll(playerExtraSettings); settingsToggle.selectedProperty().addListener((observable, oldValue, newValue) -> { if (newValue) // true? @@ -395,7 +398,7 @@ public void dragDrop(DragEvent dragDrop, int number) { absolutePath = file.getAbsolutePath(); if (file.isFile() && InfoTool.isAudioSupported(absolutePath)) { // Ask Question? - if (xPlayer.isPausedOrPlaying() && xPlayerSettingsController.askSecurityQuestion.isSelected()) { + if (xPlayer.isPausedOrPlaying() && Main.settingsWindow.getxPlayersSettingsController().getAskSecurityQuestion().isSelected()) { if (ActionTool.doQuestion("A song is already playing on this deck.\n Are you sure you want to replace it?", visualizerWindow.getStage().isShowing() && !xPlayerWindow.getWindow().isShowing() ? visualizerWindow : xPlayerStackPane)) playSong(absolutePath); @@ -587,7 +590,7 @@ public void makeTheVisualizer(Side side) { // Visualizer visualizer = new XPlayerVisualizer(this); - visualizer.setShowFPS(xPlayerSettingsController.showFPS.selectedProperty().get()); + visualizer.setShowFPS(Main.settingsWindow.getxPlayersSettingsController().getShowFPS().selectedProperty().get()); // Select the correct toggle visualizerWindow.getVisualizerTypeGroup() @@ -744,7 +747,7 @@ private void buildSettings(Side side) { // Equalizer equalizer = new XPlayerEqualizer(this); - xPlayerSettingsController.equalizerTab.setContent(new ScrollPane(equalizer)); + playerExtraSettings.getEqualizerTab().setContent(new ScrollPane(equalizer)); // PlayList //xPlayerSettingsController.playListTab.setContent(xPlayList); @@ -1101,11 +1104,13 @@ public void cancelled() { /** * When the audio starts , fast configure it's settings + * + * @param ignoreStartImmediately */ public void configureMediaSettings(boolean ignoreStartImmediately) { // Start immediately? - if (!ignoreStartImmediately && !xPlayerSettingsController.startImmediately.isSelected()) + if (!ignoreStartImmediately && !Main.settingsWindow.getxPlayersSettingsController().getStartImmediately().isSelected()) pause(); else { play(); diff --git a/src/xplayer/presenter/XPlayerExtraSettings.java b/src/xplayer/presenter/XPlayerExtraSettings.java new file mode 100644 index 00000000..b99c17ed --- /dev/null +++ b/src/xplayer/presenter/XPlayerExtraSettings.java @@ -0,0 +1,89 @@ +/** + * + */ +package xplayer.presenter; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.control.Tab; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.BorderPane; +import tools.InfoTool; + +/** + * The Class XPlayerSettingsController. + * + * @author GOXR3PLUS + */ +public class XPlayerExtraSettings extends BorderPane { + + // ------------------------ + + @FXML + private Tab equalizerTab; + + @FXML + private Tab historyTab; + + @FXML + private Tab playListTab; + + // ------------------------ + + /** The x player UI. */ + XPlayerController xPlayerUI; + + /** + * Constructor. + * + * @param xPlayerUI + * the x player UI + */ + public XPlayerExtraSettings(XPlayerController xPlayerUI) { + + this.xPlayerUI = xPlayerUI; + + // FXMLLoader + FXMLLoader loader = new FXMLLoader(getClass().getResource(InfoTool.FXMLS + "XPlayerExtraSettingsController.fxml")); + loader.setController(this); + loader.setRoot(this); + + try { + loader.load(); + } catch (IOException ex) { + Logger.getLogger(getClass().getName()).log(Level.SEVERE, "XPlayerSettingsController FXML can't be loaded!", ex); + } + + } + + /** + * As soon as fxml has been loaded then this method will be called 1)-constructor,2)-FXMLLOADER,3)-initialize(); + */ + @FXML + private void initialize() { + + // When this can be visible? + this.setOnKeyReleased(key -> { + if (key.getCode() == KeyCode.ESCAPE) + xPlayerUI.getSettingsToggle().setSelected(false); + }); + this.visibleProperty().bind(xPlayerUI.getSettingsToggle().selectedProperty()); + this.visibleProperty().addListener((observable, oldValue, newValue) -> { + if (newValue) // true? + this.requestFocus(); + }); + + } + + /** + * @return the equalizerTab + */ + public Tab getEqualizerTab() { + return equalizerTab; + } + +} diff --git a/src/xplayer/presenter/XPlayerSettingsController.java b/src/xplayer/presenter/XPlayerSettingsController.java deleted file mode 100644 index 42abf2a4..00000000 --- a/src/xplayer/presenter/XPlayerSettingsController.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * - */ -package xplayer.presenter; - -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.jfoenix.controls.JFXCheckBox; - -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.control.Tab; -import javafx.scene.input.KeyCode; -import javafx.scene.layout.BorderPane; -import tools.InfoTool; - -/** - * The Class XPlayerSettingsController. - * - * @author GOXR3PLUS - */ -public class XPlayerSettingsController extends BorderPane { - - @FXML - JFXCheckBox showFPS; - - @FXML - JFXCheckBox startImmediately; - - @FXML - private JFXCheckBox showVisualizer; - - @FXML - JFXCheckBox askSecurityQuestion; - - @FXML - Tab equalizerTab; - - @FXML - Tab playListTab; - - // ------------------------ - - /** The x player UI. */ - XPlayerController xPlayerUI; - - /** - * Constructor. - * - * @param xPlayerUI the x player UI - */ - public XPlayerSettingsController(XPlayerController xPlayerUI) { - - this.xPlayerUI = xPlayerUI; - - // FXMLLoader - FXMLLoader loader = new FXMLLoader(getClass().getResource(InfoTool.FXMLS + "XPlayerSettingsController.fxml")); - loader.setController(this); - loader.setRoot(this); - - try { - loader.load(); - } catch (IOException ex) { - Logger.getLogger(getClass().getName()) - .log(Level.SEVERE, "XPlayerSettingsController FXML can't be loaded!", ex); - } - - } - - /** - * As soon as fxml has been loaded then this method will be called - * 1)-constructor,2)-FXMLLOADER,3)-initialize(); - */ - @FXML - private void initialize() { - - // When this can be visible? - this.setOnKeyReleased(key -> { - if (key.getCode() == KeyCode.ESCAPE) - xPlayerUI.getSettingsToggle().setSelected(false); - }); - this.visibleProperty() - .bind(xPlayerUI.getSettingsToggle().selectedProperty()); - this.visibleProperty() - .addListener((observable, oldValue, newValue) -> { - if (newValue) // true? - this.requestFocus(); - }); - - // ShowFPS - showFPS.setOnAction(a -> xPlayerUI.visualizer.setShowFPS(!xPlayerUI.visualizer.isShowingFPS())); - - } - -} diff --git a/src/xplayer/presenter/XPlayersList.java b/src/xplayer/presenter/XPlayersList.java index e85e811a..987a5726 100644 --- a/src/xplayer/presenter/XPlayersList.java +++ b/src/xplayer/presenter/XPlayersList.java @@ -63,4 +63,18 @@ public void addXPlayerController(XPlayerController xPlayerController) { list.add(xPlayerController); } + /** + * @return the list + */ + public List getList() { + return list; + } + + /** + * @param list the list to set + */ + public void setList(List list) { + this.list = list; + } + }