diff --git a/.classpath b/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..a0b1bcc17fcae0d5d9653c26d4292a340e8b73e7 --- /dev/null +++ b/.classpath @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry excluding="core/CreateMe.java|core/CurrentWork.java|userInterface/CopyOfUserInterfaceController.java|userInterface/Save.java" kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/controlsfx"/> + <classpathentry combineaccessrules="false" kind="src" path="/_Tools"/> + <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/SQLite"/> + <classpathentry combineaccessrules="false" kind="src" path="/JSON"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="output" path="class"/> +</classpath> diff --git a/.project b/.project new file mode 100644 index 0000000000000000000000000000000000000000..c6c730111e9d69a3e961ea38fb1fc00a15a0de5c --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>SmartTime-v5.0</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.xtext.ui.shared.xtextBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.xtext.ui.shared.xtextNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..3a21537071bf4118b9e1ee864cb4bc258aa48211 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000000000000000000000000000000000000..88854c4884b7ae2cda1319acf53897b2baf88230 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,251 @@ +[CHANGELOG] +=========== + +SMARTTIME +========= + +>>> start-date: 09.01.15 +>>> status-date: 04.02.16 +____________________________________________________ + + +v.5.0.2 - (28) +=============== + +-Fixed error while saving later added time + +>>> end-work: 04.02.16 + +v.5.0.1 - (27) +=============== + +-"add time later"-view +--> added ComboBoxes for project- and taskname +-Fixed wrong calculation of time (negative values) +-got rid of installer (now standalone) +-savepath of database now OS independent + +>>> end-work: 02.02.16 + +v.5.0.0 - (26) +=============== + +-switched from logfile to database +--> adapted old classes +--> cleaned and improved code +--> improved charts +--> added ComboBox for Task selection in chartview +--> added ComboBox for Tasks selection in "new Project" Dialog +--> replaced ListView with TableView +--> entries in TableView are now editable (Projectname and Taskname) +--> entries in TableView are now deletable +--> added export functionality (as SmartTime-Database, as JSON) +--> added import functionality(from SmartTime up to v4.5.0, from SmartTime-Database, from JSON) +--> added functionality to completly delete database + +>>> end-work: 31.01.16 + +v.4.5.0 - (25) +=============== + +-added menuitem "add time later" +--> Choose Project, Task, Start- and Enddate and Start- bzw. Endtime + +>>> end-work: 11.11.15 + +v.4.4.0 - (24) +=============== + +-sort projects and tasks in totaltimeview + +>>> end-work: 20.10.15 + +v.4.3.2 - (23) +=============== + +-Bugfixes in charts +--> wrong month order + +>>> end-work: 06.10.15 + +v.4.3.1 - (22) +=============== + +-Bugfixes in charts +--> wrong font-size for dropdowns +--> chart did not refresh on selection of month + +>>> end-work: 02.09.15 + +v.4.3.0 - (21) +=============== + +-added pie chart for total projecttimes + +>>> end-work: 31.08.15 + +v.4.2.1 - (20) +=============== + +-Fixed bug in charts +--> wrong calculation of last day of August + +>>> end-work: 31.08.15 + +v.4.2.0 - (19) +=============== + +-formatted logview +--> added equal spaces + +>>> end-work: 12.08.15 + +v.4.1.1 - (18) +=============== + +-varo�ous Bugfixes in charts +(multiple worktimes at one day were not added) + +>>> end-work: 12.08.15 + +v.4.0.1 - (17) +=============== + +-added Tooltips for bars in barcharts that show time in hours + +>>> end-work: 01.08.15 + +v.4.0.0 - (16) +=============== + +-added charts + +>>> end-work: 16.07.15 + +v.3.4.3 - (15) +=============== + +-Programmierbeleg-Version (deleted Menuitems, added comments) + +>>> end-work: 28.06.15 + +v.3.4.2 - (14) +=============== + +-Fixed calculation bug (equal tasknames were added even if they are not in the same project) + +>>> end-work: 22.06.15 + +v.3.4.1 - (13) +=============== + +-Fixed calculation bug (if time was greater than 24 hours it was divided with modulo 24) + +>>> end-work: 25.05.15 + +v.3.4.0 - (12) +=============== + +-added Application-Icon +-splitted logview and totaltimeview in Accordion + +>>> end-work: 10.05.15 + +v.3.3.0 - (11) +=============== + +-Fixed wrong calculated task times +-added total time calculation for all projects and tasks + +>>> end-work: 09.05.15 + +v.3.2.0 - (10) +=============== + +-various Bugfixes +-added OnCloseRequest (failsafe if closing the app while clock is running) +-Jeder Projektname in der Projektansicht ist nun ausklappbar (zeigt seine Tasks) +--> Tasks nun auch zusammengefasst und die Zeiten zusammen addiert + +>>> end-work: 08.05.15 + +v.3.1.0 - (9) +=============== + +-added menubar with various functions +-added realtimeview for elapsed time (new Thread) +-Fixed Start/Stopp-Button + +>>> end-work: 07.05.15 + +v.3.0.0 - (8) +=============== + +-completly new UI with JavaFX +-re-programming old features in the new design + +>>> end-work: 21.04.15 + +v.2.4.1 - (7) +=============== + +-created an installer that creates the configfile on desktop +--> configfile saves savepath chosen by the user + +>>> end-work: 13.05.15 + +v.2.4.0 - (6) +=============== + +-added menuitem "About" (Version, Date, Author, etc.) +-added Tooltips for Buttons +-prevented editing of project and taskname while running +--> added warning dialog +-centered all dialogs according to main window +-various bugfixes + +>>> end-work: 07.05.15 + +v.2.3.0 - (5) +=============== + +-added realtimeview for elapsed time (new Thread) + +>>> end-work: 21.04.15 + +v.2.2.0 - (4) +=============== + +-current project and task now shown as label +-user can change savepath +-user can open a different logfile +-added dropdown for already used projectnames + +>>> end-work: 29.03.15 + +v.2.1.0 - (3) +=============== + +-combined Start and Stop Button to a Togglebutton +-added dialog for creation of project and task +-added calculation of total time for projects and tasks + +>>> end-work: 28.03.15 + +v.2.0.0 - (2) +=============== + +-switched to Java + +>>> end-work: 27.03.15 + +v.1.0.0 - (1) +=============== + +-basic implementation in Delphi (Start/Stopp-Button, Reset, Calculation of time difference, formatted output) + +>>> end-work: 09.01.15 + +____________________________________________________ + +[/CHANGELOG] \ No newline at end of file diff --git a/README.md b/README.md index ab31dc4d8915de519ca9f5e155ba90c8348c03df..b25cebc70e50ce58b2f155f9d2848049db7a8023 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,9 @@ -# SmartTime +# PlayCount +- startdate: 09.01.15 +- current version: 5.0.2 (28) - 04.02.16 + +### Description + +Measure the time you work on your projects and tasks. +Sum them up and visualize them in different charts. \ No newline at end of file diff --git a/build.fxbuild b/build.fxbuild new file mode 100644 index 0000000000000000000000000000000000000000..f21c65c33c7392224c1d64cc68f3247b0ace3cb5 --- /dev/null +++ b/build.fxbuild @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="ASCII"?> +<anttasks:AntTask xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:anttasks="http://org.eclipse.fx.ide.dt/1.0" buildDirectory="C:\Program Files\Java\re1.8.0_25"> + <deploy> + <application name="JavaFX" mainclass="userInterface." version="3.3.0" toolkit="fx"/> + <info title="test.SmartTime" vendor="Robert Goldmann"/> + </deploy> + <signar/> +</anttasks:AntTask> diff --git a/build/Icon.ico b/build/Icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0dcdf4925f3d61fcac6b83930a051e66f1533680 Binary files /dev/null and b/build/Icon.ico differ diff --git a/build/SmartTime-v.5.0.2.jar b/build/SmartTime-v.5.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..7d8d9c53ce8f272175b0738505c751d2334113fa Binary files /dev/null and b/build/SmartTime-v.5.0.2.jar differ diff --git a/build/SmartTime.exe b/build/SmartTime.exe new file mode 100644 index 0000000000000000000000000000000000000000..8d8a21e0a4a9041227eeb4d382bab3952453ebfa Binary files /dev/null and b/build/SmartTime.exe differ diff --git a/build/SmartTime.xml b/build/SmartTime.xml new file mode 100644 index 0000000000000000000000000000000000000000..eeebc12636bca117092bf11511f30ca56637f323 --- /dev/null +++ b/build/SmartTime.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<launch4jConfig> + <dontWrapJar>false</dontWrapJar> + <headerType>gui</headerType> + <jar>C:\Users\Robert\Documents\eclipse\compiled\SmartTime\SmartTime-v.5.0.2.jar</jar> + <outfile>C:\Users\Robert\Documents\eclipse\compiled\SmartTime\SmartTime.exe</outfile> + <errTitle></errTitle> + <cmdLine></cmdLine> + <chdir>.</chdir> + <priority>normal</priority> + <downloadUrl>http://java.com/download</downloadUrl> + <supportUrl></supportUrl> + <stayAlive>false</stayAlive> + <restartOnCrash>false</restartOnCrash> + <manifest></manifest> + <icon>C:\Users\Robert\Documents\eclipse\compiled\SmartTime\Icon.ico</icon> + <classPath> + <mainClass>userInterface.Main</mainClass> + <cp>.</cp> + </classPath> + <jre> + <path></path> + <bundledJre64Bit>false</bundledJre64Bit> + <bundledJreAsFallback>false</bundledJreAsFallback> + <minVersion>1.8.0</minVersion> + <maxVersion></maxVersion> + <jdkPreference>preferJre</jdkPreference> + <runtimeBits>64/32</runtimeBits> + </jre> +</launch4jConfig> \ No newline at end of file diff --git a/class/charts/BarChartGenerator$1.class b/class/charts/BarChartGenerator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1223c0dafe47004fbdef244d8ca6e0869991c9a7 Binary files /dev/null and b/class/charts/BarChartGenerator$1.class differ diff --git a/class/charts/BarChartGenerator$2.class b/class/charts/BarChartGenerator$2.class new file mode 100644 index 0000000000000000000000000000000000000000..3e55a49f96c806b5c0b414277c76f00f003100ff Binary files /dev/null and b/class/charts/BarChartGenerator$2.class differ diff --git a/class/charts/BarChartGenerator.class b/class/charts/BarChartGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..3a222390a23c2cd22219c7110110ea0c134bcd5e Binary files /dev/null and b/class/charts/BarChartGenerator.class differ diff --git a/class/charts/Chart.css b/class/charts/Chart.css new file mode 100644 index 0000000000000000000000000000000000000000..49e56f3d5f69680c6296f4dad7c164336fbf1967 --- /dev/null +++ b/class/charts/Chart.css @@ -0,0 +1,37 @@ +.default-color0.chart-area-symbol { -fx-background-color: #fba71b, #fba71b55; } +.default-color1.chart-area-symbol { -fx-background-color: #f3622d, #f3622d55; } +.default-color2.chart-area-symbol { -fx-background-color: #dda0dd, #d8bfd855; } + +.default-color0.chart-series-area-line { -fx-stroke: #fba71b; } +.default-color1.chart-series-area-line { -fx-stroke: #f3622d; } +.default-color2.chart-series-area-line { -fx-stroke: #dda0dd; } + +.default-color0.chart-series-area-fill { -fx-fill: #fba71b33; } +.default-color1.chart-series-area-fill { -fx-fill: #f3622d33; } +.default-color2.chart-series-area-fill { -fx-fill: #d8bfd844; } + + +.chart-vertical-grid-lines { + -fx-stroke: #787878; +} +.chart-horizontal-grid-lines { + -fx-stroke: #787878; +} + +.axis-label { + -fx-text-fill: #787878; +} + +.axis { + -fx-font-size: 1.4em; + -fx-tick-label-fill: #787878; + -fx-font-family: Tahoma; +} + +.axis-tick-mark { + -fx-stroke: #787878; + +} +.axis-minor-tick-mark { + -fx-stroke: #787878; +} \ No newline at end of file diff --git a/class/charts/ChartGUIController$1.class b/class/charts/ChartGUIController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fc7fe7fe6ff8f01f83e9a88f29e08a28ebf6b912 Binary files /dev/null and b/class/charts/ChartGUIController$1.class differ diff --git a/class/charts/ChartGUIController$2.class b/class/charts/ChartGUIController$2.class new file mode 100644 index 0000000000000000000000000000000000000000..15bf757eb95d48d5c2c73fe50ce96db6bf0654d4 Binary files /dev/null and b/class/charts/ChartGUIController$2.class differ diff --git a/class/charts/ChartGUIController$3.class b/class/charts/ChartGUIController$3.class new file mode 100644 index 0000000000000000000000000000000000000000..2080971d82d6bbba508c26f60833e1865c46fe46 Binary files /dev/null and b/class/charts/ChartGUIController$3.class differ diff --git a/class/charts/ChartGUIController$4.class b/class/charts/ChartGUIController$4.class new file mode 100644 index 0000000000000000000000000000000000000000..a895c7f641517817c6c49fa0c7c401488ffb069f Binary files /dev/null and b/class/charts/ChartGUIController$4.class differ diff --git a/class/charts/ChartGUIController.class b/class/charts/ChartGUIController.class new file mode 100644 index 0000000000000000000000000000000000000000..aef9c5c19ad0edf4826c5d3a6c2493bd6a5555c5 Binary files /dev/null and b/class/charts/ChartGUIController.class differ diff --git a/class/charts/PieChartGenerator$3.class b/class/charts/PieChartGenerator$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8e1814eea79f4971e7e1a31330dd9ec3bdbb96bc Binary files /dev/null and b/class/charts/PieChartGenerator$3.class differ diff --git a/class/charts/PieChartGenerator$4.class b/class/charts/PieChartGenerator$4.class new file mode 100644 index 0000000000000000000000000000000000000000..f6c507847c0e33fe248892611590459367a4a170 Binary files /dev/null and b/class/charts/PieChartGenerator$4.class differ diff --git a/class/charts/PieChartGenerator.class b/class/charts/PieChartGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..3d1d35813edd8a15cae004b05d8fc7dd28614dbc Binary files /dev/null and b/class/charts/PieChartGenerator.class differ diff --git a/class/charts/SummaryGenerator.class b/class/charts/SummaryGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..dcd19a79e23871b465d44d5a8f2a6de0c96262f0 Binary files /dev/null and b/class/charts/SummaryGenerator.class differ diff --git a/class/charts/chartGUI.fxml b/class/charts/chartGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..3a2dbc7619434b70a33f6b926096e2f181296e67 --- /dev/null +++ b/class/charts/chartGUI.fxml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="charts.ChartGUIController"> + <children> + <VBox prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> + <children> + <AnchorPane prefHeight="150.0" prefWidth="800.0"> + <children> + <HBox alignment="CENTER" layoutX="70.0" layoutY="29.0" spacing="25.0" AnchorPane.leftAnchor="70.0" AnchorPane.rightAnchor="70.0" AnchorPane.topAnchor="30.0"> + <children> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Projekt:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="projectBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Task:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="taskBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Jahr:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="yearBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Monat:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="monthBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + </children> + </HBox> + </children> + </AnchorPane> + <AnchorPane fx:id="chartPane" prefHeight="450.0" prefWidth="800.0" VBox.vgrow="ALWAYS" /> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/class/core/ConvertToTime.class b/class/core/ConvertToTime.class new file mode 100644 index 0000000000000000000000000000000000000000..0c261276953526f83b5ecfca2fc99df70e884acb Binary files /dev/null and b/class/core/ConvertToTime.class differ diff --git a/class/core/Counter.class b/class/core/Counter.class new file mode 100644 index 0000000000000000000000000000000000000000..f23259f5ca9348e680bce6e9d18999eeee00fe43 Binary files /dev/null and b/class/core/Counter.class differ diff --git a/class/core/Exporter.class b/class/core/Exporter.class new file mode 100644 index 0000000000000000000000000000000000000000..24587bd87e6fd20f6245d755c330eecb7787f8a9 Binary files /dev/null and b/class/core/Exporter.class differ diff --git a/class/core/Importer.class b/class/core/Importer.class new file mode 100644 index 0000000000000000000000000000000000000000..6febb4ae4a1f6239f67a4f4a6a8d7b63383dc125 Binary files /dev/null and b/class/core/Importer.class differ diff --git a/class/core/LogObject.class b/class/core/LogObject.class new file mode 100644 index 0000000000000000000000000000000000000000..e0bf5295873466037356b5e1570afb5047144724 Binary files /dev/null and b/class/core/LogObject.class differ diff --git a/class/core/LogObjectOld.class b/class/core/LogObjectOld.class new file mode 100644 index 0000000000000000000000000000000000000000..03ad562a91e1fcc719c2427522cfd38d14f03942 Binary files /dev/null and b/class/core/LogObjectOld.class differ diff --git a/class/core/ReadFromFile.class b/class/core/ReadFromFile.class new file mode 100644 index 0000000000000000000000000000000000000000..abf666d7b7e91c8652bf9bd50e1df244745ddf98 Binary files /dev/null and b/class/core/ReadFromFile.class differ diff --git a/class/core/SQL.class b/class/core/SQL.class new file mode 100644 index 0000000000000000000000000000000000000000..9296981be1b70be85611f47a57456ca72ce7ce90 Binary files /dev/null and b/class/core/SQL.class differ diff --git a/class/userInterface/EditController$1.class b/class/userInterface/EditController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..587860930ec59c0684582326846fb3873b186aba Binary files /dev/null and b/class/userInterface/EditController$1.class differ diff --git a/class/userInterface/EditController.class b/class/userInterface/EditController.class new file mode 100644 index 0000000000000000000000000000000000000000..1dac47a43a9bfb7d938bd99fb28e39d51c7095f4 Binary files /dev/null and b/class/userInterface/EditController.class differ diff --git a/class/userInterface/InsertTimeController$1.class b/class/userInterface/InsertTimeController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..30b1befa0407c01f5ff1a62d8828c9b8b6f9dd25 Binary files /dev/null and b/class/userInterface/InsertTimeController$1.class differ diff --git a/class/userInterface/InsertTimeController$2$1.class b/class/userInterface/InsertTimeController$2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..32aa837d7c593cc94fa0903ad1b4772ea74ad565 Binary files /dev/null and b/class/userInterface/InsertTimeController$2$1.class differ diff --git a/class/userInterface/InsertTimeController$2.class b/class/userInterface/InsertTimeController$2.class new file mode 100644 index 0000000000000000000000000000000000000000..69eac5e03be26480b98d63991fbcb5e5e1b947ea Binary files /dev/null and b/class/userInterface/InsertTimeController$2.class differ diff --git a/class/userInterface/InsertTimeController$3.class b/class/userInterface/InsertTimeController$3.class new file mode 100644 index 0000000000000000000000000000000000000000..0011999136486fbf678c43245cbc56093a90582c Binary files /dev/null and b/class/userInterface/InsertTimeController$3.class differ diff --git a/class/userInterface/InsertTimeController$4.class b/class/userInterface/InsertTimeController$4.class new file mode 100644 index 0000000000000000000000000000000000000000..96af08ecbe8f5cff5871b8d5d28658f7a3dd11c5 Binary files /dev/null and b/class/userInterface/InsertTimeController$4.class differ diff --git a/class/userInterface/InsertTimeController.class b/class/userInterface/InsertTimeController.class new file mode 100644 index 0000000000000000000000000000000000000000..caceb7828e7f769569bfee56826142bdc3d1ff7d Binary files /dev/null and b/class/userInterface/InsertTimeController.class differ diff --git a/class/userInterface/InsertTimeGUI.fxml b/class/userInterface/InsertTimeGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..f52c030cd5ff4c6c71b3b2006ff76b4e2b84e5dc --- /dev/null +++ b/class/userInterface/InsertTimeGUI.fxml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.DatePicker?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="400.0" prefWidth="540.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.InsertTimeController"> + <children> + <Label layoutX="35.0" layoutY="128.0" text="Startdatum:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <DatePicker fx:id="datePicker1" layoutX="151.0" layoutY="129.0" prefHeight="25.0" prefWidth="134.0" /> + <Label layoutX="313.0" layoutY="128.0" text="Startzeit:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <AnchorPane layoutX="409.0" layoutY="105.0"> + <children> + <fx:include fx:id="timePicker1" source="TimePicker.fxml" /> + </children> + </AnchorPane> + <AnchorPane layoutX="407.0" layoutY="195.0"> + <children> + <fx:include fx:id="timePicker2" source="TimePicker.fxml" /> + </children> + </AnchorPane> + <Label layoutX="321.0" layoutY="218.0" text="Endzeit:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <DatePicker fx:id="datePicker2" layoutX="154.0" layoutY="219.0" prefHeight="25.0" prefWidth="134.0" /> + <Label layoutX="48.0" layoutY="218.0" text="Enddatum:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label layoutX="157.0" layoutY="299.0" text="Arbeitszeit:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label fx:id="labelDuration" layoutX="284.0" layoutY="299.0" text="0 h 0 min 0 sek"> + <font> + <Font size="18.0" /> + </font> + </Label> + <Button fx:id="buttonAdd" layoutX="174.0" layoutY="348.0" mnemonicParsing="false" onAction="#buttonAdd" text="Hinzufügen"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + <Button fx:id="buttonCancel" layoutX="302.0" layoutY="348.0" mnemonicParsing="false" onAction="#buttonCancel" text="Abbrechen"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + <Label layoutX="35.0" layoutY="42.0" text="Projekt:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label layoutX="278.0" layoutY="42.0" text="Task:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <ComboBox fx:id="comboBoxProject" editable="true" layoutX="114.0" layoutY="43.0" prefWidth="150.0" /> + <ComboBox fx:id="comboBoxTask" editable="true" layoutX="332.0" layoutY="43.0" prefWidth="150.0" /> + </children> +</AnchorPane> diff --git a/class/userInterface/Main$1.class b/class/userInterface/Main$1.class new file mode 100644 index 0000000000000000000000000000000000000000..557c62230ba33ef7b4a25673f6ba71f997c6f054 Binary files /dev/null and b/class/userInterface/Main$1.class differ diff --git a/class/userInterface/Main.class b/class/userInterface/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..3d269fae5eafb2aebf1eb1bc7413b30f21d81118 Binary files /dev/null and b/class/userInterface/Main.class differ diff --git a/class/userInterface/ProjektFensterController$1.class b/class/userInterface/ProjektFensterController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d7b908b1582ac27277943c6eacec72a3092870e0 Binary files /dev/null and b/class/userInterface/ProjektFensterController$1.class differ diff --git a/class/userInterface/ProjektFensterController.class b/class/userInterface/ProjektFensterController.class new file mode 100644 index 0000000000000000000000000000000000000000..29217300b6d6d94500c86e17ed208b9e19814431 Binary files /dev/null and b/class/userInterface/ProjektFensterController.class differ diff --git a/class/userInterface/TimePicker.fxml b/class/userInterface/TimePicker.fxml new file mode 100644 index 0000000000000000000000000000000000000000..4d9f1797da2e768a94e76ba4d061e8ace152b585 --- /dev/null +++ b/class/userInterface/TimePicker.fxml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.text.*?> +<?import javafx.scene.control.*?> +<?import java.lang.*?> +<?import javafx.scene.layout.*?> +<?import javafx.scene.layout.AnchorPane?> + +<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.TimePickerController"> + <children> + <HBox fx:id="hbox" alignment="CENTER" /> + </children> +</AnchorPane> diff --git a/class/userInterface/TimePickerController$1.class b/class/userInterface/TimePickerController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e55c8159fa44d3800cb1970b91790dd493e96399 Binary files /dev/null and b/class/userInterface/TimePickerController$1.class differ diff --git a/class/userInterface/TimePickerController$2.class b/class/userInterface/TimePickerController$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5819634d1b12c2b45c6bdbbf0fba9bec9e63274d Binary files /dev/null and b/class/userInterface/TimePickerController$2.class differ diff --git a/class/userInterface/TimePickerController$3.class b/class/userInterface/TimePickerController$3.class new file mode 100644 index 0000000000000000000000000000000000000000..c6e6608d245eb2f6dd1f9899597525cd80c0bd61 Binary files /dev/null and b/class/userInterface/TimePickerController$3.class differ diff --git a/class/userInterface/TimePickerController$4.class b/class/userInterface/TimePickerController$4.class new file mode 100644 index 0000000000000000000000000000000000000000..143a13c7b70ef759e9047c8691769f92ce60ad67 Binary files /dev/null and b/class/userInterface/TimePickerController$4.class differ diff --git a/class/userInterface/TimePickerController$5.class b/class/userInterface/TimePickerController$5.class new file mode 100644 index 0000000000000000000000000000000000000000..3f72ce10fa3227506f228096b2be8ac53e5da26c Binary files /dev/null and b/class/userInterface/TimePickerController$5.class differ diff --git a/class/userInterface/TimePickerController$6.class b/class/userInterface/TimePickerController$6.class new file mode 100644 index 0000000000000000000000000000000000000000..04d2e311302ee138531adb1daeacecfa022af102 Binary files /dev/null and b/class/userInterface/TimePickerController$6.class differ diff --git a/class/userInterface/TimePickerController.class b/class/userInterface/TimePickerController.class new file mode 100644 index 0000000000000000000000000000000000000000..c80ba38afc4a4122d22396446e4f9485eb34c2f8 Binary files /dev/null and b/class/userInterface/TimePickerController.class differ diff --git a/class/userInterface/UserInterfaceController$1.class b/class/userInterface/UserInterfaceController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5b89d20bb425d769d7b50a6a37b29e2248330479 Binary files /dev/null and b/class/userInterface/UserInterfaceController$1.class differ diff --git a/class/userInterface/UserInterfaceController$2.class b/class/userInterface/UserInterfaceController$2.class new file mode 100644 index 0000000000000000000000000000000000000000..ff9c0970867a9b4ba466604013f5a5cc2b3115cd Binary files /dev/null and b/class/userInterface/UserInterfaceController$2.class differ diff --git a/class/userInterface/UserInterfaceController$3.class b/class/userInterface/UserInterfaceController$3.class new file mode 100644 index 0000000000000000000000000000000000000000..f773891ce2a6322c4c9a36a20f79c196f28b7a90 Binary files /dev/null and b/class/userInterface/UserInterfaceController$3.class differ diff --git a/class/userInterface/UserInterfaceController$4.class b/class/userInterface/UserInterfaceController$4.class new file mode 100644 index 0000000000000000000000000000000000000000..caf56af598306f95248b1330ad6907e1b8ac6a59 Binary files /dev/null and b/class/userInterface/UserInterfaceController$4.class differ diff --git a/class/userInterface/UserInterfaceController$5.class b/class/userInterface/UserInterfaceController$5.class new file mode 100644 index 0000000000000000000000000000000000000000..bd2a44b359e709795c7029302b60c94b5243ccae Binary files /dev/null and b/class/userInterface/UserInterfaceController$5.class differ diff --git a/class/userInterface/UserInterfaceController$6.class b/class/userInterface/UserInterfaceController$6.class new file mode 100644 index 0000000000000000000000000000000000000000..b1d6ae4f69590a96e15c905ac7259cadb231f1ed Binary files /dev/null and b/class/userInterface/UserInterfaceController$6.class differ diff --git a/class/userInterface/UserInterfaceController$7.class b/class/userInterface/UserInterfaceController$7.class new file mode 100644 index 0000000000000000000000000000000000000000..e65c291961e2ccccc86e9e64bf248976ddd9bb50 Binary files /dev/null and b/class/userInterface/UserInterfaceController$7.class differ diff --git a/class/userInterface/UserInterfaceController$8.class b/class/userInterface/UserInterfaceController$8.class new file mode 100644 index 0000000000000000000000000000000000000000..ce731de66b43d5ac2e533239183aa6f9e7b56c72 Binary files /dev/null and b/class/userInterface/UserInterfaceController$8.class differ diff --git a/class/userInterface/UserInterfaceController$9.class b/class/userInterface/UserInterfaceController$9.class new file mode 100644 index 0000000000000000000000000000000000000000..748f5236bf86ea29a442afeb65b5502cd5822882 Binary files /dev/null and b/class/userInterface/UserInterfaceController$9.class differ diff --git a/class/userInterface/UserInterfaceController.class b/class/userInterface/UserInterfaceController.class new file mode 100644 index 0000000000000000000000000000000000000000..03255cd485892493d7b8604970f406ca9ea36497 Binary files /dev/null and b/class/userInterface/UserInterfaceController.class differ diff --git a/class/userInterface/_de.properties b/class/userInterface/_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..901dfe290c66fe57681714c14a4f44b0aa1f5d01 --- /dev/null +++ b/class/userInterface/_de.properties @@ -0,0 +1,4 @@ +app.name=SmartTime +version.code=28 +version.name=5.0.2 +version.date=04.02.16 \ No newline at end of file diff --git a/class/userInterface/application.css b/class/userInterface/application.css new file mode 100644 index 0000000000000000000000000000000000000000..f21a2f70c496c0b64289b9b8d67c1156ef9882b3 --- /dev/null +++ b/class/userInterface/application.css @@ -0,0 +1,4 @@ +.combo-box { + -fx-font-family: "Arial"; + -fx-font-size: 18px; +} diff --git a/class/userInterface/editGUI.fxml b/class/userInterface/editGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..414f412407a6c1e10b7e89f584786585bae36290 --- /dev/null +++ b/class/userInterface/editGUI.fxml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="455.0" stylesheets="@../../class/userInterface/application.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.EditController"> + <children> + <Button layoutX="66.0" layoutY="221.0" mnemonicParsing="false" onAction="#okButton" prefWidth="92.0" text="OK"> + <font> + <Font size="14.0" /> + </font> + </Button> + <Button fx:id="abbrechenButton" layoutX="298.0" layoutY="221.0" mnemonicParsing="false" onAction="#abbrechenButtond" prefHeight="30.0" prefWidth="92.0" text="Abbrechen"> + <font> + <Font size="14.0" /> + </font> + </Button> + <ComboBox fx:id="dropdown" editable="true" layoutX="144.0" layoutY="63.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + <Label layoutX="34.0" layoutY="65.0" text="Projekt:"> + <font> + <Font name="System Bold" size="22.0" /> + </font> + </Label> + <Label layoutX="60.0" layoutY="132.0" text="Task:"> + <font> + <Font name="System Bold" size="21.0" /> + </font> + </Label> + <ComboBox fx:id="dropdownTasks" editable="true" layoutX="144.0" layoutY="128.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + <Button layoutX="183.0" layoutY="221.0" mnemonicParsing="false" onAction="#buttonDelete" prefHeight="30.0" prefWidth="92.0" text="Löschen"> + <font> + <Font size="14.0" /> + </font> + </Button> + </children> +</AnchorPane> diff --git a/class/userInterface/icon.png b/class/userInterface/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..adda60842424d26b524d45e0e0b169cddb0855bc Binary files /dev/null and b/class/userInterface/icon.png differ diff --git a/class/userInterface/projektFenster.fxml b/class/userInterface/projektFenster.fxml new file mode 100644 index 0000000000000000000000000000000000000000..ffe339d64a6ee3e9349ac76c07a7daccad40bb75 --- /dev/null +++ b/class/userInterface/projektFenster.fxml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="455.0" stylesheets="@../../class/userInterface/application.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.ProjektFensterController"> + <children> + <Button layoutX="109.0" layoutY="223.0" mnemonicParsing="false" onAction="#okButton" prefWidth="100.0" text="OK"> + <font> + <Font size="16.0" /> + </font> + </Button> + <Button fx:id="abbrechenButton" layoutX="253.0" layoutY="223.0" mnemonicParsing="false" onAction="#abbrechenButtond" prefWidth="100.0" text="Abbrechen"> + <font> + <Font size="16.0" /> + </font> + </Button> + <ComboBox fx:id="dropdown" editable="true" layoutX="144.0" layoutY="63.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + <Label layoutX="34.0" layoutY="65.0" text="Projekt:"> + <font> + <Font name="System Bold" size="22.0" /> + </font> + </Label> + <Label layoutX="60.0" layoutY="132.0" text="Task:"> + <font> + <Font name="System Bold" size="21.0" /> + </font> + </Label> + <ComboBox fx:id="dropdownTasks" editable="true" layoutX="144.0" layoutY="128.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + </children> +</AnchorPane> diff --git a/class/userInterface/userInterface.fxml b/class/userInterface/userInterface.fxml new file mode 100644 index 0000000000000000000000000000000000000000..7cb9dce06cd26e597f9fd983aa193e1e6fe96c3a --- /dev/null +++ b/class/userInterface/userInterface.fxml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Accordion?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.Menu?> +<?import javafx.scene.control.MenuBar?> +<?import javafx.scene.control.MenuItem?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.control.TableView?> +<?import javafx.scene.control.TitledPane?> +<?import javafx.scene.control.ToggleButton?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.Pane?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.shape.Line?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.UserInterfaceController"> + <children> + <VBox layoutX="143.0" layoutY="69.0" prefHeight="800.0" prefWidth="650.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> + <children> + <MenuBar> + <menus> + <Menu mnemonicParsing="false" text="Datei"> + <items> + <MenuItem mnemonicParsing="false" onAction="#insertTime" text="Zeit nachträglich einfügen" /> + <MenuItem mnemonicParsing="false" onAction="#deleteDB" text="Datenbank löschen" /> + </items></Menu> + <Menu mnemonicParsing="false" text="Import"> + <items> + <MenuItem mnemonicParsing="false" onAction="#importFromSmartTime" text="von SmartTime bis Version 4.5.0" /> + <MenuItem mnemonicParsing="false" onAction="#importFromDB" text="von SmartTime Datenbank" /> + <MenuItem mnemonicParsing="false" onAction="#importFromJSON" text="von JSON" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="Export"> + <items> + <MenuItem mnemonicParsing="false" onAction="#exportAsDB" text="als SmartTime Datenbank" /> + <MenuItem mnemonicParsing="false" onAction="#exportAsJSON" text="als JSON" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="?"> + <items> + <MenuItem mnemonicParsing="false" onAction="#about" text="Über" /> + </items> + </Menu> + </menus> + </MenuBar> + <Pane prefHeight="121.0" prefWidth="650.0"> + <children> + <Label layoutX="48.0" layoutY="25.0" text="aktuelles Projekt:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label layoutX="48.0" layoutY="73.0" text="aktuelle Aufgabe:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Button layoutX="613.0" layoutY="67.0" mnemonicParsing="false" onAction="#openProjectGUI" prefHeight="39.0" prefWidth="107.0" text="Ändern"> + <font> + <Font size="16.0" /> + </font> + </Button> + <Label fx:id="aktuellesProjektAusgabe" layoutX="239.0" layoutY="25.0" text=" "> + <font> + <Font size="18.0" /> + </font> + </Label> + <Label fx:id="aktuellerTaskAusgabe" layoutX="239.0" layoutY="73.0" text=" "> + <font> + <Font size="18.0" /> + </font> + </Label> + </children> + </Pane> + <Line endX="790.0" fill="BLACK" stroke="#cdc6c6" strokeWidth="1.5" translateX="5.0"> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </Line> + <Pane prefHeight="100.0" prefWidth="652.0"> + <children> + <ToggleButton fx:id="startButton" layoutX="49.0" layoutY="23.0" mnemonicParsing="false" prefHeight="49.0" prefWidth="116.0" text="Start"> + <font> + <Font size="16.0" /> + </font> + </ToggleButton> + <Label fx:id="labelTime" layoutX="240.0" layoutY="23.0" prefHeight="49.0" prefWidth="326.0" text=" "> + <font> + <Font name="Arial" size="28.0" /> + </font> + </Label> + <Button layoutX="614.0" layoutY="30.0" mnemonicParsing="false" onAction="#charts" prefHeight="40.0" prefWidth="107.0" text="Diagramme"> + <font> + <Font size="15.0" /> + </font> + </Button> + </children> + </Pane> + <Accordion fx:id="accordion" prefHeight="516.0" prefWidth="652.0"> + <panes> + <TitledPane fx:id="Projekte" animated="false" minHeight="250.0" prefHeight="283.0" prefWidth="652.0" text="Projekte gesamt"> + <content> + <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="650.0" /> + </content> + <font> + <Font size="14.0" /> + </font> + </TitledPane> + <TitledPane fx:id="gesamtesLog" animated="false" text="letzte Aktivitäten"> + <content> + <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> + <children> + <ScrollPane fx:id="scrollPane" layoutX="11.199999809265137" layoutY="11.199999809265137" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> + <content> + <TableView fx:id="table" prefHeight="430.0" prefWidth="784.0" /> + </content> + </ScrollPane> + </children></AnchorPane> + </content> + <font> + <Font size="14.0" /> + </font> + </TitledPane> + </panes> + </Accordion> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/src/charts/BarChartGenerator.java b/src/charts/BarChartGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..459a9b0907c61fe713f62e1e1eac3710488adcdf --- /dev/null +++ b/src/charts/BarChartGenerator.java @@ -0,0 +1,151 @@ +package charts; + +import java.util.ArrayList; +import java.util.Calendar; + +import javafx.geometry.Point2D; +import javafx.scene.Node; +import javafx.event.*; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.CategoryAxis; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.XYChart; +import javafx.scene.chart.XYChart.Data; +import javafx.scene.chart.XYChart.Series; +import javafx.scene.control.Tooltip; +import javafx.scene.input.MouseEvent; +import core.LogObject; +import core.SQL; + +public class BarChartGenerator +{ + private SQL sql; + + public BarChartGenerator(String path) + { + sql = new SQL(path); + } + + private long getMinute(long millis) + { + return (millis / (1000 * 60)); + } + + private String getHours(int minutes) + { + int hours = (int)minutes / 60; + int min = (int)minutes % 60; + return "" + hours + " h " + min + " min"; + } + + private int getMax(int year, int month) + { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month); + calendar.set(Calendar.DATE, - 1); + + int numDays = calendar.getActualMaximum(Calendar.DATE); + + return numDays; + } + + private String getMonthName(int month) + { + switch(month) + { + case 1: + return "Januar"; + case 2: + return "Februar"; + case 3: + return "M�rz"; + case 4: + return "April"; + case 5: + return "Mai"; + case 6: + return "Juni"; + case 7: + return "Juli"; + case 8: + return "August"; + case 9: + return "September"; + case 10: + return "Oktober"; + case 11: + return "November"; + case 12: + return "Dezember"; + default: + return null; + } + } + + @SuppressWarnings("unchecked") + public BarChart<String, Number> getBarChart(String project, String task, int year, int month) throws Exception + { + final CategoryAxis xAxis = new CategoryAxis(); + final NumberAxis yAxis = new NumberAxis(); + final BarChart<String, Number> chart = new BarChart<String, Number>(xAxis, yAxis); + chart.setTitle(project + " - " + task + " - " + getMonthName(month) + " " + year); + xAxis.setLabel("Tag"); + yAxis.setLabel("Zeit in Minuten"); + chart.setCategoryGap(2); + + XYChart.Series<String, Number> series = new XYChart.Series<>(); + series.setName("Arbeitszeit in Minuten"); + + ArrayList<LogObject> objects = sql.getByProjectAndTaskAndYearAndMonth(project, task, year, month); + + Long[] times = new Long[getMax(year, month)]; + + for(int i = 0; i < times.length; i++) + { + times[i] = 0L; + for(LogObject current : objects) + { + if(current.getDay() == i+1) + { + times[i] += getMinute(current.getDuration()); + } + } + } + + for(int l = 0; l < getMax(year, month); l++) + { + series.getData().add(new XYChart.Data<String, Number>(String.valueOf(l + 1), times[l])); + } + chart.getData().addAll(series); + + for(final Series<String, Number> serie : chart.getData()) + { + for(final Data<String, Number> data : serie.getData()) + { + Tooltip tooltip = new Tooltip(); + String stunden = getHours(data.getYValue().intValue()); + tooltip.setText(stunden); + Node node = data.getNode(); + node.setOnMouseEntered(new EventHandler<MouseEvent>() + { + @Override + public void handle(MouseEvent event) + { + Point2D p = node.localToScreen(event.getX() + 5, event.getY() + 7); + tooltip.show(node, p.getX(), p.getY()); + } + }); + node.setOnMouseExited(new EventHandler<MouseEvent>() + { + @Override + public void handle(MouseEvent event) + { + tooltip.hide(); + } + }); + } + } + return chart; + } +} \ No newline at end of file diff --git a/src/charts/Chart.css b/src/charts/Chart.css new file mode 100644 index 0000000000000000000000000000000000000000..49e56f3d5f69680c6296f4dad7c164336fbf1967 --- /dev/null +++ b/src/charts/Chart.css @@ -0,0 +1,37 @@ +.default-color0.chart-area-symbol { -fx-background-color: #fba71b, #fba71b55; } +.default-color1.chart-area-symbol { -fx-background-color: #f3622d, #f3622d55; } +.default-color2.chart-area-symbol { -fx-background-color: #dda0dd, #d8bfd855; } + +.default-color0.chart-series-area-line { -fx-stroke: #fba71b; } +.default-color1.chart-series-area-line { -fx-stroke: #f3622d; } +.default-color2.chart-series-area-line { -fx-stroke: #dda0dd; } + +.default-color0.chart-series-area-fill { -fx-fill: #fba71b33; } +.default-color1.chart-series-area-fill { -fx-fill: #f3622d33; } +.default-color2.chart-series-area-fill { -fx-fill: #d8bfd844; } + + +.chart-vertical-grid-lines { + -fx-stroke: #787878; +} +.chart-horizontal-grid-lines { + -fx-stroke: #787878; +} + +.axis-label { + -fx-text-fill: #787878; +} + +.axis { + -fx-font-size: 1.4em; + -fx-tick-label-fill: #787878; + -fx-font-family: Tahoma; +} + +.axis-tick-mark { + -fx-stroke: #787878; + +} +.axis-minor-tick-mark { + -fx-stroke: #787878; +} \ No newline at end of file diff --git a/src/charts/ChartGUIController.java b/src/charts/ChartGUIController.java new file mode 100644 index 0000000000000000000000000000000000000000..b1c5c7d68c645a96771334f03e814f302f9a2b7f --- /dev/null +++ b/src/charts/ChartGUIController.java @@ -0,0 +1,583 @@ +package charts; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.fxml.FXML; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.PieChart; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import core.LogObject; +import core.SQL; + +@SuppressWarnings("rawtypes") +public class ChartGUIController +{ + @FXML private Button showButton; + @FXML private ComboBox<String> projectBox; + @FXML private ComboBox<String> taskBox; + @FXML private ComboBox<String> yearBox; + @FXML private ComboBox<String> monthBox; + @FXML private AnchorPane chartPane; + + private Stage stage; + private ArrayList<String> tasks; + private ArrayList<String> years; + private ArrayList<String> months; + private SQL sql; + private Image icon; + private PieChartGenerator generator; + private SummaryGenerator summaryGenerator; + private BarChartGenerator barChartGenertator; + + public void init(String savePath, Stage stage, Image icon) + { + try + { + this.icon = icon; + sql = new SQL(savePath); + + ArrayList<String> projects = new ArrayList<String>(); + projects.add("Alle Projekte"); + ArrayList<String> projectNames = sql.getProjectNames(); + projects.addAll(projectNames); + Collections.sort(projects); + + projectBox.getItems().addAll(projects); + projectBox.setValue(projects.get(0)); + projectBox.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 15px;"); + taskBox.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 15px;"); + yearBox.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 15px;"); + monthBox.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 15px;"); + + generator = new PieChartGenerator(savePath); + summaryGenerator = new SummaryGenerator(savePath); + barChartGenertator = new BarChartGenerator(savePath); + + years = sql.getYears(); + Collections.sort(years); + yearBox.getItems().clear(); + yearBox.getItems().add("Alle Jahre"); + yearBox.getItems().addAll(years); + yearBox.getSelectionModel().select(0); + showPieChart(generator.getChart0000("Alle Projekte")); + + projectBox.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue ov, String t, String t1) + { + String selectedProject = projectBox.getValue(); + if(selectedProject.equals("Alle Projekte")) + { + try + { + taskBox.getItems().clear(); + years = sql.getYears(); + Collections.sort(years); + yearBox.getItems().clear(); + yearBox.getItems().add("Alle Jahre"); + yearBox.getItems().addAll(years); + yearBox.getSelectionModel().select(0); + monthBox.getItems().clear(); + + showPieChart(generator.getChart0000("Alle Projekte")); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + tasks = getTasks(sql.getByProject(selectedProject)); + taskBox.getItems().clear(); + taskBox.getItems().add("Alle Tasks"); + Collections.sort(tasks); + taskBox.getItems().addAll(tasks); + taskBox.getSelectionModel().select(0); + + years = getYears(sql.getByProject(selectedProject)); + Collections.sort(years); + yearBox.getItems().clear(); + yearBox.getItems().add("Alle Jahre"); + yearBox.getItems().addAll(years); + yearBox.getSelectionModel().select(0); + + monthBox.getItems().clear(); + + showPieChart(generator.getChart1000(selectedProject, selectedProject)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + }); + + taskBox.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue ov, String t, String t1) + { + + String selectedProject = projectBox.getValue(); + String selectedTask = taskBox.getValue(); + + if(selectedProject != null && selectedTask != null) + { + if( ! selectedProject.equals("Alle Projekte")) + { + if(selectedTask.equals("Alle Tasks")) + { + try + { + years = getYears(sql.getByProject(selectedProject)); + Collections.sort(years); + yearBox.getItems().clear(); + yearBox.getItems().add("Alle Jahre"); + yearBox.getItems().addAll(years); + yearBox.getSelectionModel().select(0); + monthBox.getItems().clear(); + + showPieChart(generator.getChart1000(selectedProject, selectedProject)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + years = getYears(sql.getByProjectAndTask(selectedProject, selectedTask)); + Collections.sort(years); + yearBox.getItems().clear(); + yearBox.getItems().add("Alle Jahre"); + yearBox.getItems().addAll(years); + yearBox.getSelectionModel().select(0); + monthBox.getItems().clear(); + + showSummary(summaryGenerator.getSummaryByProjectAndTask(selectedProject, selectedTask)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + } + } + }); + + yearBox.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue ov, String t, String t1) + { + String selectedProject = projectBox.getValue(); + String selectedTask = taskBox.getValue(); + String selectedYear = yearBox.getValue(); + + if(selectedProject != null && selectedYear != null) + { + if(selectedProject.equals("Alle Projekte")) + { + if(selectedYear.equals("Alle Jahre")) + { + try + { + monthBox.getItems().clear(); + showPieChart(generator.getChart0000(selectedProject)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + months = getMonths(sql.getLogObjects()); + monthBox.getItems().clear(); + monthBox.getItems().add("Alle Monate"); + monthBox.getItems().addAll(months); + monthBox.getSelectionModel().select(0); + + showPieChart(generator.getChart0010(Integer.parseInt(selectedYear), "Alle Projekte - " + selectedYear)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + else + { + if(selectedTask.equals("Alle Tasks")) + { + if(selectedYear.equals("Alle Jahre")) + { + try + { + monthBox.getItems().clear(); + showPieChart(generator.getChart1000(selectedProject, selectedProject)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + months = getMonths(sql.getByProjectAndYear(selectedProject, Integer.parseInt(selectedYear))); + monthBox.getItems().clear(); + monthBox.getItems().add("Alle Monate"); + monthBox.getItems().addAll(months); + monthBox.getSelectionModel().select(0); + + showPieChart(generator.getChart1010(selectedProject, Integer.parseInt(selectedYear), selectedProject + " - " + selectedYear)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + else + { + if(selectedYear.equals("Alle Jahre")) + { + try + { + monthBox.getItems().clear(); + showSummary(summaryGenerator.getSummaryByProjectAndTask(selectedProject, selectedTask)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + months = getMonths(sql.getByProjectAndTaskAndYear(selectedProject, selectedTask, Integer.parseInt(selectedYear))); + monthBox.getItems().clear(); + monthBox.getItems().add("Alle Monate"); + monthBox.getItems().addAll(months); + monthBox.getSelectionModel().select(0); + + showSummary(summaryGenerator.getSummaryByProjectAndTaskAndYear(selectedProject, selectedTask, Integer.parseInt(selectedYear))); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + } + } + } + }); + + monthBox.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue ov, String t, String t1) + { + String selectedProject = projectBox.getValue(); + String selectedTask = taskBox.getValue(); + String selectedYear = yearBox.getValue(); + String selectedMonth = monthBox.getValue(); + + if(selectedProject != null && selectedYear != null && selectedMonth != null) + { + if(selectedProject.equals("Alle Projekte")) + { + if(!selectedYear.equals("Alle Jahre")) + { + if(selectedMonth.equals("Alle Monate")) + { + try + { + showPieChart(generator.getChart0010(Integer.parseInt(selectedYear), "Alle Projekte - " + selectedYear)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + showPieChart(generator.getChart0011(Integer.parseInt(selectedYear), getMonthNumber(selectedMonth), "Alle Projekte - " + selectedMonth + " " + selectedYear)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + } + else + { + if(selectedTask.equals("Alle Tasks")) + { + if(!selectedYear.equals("Alle Jahre")) + { + if(selectedMonth.equals("Alle Monate")) + { + try + { + showPieChart(generator.getChart1010(selectedProject, Integer.parseInt(selectedYear), selectedProject + " - " + selectedYear)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + else + { + try + { + showPieChart(generator.getChart1011(selectedProject, Integer.parseInt(selectedYear), getMonthNumber(selectedMonth), selectedProject + " - " + selectedMonth + " " + selectedYear)); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + } + } + else + { + if(!selectedYear.equals("Alle Jahre")) + { + if(selectedMonth.equals("Alle Monate")) + { + try + { + showSummary(summaryGenerator.getSummaryByProjectAndTask(selectedProject, selectedTask)); + } + catch(Exception e) + { + showErrorMessage(); + e.printStackTrace(); + } + } + else + { + try + { + showBarChart(barChartGenertator.getBarChart(selectedProject, selectedTask, Integer.parseInt(selectedYear), getMonthNumber(selectedMonth))); + } + catch(Exception e) + { + showErrorMessage(); + e.printStackTrace(); + } + } + } + } + } + } + } + }); + } + catch(Exception e) + { + e.printStackTrace(); + showErrorMessage(); + } + } + + // public void zeigenButton() + // { + // charts.Projects.getChart(Main.dates, Main.projects, Main.differences); + // BarChart chart = charts.Projects.getSpecificChart(monthBox.getValue(), + // yearBox.getValue(), projectBox.getValue()); + // chartPane.getChildren().clear(); + // chartPane.getChildren().add(chart); + // AnchorPane.setBottomAnchor(chart, 14.0); + // AnchorPane.setTopAnchor(chart, 0.0); + // AnchorPane.setLeftAnchor(chart, 14.0); + // AnchorPane.setRightAnchor(chart, 14.0); + // chartPane.setMaxHeight(Double.MAX_VALUE); + // } + + private void showErrorMessage() + { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Fehler beim Erstellen des Diagramms."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + + private void showPieChart(PieChart chart) + { + chartPane.getChildren().clear(); + chartPane.getChildren().add(chart); + AnchorPane.setBottomAnchor(chart, 14.0); + AnchorPane.setTopAnchor(chart, 0.0); + AnchorPane.setLeftAnchor(chart, 14.0); + AnchorPane.setRightAnchor(chart, 14.0); + chartPane.setMaxHeight(Double.MAX_VALUE); + } + + private void showSummary(VBox vboxSummary) + { + chartPane.getChildren().clear(); + chartPane.getChildren().add(vboxSummary); + AnchorPane.setBottomAnchor(vboxSummary, 14.0); + AnchorPane.setTopAnchor(vboxSummary, 0.0); + AnchorPane.setLeftAnchor(vboxSummary, 14.0); + AnchorPane.setRightAnchor(vboxSummary, 14.0); + chartPane.setMaxHeight(Double.MAX_VALUE); + } + + private void showBarChart(BarChart<String, Number> chart) + { + chartPane.getChildren().clear(); + chartPane.getChildren().add(chart); + AnchorPane.setBottomAnchor(chart, 14.0); + AnchorPane.setTopAnchor(chart, 0.0); + AnchorPane.setLeftAnchor(chart, 14.0); + AnchorPane.setRightAnchor(chart, 14.0); + chartPane.setMaxHeight(Double.MAX_VALUE); + } + + private ArrayList<String> getTasks(ArrayList<LogObject> objects) + { + HashSet<String> tasks2 = new HashSet<String>(); + for(LogObject current : objects) + { + tasks2.add(String.valueOf(current.getTask())); + } + return new ArrayList<String>(tasks2); + } + + private ArrayList<String> getYears(ArrayList<LogObject> objects) + { + HashSet<String> years2 = new HashSet<String>(); + for(LogObject current : objects) + { + years2.add(String.valueOf(current.getYear())); + } + return new ArrayList<String>(years2); + } + + private ArrayList<String> getMonths(ArrayList<LogObject> objects) + { + HashSet<Integer> months2 = new HashSet<Integer>(); + for(LogObject current : objects) + { + months2.add(current.getMonth()); + } + + ArrayList<Integer> monthsList = new ArrayList<Integer>(months2); + + ArrayList<String> monthNames = new ArrayList<String>(); + + for(int k = 0; k < monthsList.size(); k++) + { + switch(monthsList.get(k)) + { + case 1: + monthNames.add("Januar"); + break; + case 2: + monthNames.add("Februar"); + break; + case 3: + monthNames.add("M�rz"); + break; + case 4: + monthNames.add("April"); + break; + case 5: + monthNames.add("Mai"); + break; + case 6: + monthNames.add("Juni"); + break; + case 7: + monthNames.add("Juli"); + break; + case 8: + monthNames.add("August"); + break; + case 9: + monthNames.add("September"); + break; + case 10: + monthNames.add("Oktober"); + break; + case 11: + monthNames.add("November"); + break; + case 12: + monthNames.add("Dezember"); + break; + } + } + + return monthNames; + } + + private int getMonthNumber(String monthName) + { + switch(monthName) + { + case "Januar": return 1; + case "Februar": return 2; + case "M�rz": return 3; + case "April": return 4; + case "Mai": return 5; + case "Juni": return 6; + case "Juli": return 7; + case "August": return 8; + case "September": return 9; + case "Oktober": return 10; + case "November": return 11; + case "Dezember": return 12; + default: return 0; + } + } +} \ No newline at end of file diff --git a/src/charts/PieChartGenerator.java b/src/charts/PieChartGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..6269a0673bdb768fa62ff6e820c54966e82a5bf7 --- /dev/null +++ b/src/charts/PieChartGenerator.java @@ -0,0 +1,174 @@ +package charts; + +import java.util.ArrayList; +import java.util.HashSet; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.EventHandler; +import javafx.geometry.Point2D; +import javafx.scene.Node; +import javafx.scene.chart.PieChart; +import javafx.scene.control.Tooltip; +import javafx.scene.input.MouseEvent; +import core.LogObject; +import core.SQL; + +public class PieChartGenerator +{ + private SQL sql; + + public PieChartGenerator(String path) + { + sql = new SQL(path); + } + + private long completeTime(ArrayList<LogObject> list) + { + long total = 0; + for(LogObject current : list) + { + total += current.getDuration(); + } + return total; + } + + private PieChart createChart(ObservableList<PieChart.Data> data, String title) + { + PieChart chart = new PieChart(data); + chart.setTitle(title); + + chart.getData().stream().forEach(tool -> { + Tooltip tooltip = new Tooltip(); + + double total = 0; + for (PieChart.Data d : chart.getData()) + { + total += d.getPieValue(); + } + + double pieValue = tool.getPieValue(); + double percentage = (pieValue/total) * 100; + String percent = String.valueOf(percentage); + percent = percent.substring(0, percent.indexOf(".") + 2); + String time = core.ConvertToTime.ConvertMillisToTime((long) pieValue); + + tooltip.setText(percent + " % \n" + time); + Tooltip.install(tool.getNode(), tooltip); + Node node = tool.getNode(); + node.setOnMouseEntered(new EventHandler<MouseEvent>() { + + @Override + public void handle(MouseEvent event) { + Point2D p = node.localToScreen(event.getX()+5,event.getY()+7); + tooltip.show(node, p.getX(), p.getY()); + } + }); + node.setOnMouseExited(new EventHandler<MouseEvent>() { + + @Override + public void handle(MouseEvent event) { + tooltip.hide(); + } + }); + }); + return chart; + } + + private ArrayList<String> getProjectNames(ArrayList<LogObject> objects) + { + HashSet<String> names = new HashSet<String>(); + for(LogObject current : objects) + { + names.add(current.getProject()); + } + + return new ArrayList<String>(names); + } + + private ArrayList<String> getTasknames(ArrayList<LogObject> objects) + { + HashSet<String> names = new HashSet<String>(); + for(LogObject current : objects) + { + names.add(current.getTask()); + } + + return new ArrayList<String>(names); + } + + //all Projects for all time + public PieChart getChart0000(String title) throws Exception + { + ArrayList<String> names = sql.getProjectNames(); + ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); + for(String currentName : names) + { + data.add(new PieChart.Data(currentName, completeTime(sql.getByProject(currentName)))); + } + return createChart(data, title); + } + + //all Projects for one specific year + public PieChart getChart0010(int year, String title) throws Exception + { + ArrayList<String> names = getProjectNames(sql.getByYear(year)); + ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); + for(String currentName : names) + { + data.add(new PieChart.Data(currentName, completeTime(sql.getByProjectAndYear(currentName, year)))); + } + return createChart(data, title); + } + + //all Projects for one specific year and month + public PieChart getChart0011(int year, int month, String title) throws Exception + { + ArrayList<String> names = getProjectNames(sql.getByYearAndMonth(year, month)); + ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); + for(String currentName : names) + { + data.add(new PieChart.Data(currentName, completeTime(sql.getByProjectAndYearAndMonth(currentName, year, month)))); + } + return createChart(data, title); + } + + //one specific Project for all time + public PieChart getChart1000(String projectName, String title) throws Exception + { + ArrayList<LogObject> objects = sql.getByProject(projectName); + ArrayList<String> names = getTasknames(objects); + ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); + for(String taskName : names) + { + data.add(new PieChart.Data(taskName, completeTime(sql.getByProjectAndTask(projectName, taskName)))); + } + return createChart(data, title); + } + + //one specific Project for one specific year + public PieChart getChart1010(String projectName, int year, String title) throws Exception + { + ArrayList<LogObject> objects = sql.getByProjectAndYear(projectName, year); + ArrayList<String> names = getTasknames(objects); + ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); + for(String taskName : names) + { + data.add(new PieChart.Data(taskName, completeTime(sql.getByProjectAndTaskAndYear(projectName, taskName, year)))); + } + return createChart(data, title); + } + + //one specific Project for one specific year and month + public PieChart getChart1011(String projectName, int year, int month, String title) throws Exception + { + ArrayList<LogObject> objects = sql.getByProjectAndYearAndMonth(projectName, year, month); + ArrayList<String> names = getTasknames(objects); + ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); + for(String taskName : names) + { + data.add(new PieChart.Data(taskName, completeTime(sql.getByProjectAndTaskAndYearAndMonth(projectName, taskName, year, month)))); + } + return createChart(data, title); + } +} \ No newline at end of file diff --git a/src/charts/SummaryGenerator.java b/src/charts/SummaryGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..842b13ef5504373a0ffbce6c5807d8b30af5abb2 --- /dev/null +++ b/src/charts/SummaryGenerator.java @@ -0,0 +1,117 @@ +package charts; + +import java.util.ArrayList; +import java.util.HashSet; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import core.ConvertToTime; +import core.LogObject; +import core.SQL; + +public class SummaryGenerator +{ + private SQL sql; + + public SummaryGenerator(String path) + { + sql = new SQL(path); + } + + private long completeTime(ArrayList<LogObject> list) + { + long total = 0; + for(LogObject current : list) + { + total += current.getDuration(); + } + return total; + } + + private int workingDays(ArrayList<LogObject> list) + { + HashSet<String> dates = new HashSet<String>(); + for(LogObject current : list) + { + dates.add(current.getDate()); + } + return dates.size(); + } + + public VBox getSummaryByProjectAndTask(String project, String task) throws Exception + { + VBox vboxSummary = new VBox(); + Label labelName = new Label(project + " - " + task); + labelName.setStyle("-fx-font-size: 25; -fx-font-weight: bold;"); + + ArrayList<LogObject> objects = sql.getByProjectAndTask(project, task); + + Label labelTotalTime = new Label(ConvertToTime.ConvertMillisToTime(completeTime(objects))); + labelTotalTime.setStyle("-fx-font-size: 25;"); + + int days = workingDays(objects); + Label labelDays; + if(days == 1) + { + labelDays = new Label(workingDays(objects) + " Arbeitstag"); + } + else + { + labelDays = new Label(workingDays(objects) + " Arbeitstage"); + } + labelDays.setStyle("-fx-font-size: 25;"); + + vboxSummary.setAlignment(Pos.CENTER); + vboxSummary.getChildren().add(labelName); + vboxSummary.getChildren().add(labelTotalTime); + vboxSummary.getChildren().add(labelDays); + VBox.setVgrow(labelName, Priority.ALWAYS); + VBox.setVgrow(labelTotalTime, Priority.ALWAYS); + VBox.setVgrow(labelDays, Priority.ALWAYS); + VBox.setMargin(labelName, new Insets(0.0, 0.0, 20.0, 0.0)); + VBox.setMargin(labelTotalTime, new Insets(20.0, 0.0, 20.0, 0.0)); + VBox.setMargin(labelDays, new Insets(20.0, 0.0, 0.0, 0.0)); + + return vboxSummary; + } + + public VBox getSummaryByProjectAndTaskAndYear(String project, String task, int year) throws Exception + { + VBox vboxSummary = new VBox(); + Label labelName = new Label(project + " - " + task + " - " + year); + labelName.setStyle("-fx-font-size: 25; -fx-font-weight: bold;"); + + ArrayList<LogObject> objects = sql.getByProjectAndTaskAndYear(project, task, year); + + Label labelTotalTime = new Label(ConvertToTime.ConvertMillisToTime(completeTime(objects))); + labelTotalTime.setStyle("-fx-font-size: 25;"); + + int days = workingDays(objects); + Label labelDays; + if(days == 1) + { + labelDays = new Label(workingDays(objects) + " Arbeitstag"); + } + else + { + labelDays = new Label(workingDays(objects) + " Arbeitstage"); + } + labelDays.setStyle("-fx-font-size: 25;"); + + vboxSummary.setAlignment(Pos.CENTER); + vboxSummary.getChildren().add(labelName); + vboxSummary.getChildren().add(labelTotalTime); + vboxSummary.getChildren().add(labelDays); + VBox.setVgrow(labelName, Priority.ALWAYS); + VBox.setVgrow(labelTotalTime, Priority.ALWAYS); + VBox.setVgrow(labelDays, Priority.ALWAYS); + VBox.setMargin(labelName, new Insets(0.0, 0.0, 20.0, 0.0)); + VBox.setMargin(labelTotalTime, new Insets(20.0, 0.0, 20.0, 0.0)); + VBox.setMargin(labelDays, new Insets(20.0, 0.0, 0.0, 0.0)); + + return vboxSummary; + } +} \ No newline at end of file diff --git a/src/charts/chartGUI.fxml b/src/charts/chartGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..3a2dbc7619434b70a33f6b926096e2f181296e67 --- /dev/null +++ b/src/charts/chartGUI.fxml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="charts.ChartGUIController"> + <children> + <VBox prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> + <children> + <AnchorPane prefHeight="150.0" prefWidth="800.0"> + <children> + <HBox alignment="CENTER" layoutX="70.0" layoutY="29.0" spacing="25.0" AnchorPane.leftAnchor="70.0" AnchorPane.rightAnchor="70.0" AnchorPane.topAnchor="30.0"> + <children> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Projekt:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="projectBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Task:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="taskBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Jahr:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="yearBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <VBox alignment="CENTER"> + <children> + <Label prefHeight="25.0" prefWidth="64.0" text="Monat:"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <ComboBox fx:id="monthBox" prefWidth="150.0"> + <VBox.margin> + <Insets top="11.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + </children> + </HBox> + </children> + </AnchorPane> + <AnchorPane fx:id="chartPane" prefHeight="450.0" prefWidth="800.0" VBox.vgrow="ALWAYS" /> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/src/core/ConvertToTime.java b/src/core/ConvertToTime.java new file mode 100644 index 0000000000000000000000000000000000000000..850932cee5f755226735ea7516c9e16dea22e0d8 --- /dev/null +++ b/src/core/ConvertToTime.java @@ -0,0 +1,36 @@ +package core; + +/** + * Klasse f�r die Umrechnung von Zeiten + * @author Robert + * + */ +public class ConvertToTime +{ + /** + * Konvertiert Millisekunden in Stunden, Minuten und Sekunden + * @param differenz long - Millisekunden + * @return String - Stunden + Minuten + Sekunden + */ + public static String ConvertMillisToTime(long differenz) + { + long sek = (differenz / 1000) % 60; + long min = (differenz / (1000 * 60)) % 60; + long hour = (differenz / (1000 * 60 * 60)); + + return hour + " h " + min + " min " + sek + " sek"; + } + + /** + * Berechnet die Differenz zwischen End- und Startzeit + * @param start long - Startzeit in Millisekunden + * @param end long - Endzeit in Millisekunden + * @return long - Differenz + */ + public static long CalculateDifference(long start, long end) + { + long difference = end - start; + + return difference; + } +} \ No newline at end of file diff --git a/src/core/Counter.java b/src/core/Counter.java new file mode 100644 index 0000000000000000000000000000000000000000..c1586b481a154d35e2555f91b20531e0aacb13e9 --- /dev/null +++ b/src/core/Counter.java @@ -0,0 +1,47 @@ +package core; + +import javafx.application.Platform; +import userInterface.UserInterfaceController; + +/** + * Thread f�r die zeitgleiche Ausf�hrung der Zeitmessung ohne Beeintr�chtigung der Hauptanwendung + * @author Robert + * + */ +public class Counter extends Thread +{ + public static boolean running; + public static long ausgabe; + public static UserInterfaceController uic; + + @Override + public void run() + { + //l�scht zu Beginn den Text des Labels + uic.labelTime.setText(""); + //initialisiert die Z�hlvariable + ausgabe = 0; + + while (running) + { + try + { + //konvertiert die bereits verstrichenen Millisekunden in Stunden, Minuten und Sekunden + //und gibt diese auf dem Label aus + Platform.runLater(()->{ + uic.labelTime.setText(ConvertToTime.ConvertMillisToTime(ausgabe)); + }); + + //schl�ft 1000 Millisekunden + Thread.sleep(1000); + //erh�ht die Z�hlvariable um 1000 Millisekunden + ausgabe = ausgabe + 1000; + } + //reagiert auf eine InterruptedException, die ausgel�st wird, wenn der Stopp-Button gedr�ckt wird + catch (InterruptedException e) + { + running = false; + } + } + } +} \ No newline at end of file diff --git a/src/core/Exporter.java b/src/core/Exporter.java new file mode 100644 index 0000000000000000000000000000000000000000..8d1e9950e8636a5d2fa32ec660d8a9319d0095eb --- /dev/null +++ b/src/core/Exporter.java @@ -0,0 +1,83 @@ +package core; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.Date; + +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.image.Image; +import javafx.stage.Stage; + +import org.jason.JSONObject; + +public class Exporter +{ + private String path; + private Stage stage; + private Image icon; + + public Exporter(String path, Stage stage, Image icon) + { + this.path = path; + this.stage = stage; + this.icon = icon; + } + + public void exportAsJSON(File file) + { + try + { + SQL sql = new SQL(path); + ArrayList<LogObject> objects = sql.getLogObjects(); + + JSONObject allItems = new JSONObject(); + + allItems.put("SmartTime", new Date()); + + for(LogObject current : objects) + { + JSONObject item = new JSONObject(); + item.put("date", current.getDate()); + item.put("startTime", current.getStartTime()); + item.put("endTime", current.getEndTime()); + item.put("duration", current.getDuration()); + item.put("project", current.getProject()); + item.put("task", current.getTask()); + allItems.append("logObjects", item); + } + + BufferedWriter out = new BufferedWriter(new FileWriter(file)); + out.write(allItems.toString()); + out.close(); + + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle("Erfolgreich exportiert"); + alert.setHeaderText(""); + alert.setContentText("Der Exportvorgang wurde erfolgreich abgeschlossen."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + catch(Exception e) + { + e.printStackTrace(); + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Exportieren der Daten ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + } +} \ No newline at end of file diff --git a/src/core/Importer.java b/src/core/Importer.java new file mode 100644 index 0000000000000000000000000000000000000000..8420ea8d9c7c5d00721d8d3352fee413c9c9832c --- /dev/null +++ b/src/core/Importer.java @@ -0,0 +1,187 @@ +package core; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.regex.Pattern; + +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.image.Image; +import javafx.stage.Stage; + +import org.jason.JSONArray; +import org.jason.JSONObject; + +public class Importer +{ + private String path; + private Stage stage; + private Image icon; + + public Importer(String path, Stage stage, Image icon) + { + this.path = path; + this.stage = stage; + this.icon = icon; + } + + public void importFromSmartTime(File file) + { + try + { + ArrayList<String > lines = readFile(file); + ArrayList<LogObject> objects = new ArrayList<LogObject>(); + for(String item : lines) + { + String[] parts = item.split("\t"); + + String date = parts[0]; + String[] dateParts = date.split("-"); + + LogObject current = new LogObject(Integer.parseInt(dateParts[2]), Integer.parseInt(dateParts[1]), Integer.parseInt(dateParts[0]), parts[3], parts[4], Long.parseLong(parts[7]), parts[5], parts[6]); + objects.add(current); + } + + SQL sql = new SQL(path); + for(LogObject o : objects) + { + sql.insert(o); + } + + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle("Erfolgreich importiert"); + alert.setHeaderText(""); + alert.setContentText("Der Importvorgang wurde erfolgreich abgeschlossen."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + catch(Exception e) + { + e.printStackTrace(); + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Importieren der Daten ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + } + + public void importFromDB(File file) + { + SQL sql = new SQL(file.getAbsolutePath()); + try + { + ArrayList<LogObject> objects = sql.getLogObjects(); + SQL currentDB = new SQL(path); + for(LogObject item : objects) + { + currentDB.insert(item); + } + + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle("Erfolgreich importiert"); + alert.setHeaderText(""); + alert.setContentText("Der Importvorgang wurde erfolgreich abgeschlossen."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + catch(Exception e) + { + e.printStackTrace(); + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Importieren der Daten ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + } + + public void importFromJSON(File file) + { + try + { + FileInputStream fis = new FileInputStream(file); + BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); + String text = ""; + String line; + while ((line = reader.readLine()) != null) + { + text = text + line; + } + reader.close(); + + JSONObject allItems = new JSONObject(text); + + SQL sql = new SQL(path); + JSONArray loadedItems = (JSONArray)allItems.get("logObjects"); + for(int i = 0; i < loadedItems.length(); i++) + { + JSONObject item = (JSONObject) loadedItems.get(i); + String date = item.getString("date"); + String startTime = item.getString("startTime"); + String endTime = item.getString("endTime"); + long duration = item.getLong("duration"); + String project = item.getString("project"); + String task = item.getString("task"); + + String[] dateParts = date.split(Pattern.quote(".")); + + LogObject loadedObject = new LogObject(Integer.parseInt(dateParts[2]), Integer.parseInt(dateParts[1]), Integer.parseInt(dateParts[0]), startTime, endTime, duration, project, task); + sql.insert(loadedObject); + } + } + catch(Exception e) + { + e.printStackTrace(); + Platform.runLater(()->{ + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Importieren der Daten ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + }); + } + } + + private ArrayList<String> readFile(File file) throws Exception + { + FileInputStream fis = new FileInputStream(file); + BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); + ArrayList<String> list = new ArrayList<>(); + + String line; + while((line = reader.readLine()) != null) + { + list.add(line); + } + + reader.close(); + + return list; + } +} diff --git a/src/core/LogObject.java b/src/core/LogObject.java new file mode 100644 index 0000000000000000000000000000000000000000..03471e141d95d99ff1f7834e4a8c996895fa8682 --- /dev/null +++ b/src/core/LogObject.java @@ -0,0 +1,122 @@ +package core; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Klasse "Logobject" - generiert Objekte, die alle wichtigen Eigenschaften f�r das Logfile enthalten + * @author Robert + * + */ +public class LogObject +{ + private int year; + private int month; + private int day; + private String startTime; + private String endTime; + private long duration; + private String project; + private String task; + + + public LogObject(int year, int month, int day, String startTime, String endTime, long duration, String project, String task) + { + this.year = year; + this.month = month; + this.day = day; + this.startTime = startTime; + this.endTime = endTime; + this.duration = duration; + this.project = project; + this.task = task; + } + + public LogObject() + { + } + + public String toString() + { + return day + "." + month + "." + year + " " + startTime + " bis " + endTime + "\t" + project + "\t" + task +"\t" + duration + " (" + ConvertToTime.ConvertMillisToTime(duration)+ ")"; + } + + public void createStartTime() + { + LocalDateTime date = LocalDateTime.now(); + year = date.getYear(); + month = date.getMonthValue(); + day = date.getDayOfMonth(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + startTime = date.format(formatter); + } + + public void createEndTime() + { + LocalDateTime date = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + endTime = date.format(formatter); + } + + public void setDuration(long duration) + { + this.duration = duration; + } + + public void setProject(String p) + { + project = p; + } + + public void setTask(String t) + { + task = t; + } + + public String getDate() + { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + LocalDateTime dateTime = LocalDateTime.of(year, month, day, 12, 00); + return dateTime.format(formatter); + } + + public String getStartTime() + { + return startTime; + } + + public String getEndTime() + { + return endTime; + } + + public long getDuration() + { + return duration; + } + + public String getProject() + { + return project; + } + + public String getTask() + { + return task; + } + + public int getYear() + { + return year; + } + + public int getMonth() + { + return month; + } + + public int getDay() + { + return day; + } +} \ No newline at end of file diff --git a/src/core/LogObjectOld.java b/src/core/LogObjectOld.java new file mode 100644 index 0000000000000000000000000000000000000000..b94af4e256ae60a675680e23d8c7c9fe9fb92fe3 --- /dev/null +++ b/src/core/LogObjectOld.java @@ -0,0 +1,224 @@ +package core; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Klasse "Logobject" - generiert Objekte, die alle wichtigen Eigenschaften f�r das Logfile enthalten + * @author Robert + * + */ +public class LogObjectOld +{ + // Startzeit in Millisekunden + private long starttime; + // Startzeit als Uhrzeit + private String startUhrzeit; + // Endzeit in Millisekunden + private long endtime; + // Endzeit als Uhrzeit + private String endUhrzeit; + private String date; + private String project; + private String task; + // Berechnete Differenz zwischen starttime und endtime + private long differenz; + // in Stunden, Minuten und Sekunden umgerechnete Differenz + private String time; + + /** + * Konstruktor nach dem Einlesen aus Datei (komplettes Objekt) + * @param date String - Datum + * @param start long - Startzeit in Millisekunden (Unixtime) + * @param startUhrzeit String - Startuhrzeit + * @param end long - Startzeit in Millisekunden (Unixtime) + * @param endUhrzeit String- Enduhrzeit + * @param project String - Projektname + * @param task String - Aufgabenname + * @param differenz long - verstrichene zeit in Millisekunden zwischen start und end + * @param time String - Differenz umgerechnet in Stunden, Minuten und Sekunden + */ + public LogObjectOld(String date, long start, String startUhrzeit, long end, String endUhrzeit, String project, String task, long differenz, String time) + { + this.date = date; + starttime = start; + this.startUhrzeit = startUhrzeit; + endtime = end; + this.endUhrzeit = endUhrzeit; + this.project = project; + this.task = task; + this.differenz = differenz; + this.time = time; + } + + /** + * leerer Konstruktor + */ + public LogObjectOld() + { + } + + /** + * toString f�r Ausgabe in Datei + * @return String - date + starttime + endtime + startUhtzeit + endUhrzeit + project + task + differenz + time + */ + public String toString() + { + return date + "\t" + starttime + "\t" + endtime + "\t" + startUhrzeit + "\t" + endUhrzeit + "\t" + project + "\t" + task + "\t" + differenz + "\t" + time; + } + + /** + * toString f�r Ausgabe im Programm + * @return String - date + startUhtzeit + endUhrzeit + project + task + time + */ + public String toString2() + { + return String.format("%-15s\t %-15s\t %-15s\t %-30s\t %-30s\t %s\t", date, startUhrzeit, endUhrzeit, project, task, time); + } + + /** + * erzeugt die Startzeit + */ + public void createStarttime() + { + Calendar cal = Calendar.getInstance(); + starttime = cal.getTimeInMillis(); + startUhrzeit = new SimpleDateFormat("HH:mm:ss").format(new Date()); + } + + /** + * erzeugt das Datum + */ + public void createDate() + { + date = new SimpleDateFormat("dd-MM-yyyy").format(new Date()); + } + + /** + * erzeugt die Endzeit + */ + public void createEndtime() + { + Calendar cal = Calendar.getInstance(); + endtime = cal.getTimeInMillis(); + endUhrzeit = new SimpleDateFormat("HH:mm:ss").format(new Date()); + } + + /** + * setzt das Projekt + * @param p String - Projektname + */ + public void setProject(String p) + { + project = p; + } + + /** + * setzt den Task + * @param t String - Taskname + */ + public void setTask(String t) + { + task = t; + } + + /** + * gibt den Projektnamen zur�ck + * @return String - Projektname + */ + public String getProject() + { + return project; + } + + /** + * gibt den Tasknamen zur�ck + * @return String - Taskname + */ + public String getTask() + { + return task; + } + + /** + * gibt die Differenz in Millisekundne zur�ck + * @return long - Differenz + */ + public long getDifferenz() + { + return differenz; + } + + /** + * gibt das Datum zur�ck + * @return String - Datum + */ + public String getDate() + { + return date; + } + + /** + * gibt die Startuhrzeit zur�ck + * @return String - Startuhrzeit + */ + public String getStartUhrzeit() + { + return startUhrzeit; + } + + /** + * gibt die Enduhrzeit zur�ck + * @return String - Enduhrzeit + */ + public String getEndUhrzeit() + { + return endUhrzeit; + } + + /** + * gibt die Differenz zur�ck + * @return String - Differenz + */ + public String getTime() + { + return time; + } + + /** + * setzt die Differenz + * @param differenz long - Differenz + */ + public void setDifferenz(long differenz) + { + this.differenz = differenz; + } + + /** + * gibt die Startuhrzeit zur�ck + * @return String - Startuhrzeit + */ + public long getStarttime() + { + return starttime; + } + + /** + * gibt die Enduhrzeit zur�ck + * @return String - Enduhrzeit + */ + public long getEndtime() + { + return endtime; + } + + /** + * setzt den Wert f�r die Differenz in Stunden, Minuten und Sekunden + * @param time String - Zeit in der Form "Stunden + Minuten + Sekunden" + */ + public void setTime(String time) + { + this.time = time; + } +} \ No newline at end of file diff --git a/src/core/ReadFromFile.java b/src/core/ReadFromFile.java new file mode 100644 index 0000000000000000000000000000000000000000..e3d71513f555dc6afdd296c70923f690e722ef92 --- /dev/null +++ b/src/core/ReadFromFile.java @@ -0,0 +1,37 @@ +package core; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; + +/** + * import old Logfiles + * @author Robert + * + */ +public class ReadFromFile +{ + public static void importFromSmartTime(File file) + { + + } + + public static ArrayList<String> read(String directory) throws IOException + { + FileInputStream fis = new FileInputStream(directory + "/save.log"); + BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); + ArrayList<String> list = new ArrayList<>(); + + String line; + while((line = reader.readLine()) != null) + { + list.add(line); + } + + reader.close(); + return list; + } +} \ No newline at end of file diff --git a/src/core/SQL.java b/src/core/SQL.java new file mode 100644 index 0000000000000000000000000000000000000000..eb0304a0bac16a33238ebce61e095d319e91389f --- /dev/null +++ b/src/core/SQL.java @@ -0,0 +1,371 @@ +package core; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashSet; + +public class SQL +{ + private String path; + + public SQL(String path) + { + this.path = path; + } + + public void createDB() throws Exception + { + Connection c = null; + Statement stmt = null; + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + + stmt = c.createStatement(); + String sql = "CREATE TABLE IF NOT EXISTS SMARTTIME(YEAR INT, MONTH INT, DAY INT, STARTTIME TEXT, ENDTIME TEXT, DURATION INT, PROJECT TEXT, TASK TEXT)"; + stmt.executeUpdate(sql); + stmt.executeUpdate("VACUUM;"); + stmt.close(); + + c.close(); + } + + public void deleteDB() throws Exception + { + Connection c = null; + Statement stmt = null; + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + + stmt = c.createStatement(); + String sql = "DELETE FROM SMARTTIME;"; + stmt.executeUpdate(sql); + stmt.close(); + + c.close(); + } + + public void insert(LogObject log) throws Exception + { + Connection c = null; + Statement stmt = null; + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + + stmt = c.createStatement(); + String sql = "INSERT INTO SMARTTIME VALUES(" + log.getYear() + "," + log.getMonth() + "," + log.getDay() + "," + "'" + log.getStartTime() + "'," + "'" + log.getEndTime() + "'," + + log.getDuration() + "," + "'" + log.getProject() + "'," + "'" + log.getTask() + "')"; + stmt.executeUpdate(sql); + stmt.close(); + + c.close(); + } + + private ArrayList<LogObject> extractLogObjects(ResultSet rs) throws Exception + { + ArrayList<LogObject> logObjects = new ArrayList<LogObject>(); + while(rs.next()) + { + int year = rs.getInt("YEAR"); + int month = rs.getInt("MONTH"); + int day = rs.getInt("DAY"); + String startTime = rs.getString("STARTTIME"); + String endTime = rs.getString("ENDTIME"); + int duration = rs.getInt("DURATION"); + String project = rs.getString("PROJECT"); + String task = rs.getString("TASK"); + + LogObject current = new LogObject(year, month, day, startTime, endTime, duration, project, task); + logObjects.add(current); + } + return logObjects; + } + + public ArrayList<LogObject> getLogObjects() throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME ORDER BY YEAR DESC, MONTH DESC, DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByProject(String projectName) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE PROJECT='"+ projectName +"'ORDER BY TASK, YEAR DESC, MONTH DESC, DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByProjectAndTask(String projectName, String taskName) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE PROJECT='"+ projectName + "' AND TASK='"+ taskName +"' ORDER BY YEAR DESC, MONTH DESC, DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByProjectAndTaskAndYear(String projectName, String taskName, int year) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE PROJECT='"+ projectName + "' AND TASK='"+ taskName +"' AND YEAR='"+ year +"'ORDER BY MONTH DESC, DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByProjectAndTaskAndYearAndMonth(String projectName, String taskName, int year, int month) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE PROJECT='"+ projectName + "' AND TASK='"+ taskName +"' AND YEAR='"+ year +"' AND MONTH='"+ month +"'ORDER BY DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByProjectAndYear(String projectName, int year) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE PROJECT='"+ projectName + "' AND YEAR='"+ year +"'ORDER BY MONTH DESC, DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByProjectAndYearAndMonth(String projectName, int year, int month) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE PROJECT='"+ projectName + "' AND YEAR='"+ year +"' AND MONTH='"+ month +"'ORDER BY DAY DESC, STARTTIME DESC;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByYear(int year) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE YEAR='"+ year +"' ORDER BY PROJECT, TASK"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<LogObject> getByYearAndMonth(int year, int month) throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME WHERE YEAR='"+ year + "' AND MONTH='"+ month +"'ORDER BY PROJECT, TASK;"); + + ArrayList<LogObject> logObjects = extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + return logObjects; + } + + public ArrayList<String> getProjectNames() throws Exception + { + Connection c = null; + Statement stmt = null; + + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:"+path); + c.setAutoCommit(false); + + stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM SMARTTIME ORDER BY PROJECT;"); + + ArrayList<LogObject> objects= extractLogObjects(rs); + + rs.close(); + stmt.close(); + c.close(); + + HashSet<String> names = new HashSet<String>(); + for(LogObject current : objects) + { + names.add(current.getProject()); + } + + return new ArrayList<String>(names); + } + + public ArrayList<String> getTaskNamesByProject(String projectName) throws Exception + { + ArrayList<LogObject> objects = getByProject(projectName); + HashSet<String> names = new HashSet<String>(); + for(LogObject current : objects) + { + names.add(current.getTask()); + } + + return new ArrayList<String>(names); + } + + public ArrayList<String> getYears() throws Exception + { + ArrayList<LogObject> objects = getLogObjects(); + HashSet<String> names = new HashSet<String>(); + for(LogObject current : objects) + { + names.add(String.valueOf(current.getYear())); + } + + return new ArrayList<String>(names); + } + + public void update(LogObject oldLog, LogObject newLog) throws Exception + { + Connection c = null; + Statement stmt = null; + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + + stmt = c.createStatement(); + String sql = "UPDATE SMARTTIME SET PROJECT='" + newLog.getProject() + "' , TASK='" + newLog.getTask() + "' " + + "WHERE YEAR='" + oldLog.getYear() + + "' AND MONTH='" + oldLog.getMonth() + + "' AND DAY='" + oldLog.getDay() + + "' AND STARTTIME='" + oldLog.getStartTime() + + "' AND ENDTIME='" + oldLog.getEndTime() + + "' AND DURATION='" + oldLog.getDuration() + + "' AND PROJECT='" + oldLog.getProject() + + "' AND TASK='" + oldLog.getTask() + "';"; + stmt.executeUpdate(sql); + stmt.close(); + + c.close(); + } + + public void delete(LogObject log) throws Exception + { + Connection c = null; + Statement stmt = null; + Class.forName("org.sqlite.JDBC"); + c = DriverManager.getConnection("jdbc:sqlite:" + path); + + stmt = c.createStatement(); + String sql = "DELETE FROM SMARTTIME " + + "WHERE YEAR='" + log.getYear() + + "' AND MONTH='" + log.getMonth() + + "' AND DAY='" + log.getDay() + + "' AND STARTTIME='" + log.getStartTime() + + "' AND ENDTIME='" + log.getEndTime() + + "' AND DURATION='" + log.getDuration() + + "' AND PROJECT='" + log.getProject() + + "' AND TASK='" + log.getTask() + "';"; + stmt.executeUpdate(sql); + stmt.close(); + + c.close(); + } +} \ No newline at end of file diff --git a/src/userInterface/EditController.java b/src/userInterface/EditController.java new file mode 100644 index 0000000000000000000000000000000000000000..29796a201fe051b59a90ff62f19cc5e69e76758b --- /dev/null +++ b/src/userInterface/EditController.java @@ -0,0 +1,132 @@ +package userInterface; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Optional; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ComboBox; +import javafx.scene.image.Image; +import javafx.stage.Stage; +import core.LogObject; +import core.SQL; + + +public class EditController +{ + @FXML private Button abbrechenButton; + @FXML private ComboBox<String> dropdown; + @FXML private ComboBox<String> dropdownTasks; + private Stage stage; + private UserInterfaceController controller; + private Image icon; + private LogObject object; + + public void init(UserInterfaceController controller, String savePath, Image icon, LogObject object) + { + this.controller = controller; + this.icon = icon; + this.object = object; + + ArrayList<String> objects = new ArrayList<String>(); + + SQL sql = new SQL(savePath); + try + { + objects = sql.getProjectNames(); + Collections.sort(objects); + } + catch(Exception e) + { + } + + dropdown.getItems().addAll(objects); + dropdown.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 18px;"); + dropdownTasks.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 18px;"); + + dropdown.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) + { + dropdownTasks.getItems().clear(); + + if(newValue != null && ! newValue.equals("")) + { + try + { + ArrayList<String> tasks = sql.getTaskNamesByProject(newValue); + Collections.sort(tasks); + dropdownTasks.getItems().addAll(tasks); + } + catch(Exception e) + { + } + } + } + }); + + dropdown.getSelectionModel().select(object.getProject()); + dropdownTasks.getSelectionModel().select(object.getTask()); + + } + + public void setStage(Stage s) + { + stage = s; + } + + public void okButton(ActionEvent e) + { + String project = dropdown.getValue(); + + String task = dropdownTasks.getValue(); + + if(project == null || project.equals("") || task == null || task.equals("")) + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Die Felder d�rfen nicht leer sein."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + else + { + LogObject newLog = new LogObject(object.getYear(), object.getMonth(), object.getDay(), object.getStartTime(), object.getEndTime(), object.getDuration(), project, task); + controller.updateEntry(object, newLog); + stage.close(); + } + } + + public void buttonDelete() + { + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("L�schen"); + alert.setHeaderText(""); + alert.setContentText("M�chten Sie den Eintrag wirklich unwiederruflich aus der Datenbank l�schen?"); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + + Optional<ButtonType> result = alert.showAndWait(); + if(result.get() == ButtonType.OK) + { + controller.deleteEntry(object); + stage.close(); + } + } + + public void abbrechenButtond(ActionEvent e) + { + stage.close(); + } +} \ No newline at end of file diff --git a/src/userInterface/InsertTimeController.java b/src/userInterface/InsertTimeController.java new file mode 100644 index 0000000000000000000000000000000000000000..f7125914da50364af1f311f9b1909f4e23c5990f --- /dev/null +++ b/src/userInterface/InsertTimeController.java @@ -0,0 +1,471 @@ +package userInterface; + +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.fxml.FXML; +import javafx.scene.Parent; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.DateCell; +import javafx.scene.control.DatePicker; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.stage.Stage; +import javafx.util.Callback; +import core.LogObject; +import core.SQL; + +public class InsertTimeController +{ + @FXML DatePicker datePicker1; + @FXML DatePicker datePicker2; + @FXML Parent timePicker1; + @FXML TimePickerController timePicker1Controller; + @FXML Parent timePicker2; + @FXML TimePickerController timePicker2Controller; + @FXML Button buttonAdd; + @FXML Button buttonCancel; + @FXML Label labelDuration; + @FXML ComboBox<String> comboBoxProject; + @FXML ComboBox<String> comboBoxTask; + + private Stage stage; + private UserInterfaceController controller; + private String savePath; + private Image icon; + + public void init(Stage stage, UserInterfaceController controller, String savePath, Image icon) + { + this.savePath = savePath; + this.stage = stage; + this.controller = controller; + this.icon = icon; + + ArrayList<String> objects = new ArrayList<String>(); + + SQL sql = new SQL(savePath); + try + { + objects = sql.getProjectNames(); + Collections.sort(objects); + } + catch(Exception e) + { + } + + comboBoxProject.getItems().addAll(objects); + comboBoxProject.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 15px;"); + comboBoxTask.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 15px;"); + + comboBoxProject.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) + { + comboBoxTask.getItems().clear(); + + if(newValue != null && !newValue.equals("")) + { + try + { + ArrayList<String> tasks = sql.getTaskNamesByProject(newValue); + Collections.sort(tasks); + comboBoxTask.getItems().addAll(tasks); + } + catch(Exception e) + { + } + } + } + }); + + timePicker1Controller.setController(this); + timePicker2Controller.setController(this); + + datePicker1.setValue(LocalDate.now()); + datePicker2.setValue(LocalDate.now()); + + final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() + { + @Override + public DateCell call(final DatePicker datePicker) + { + return new DateCell() + { + @Override + public void updateItem(LocalDate item, boolean empty) + { + super.updateItem(item, empty); + + if(item.isBefore(datePicker1.getValue())) + { + setDisable(true); + setStyle("-fx-background-color: #ffc0cb;"); + } + } + }; + } + }; + datePicker2.setDayCellFactory(dayCellFactory); + + datePicker1.valueProperty().addListener(new ChangeListener<LocalDate>() + { + @Override + public void changed(ObservableValue<? extends LocalDate> observable, LocalDate oldValue, LocalDate newValue) + { + if(isEndDateAfterStartDate()) + { + setLabelDuration(); + } + else + { + labelDuration.setText("Endzeit liegt vor Startzeit"); + } + } + }); + + datePicker2.valueProperty().addListener(new ChangeListener<LocalDate>() + { + @Override + public void changed(ObservableValue<? extends LocalDate> observable, LocalDate oldValue, LocalDate newValue) + { + if(isEndDateAfterStartDate()) + { + setLabelDuration(); + } + else + { + labelDuration.setText("Endzeit liegt vor Startzeit"); + } + } + }); + + comboBoxProject.requestFocus(); + } + + public void buttonAdd() + { + String project = comboBoxProject.getValue(); + String task = comboBoxTask.getValue(); + + if(!project.equals("") && !task.equals("")) + { + if(isEndDateAfterStartDate()) + { + int hours1 = timePicker1Controller.getHours(); + int minutes1 = timePicker1Controller.getMinutes(); + int seconds1 = timePicker1Controller.getSeconds(); + + int hours2 = timePicker2Controller.getHours(); + int minutes2 = timePicker2Controller.getMinutes(); + int seconds2 = timePicker2Controller.getSeconds(); + + LocalDate dateOne = datePicker1.getValue(); + LocalDate dateTwo = datePicker2.getValue(); + + Timestamp timestampStart = Timestamp.valueOf(dateOne.toString() + " " + hours1 + ":" + minutes1 +":" + seconds1 + ".000"); + Timestamp timestampEnd = Timestamp.valueOf(dateTwo.toString() + " " + hours2 + ":" + minutes2 +":" + seconds2 + ".000"); + + LogObject log = new LogObject( + dateOne.getYear(), + dateOne.getMonthValue(), + dateOne.getDayOfMonth(), + getCorrectedString(hours1) + ":" + getCorrectedString(minutes1) +":" + getCorrectedString(seconds1), + getCorrectedString(hours2) + ":" + getCorrectedString(minutes2) +":" + getCorrectedString(seconds2), + timestampEnd.getTime()-timestampStart.getTime(), + project, + task + ); + + SQL sql = new SQL(savePath); + try + { + sql.insert(log); + } + catch(Exception e) + { + e.printStackTrace(); + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Fehler beim Speichern des Eintrags."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle("Gespeichert"); + alert.setHeaderText(""); + alert.setContentText("Der Eintrag wurde erfolgreich gespeichert."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + stage.close(); + controller.loadAll(); + } + else + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Endzeit muss nach Startzeit liegen!"); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + } + else + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Die Felder f�r Projekt und Task d�rfen nicht leer sein!"); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + } + + public void buttonCancel() + { + stage.close(); + } + + public void refresh(TimePickerController controller, int hours, int minutes, int seconds, String item, String direction) + { + if(controller == timePicker1Controller) + { + if(item.equals("hours")) + { + if(direction.equals("up")) + { + hours++; + if(hours == 24) + { + hours = 0; + } + } + else + { + hours--; + if(hours == -1 ) + { + hours = 23; + } + } + } + else if(item.equals("minutes")) + { + if(direction.equals("up")) + { + minutes++; + if(minutes == 60) + { + minutes = 0; + } + } + else + { + minutes--; + if(minutes == -1) + { + minutes = 59; + } + } + } + else + { + if(direction.equals("up")) + { + seconds++; + if(seconds == 60) + { + seconds = 0; + } + } + else + { + seconds--; + if(seconds == -1) + { + seconds = 59; + } + } + } + timePicker1Controller.setTime(hours, minutes, seconds); + timePicker1Controller.init(); + } + else + { + if(item.equals("hours")) + { + if(direction.equals("up")) + { + hours++; + if(hours == 24) + { + hours = 0; + } + } + else + { + hours--; + if(hours == -1 ) + { + hours = 23; + } + } + } + else if(item.equals("minutes")) + { + if(direction.equals("up")) + { + minutes++; + if(minutes == 60) + { + minutes = 0; + } + } + else + { + minutes--; + if(minutes == -1) + { + minutes = 59; + } + } + } + else + { + if(direction.equals("up")) + { + seconds++; + if(seconds == 60) + { + seconds = 0; + } + } + else + { + seconds--; + if(seconds == -1) + { + seconds = 59; + } + } + } + timePicker2Controller.setTime(hours, minutes, seconds); + timePicker2Controller.init(); + } + + if(isEndDateAfterStartDate()) + { + setLabelDuration(); + } + else + { + labelDuration.setText("Endzeit liegt vor Startzeit"); + } + } + + public void setLabelDuration() + { + int hours1 = timePicker1Controller.getHours(); + int minutes1 = timePicker1Controller.getMinutes(); + int seconds1 = timePicker1Controller.getSeconds(); + + int hours2 = timePicker2Controller.getHours(); + int minutes2 = timePicker2Controller.getMinutes(); + int seconds2 = timePicker2Controller.getSeconds(); + + int days = Period.between(datePicker1.getValue(), datePicker2.getValue()).getDays(); + + String dateString = datePicker1.getValue().getYear() + "-" + getCorrectedString(datePicker1.getValue().getMonthValue()) + "-" + getCorrectedString(datePicker1.getValue().getDayOfMonth()) + "-" + getCorrectedString(hours1) + ":" + getCorrectedString(minutes1) + ":" + getCorrectedString(seconds1); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss"); + LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter); + + dateString = datePicker2.getValue().getYear() + "-" + getCorrectedString(datePicker2.getValue().getMonthValue()) + "-" + getCorrectedString(datePicker2.getValue().getDayOfMonth()) + "-" + getCorrectedString(hours2) + ":" + getCorrectedString(minutes2) + ":" + getCorrectedString(seconds2); + LocalDateTime dateTime2 = LocalDateTime.parse(dateString, formatter); + + Duration d= Duration.between(dateTime, dateTime2); + + long seconds = d.getSeconds(); + + int finalHours = 24 * days + (int)(seconds / (60 * 60)) % 24; + int finalMinutes = (int)seconds / 60 % 60;; + int finalSeconds = (int)seconds % 60; + + labelDuration.setText("" + finalHours + " h " + finalMinutes + " min " + finalSeconds + " sek"); + } + + public boolean isEndDateAfterStartDate() + { + int hours1 = timePicker1Controller.getHours(); + int minutes1 = timePicker1Controller.getMinutes(); + int seconds1 = timePicker1Controller.getSeconds(); + + int hours2 = timePicker2Controller.getHours(); + int minutes2 = timePicker2Controller.getMinutes(); + int seconds2 = timePicker2Controller.getSeconds(); + + String dateOne = java.sql.Date.valueOf(datePicker1.getValue()).toString(); + String dateTwo = java.sql.Date.valueOf(datePicker2.getValue()).toString(); + + DateFormat format = new SimpleDateFormat("yy-MM-dd - HH:mm:ss"); + + dateOne = dateOne + " - " + getCorrectedString(hours1) + ":"+ getCorrectedString(minutes1) + ":" + getCorrectedString(seconds1); + dateTwo = dateTwo + " - " + getCorrectedString(hours2) + ":"+ getCorrectedString(minutes2) + ":" + getCorrectedString(seconds2); + + try + { + Date startDate = format.parse(dateOne); + Date endDate = format.parse(dateTwo); + + if(startDate.before(endDate)) + { + return true; + } + else + { + return false; + } + } + catch(ParseException e) + { + e.printStackTrace(); + } + return false; + } + + private String getCorrectedString(int number) + { + if(number < 10) + { + return "0" + number; + } + else + { + return "" + number; + } + } +} \ No newline at end of file diff --git a/src/userInterface/InsertTimeGUI.fxml b/src/userInterface/InsertTimeGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..f52c030cd5ff4c6c71b3b2006ff76b4e2b84e5dc --- /dev/null +++ b/src/userInterface/InsertTimeGUI.fxml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.DatePicker?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="400.0" prefWidth="540.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.InsertTimeController"> + <children> + <Label layoutX="35.0" layoutY="128.0" text="Startdatum:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <DatePicker fx:id="datePicker1" layoutX="151.0" layoutY="129.0" prefHeight="25.0" prefWidth="134.0" /> + <Label layoutX="313.0" layoutY="128.0" text="Startzeit:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <AnchorPane layoutX="409.0" layoutY="105.0"> + <children> + <fx:include fx:id="timePicker1" source="TimePicker.fxml" /> + </children> + </AnchorPane> + <AnchorPane layoutX="407.0" layoutY="195.0"> + <children> + <fx:include fx:id="timePicker2" source="TimePicker.fxml" /> + </children> + </AnchorPane> + <Label layoutX="321.0" layoutY="218.0" text="Endzeit:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <DatePicker fx:id="datePicker2" layoutX="154.0" layoutY="219.0" prefHeight="25.0" prefWidth="134.0" /> + <Label layoutX="48.0" layoutY="218.0" text="Enddatum:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label layoutX="157.0" layoutY="299.0" text="Arbeitszeit:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label fx:id="labelDuration" layoutX="284.0" layoutY="299.0" text="0 h 0 min 0 sek"> + <font> + <Font size="18.0" /> + </font> + </Label> + <Button fx:id="buttonAdd" layoutX="174.0" layoutY="348.0" mnemonicParsing="false" onAction="#buttonAdd" text="Hinzufügen"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + <Button fx:id="buttonCancel" layoutX="302.0" layoutY="348.0" mnemonicParsing="false" onAction="#buttonCancel" text="Abbrechen"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + <Label layoutX="35.0" layoutY="42.0" text="Projekt:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label layoutX="278.0" layoutY="42.0" text="Task:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <ComboBox fx:id="comboBoxProject" editable="true" layoutX="114.0" layoutY="43.0" prefWidth="150.0" /> + <ComboBox fx:id="comboBoxTask" editable="true" layoutX="332.0" layoutY="43.0" prefWidth="150.0" /> + </children> +</AnchorPane> diff --git a/src/userInterface/Main.java b/src/userInterface/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..921429578a82db51c93e89da35448134646cb7b8 --- /dev/null +++ b/src/userInterface/Main.java @@ -0,0 +1,73 @@ +package userInterface; + +import javafx.application.Application; +import javafx.event.EventHandler; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.image.Image; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; + + +public class Main extends Application +{ + @Override + public void start(Stage stage) + { + try + { + FXMLLoader loader = new FXMLLoader(getClass().getResource("userInterface.fxml")); + Parent root = (Parent)loader.load(); + + Scene scene = new Scene(root, 800, 800); + + stage.setResizable(false); + stage.setTitle("SmartTime"); + stage.setScene(scene); + + UserInterfaceController controller = (UserInterfaceController)loader.getController(); + controller.setStage(stage); + controller.init(); + + stage.getIcons().add(new Image("/userInterface/icon.png")); + stage.show(); + + // f�ngt die Aufforderung das Fenster zu schlie�en ab, um vorher + // noch eine Pr�fung duchzuf�hren + stage.setOnCloseRequest(new EventHandler<WindowEvent>() + { + public void handle(WindowEvent we) + { + if(controller.stoppUhrL�uftFlag == true) + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Stoppuhr l�uft noch!"); + alert.showAndWait(); + + // "schluckt" die Aufforderung das Fenster zu schlie�en + // (Fenster wird dadurch nicht geschlossen) + we.consume(); + } + else + { + stage.close(); + } + } + }); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + public static void main(String[] args) + { + launch(args); + } +} \ No newline at end of file diff --git a/src/userInterface/ProjektFensterController.java b/src/userInterface/ProjektFensterController.java new file mode 100644 index 0000000000000000000000000000000000000000..85846fe48f025294d738ce718ffbf4a5e1aa8003 --- /dev/null +++ b/src/userInterface/ProjektFensterController.java @@ -0,0 +1,123 @@ +package userInterface; + +import java.util.ArrayList; +import java.util.Collections; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.image.Image; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; +import core.SQL; + +/** + * Controllerklasse f�r das Projektfenster + * @author Robert + * + */ + +public class ProjektFensterController implements EventHandler<WindowEvent> +{ + @FXML private Button abbrechenButton; + @FXML private ComboBox<String> dropdown; + @FXML private ComboBox<String> dropdownTasks; + private Stage stage; + private UserInterfaceController controller; + private Image icon; + + + public void init(UserInterfaceController controller, String savePath, Image icon) + { + this.controller = controller; + this.icon = icon; + + ArrayList<String> objects = new ArrayList<String>(); + + SQL sql = new SQL(savePath); + try + { + objects = sql.getProjectNames(); + Collections.sort(objects); + } + catch(Exception e) + { + } + + dropdown.getItems().addAll(objects); + dropdown.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 18px;"); + dropdownTasks.setStyle("-fx-font-family: \"Arial\";-fx-font-size: 18px;"); + + dropdown.valueProperty().addListener(new ChangeListener<String>() + { + @Override + public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) + { + dropdownTasks.getItems().clear(); + + if(newValue != null && !newValue.equals("")) + { + try + { + ArrayList<String> tasks = sql.getTaskNamesByProject(newValue); + Collections.sort(tasks); + dropdownTasks.getItems().addAll(tasks); + } + catch(Exception e) + { + } + } + } + }); + } + + @Override + public void handle(WindowEvent arg0) + { + controller.projektExistiertFlag = false; + stage.close(); + } + + public void setStage(Stage s) + { + stage = s; + stage.setOnCloseRequest(this); + } + + public void okButton(ActionEvent e) + { + String project = dropdown.getValue(); + + String task = dropdownTasks.getValue(); + + if (project == null || project.equals("") || task == null || task.equals("")) + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Die Felder d�rfen nicht leer sein."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + else + { + controller.setLabels(project,task); + controller.projektExistiertFlag = true; + controller.newProject(project, task); + stage.close(); + } + } + + public void abbrechenButtond(ActionEvent e) + { + stage.close(); + } +} \ No newline at end of file diff --git a/src/userInterface/TimePicker.fxml b/src/userInterface/TimePicker.fxml new file mode 100644 index 0000000000000000000000000000000000000000..4d9f1797da2e768a94e76ba4d061e8ace152b585 --- /dev/null +++ b/src/userInterface/TimePicker.fxml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.text.*?> +<?import javafx.scene.control.*?> +<?import java.lang.*?> +<?import javafx.scene.layout.*?> +<?import javafx.scene.layout.AnchorPane?> + +<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.TimePickerController"> + <children> + <HBox fx:id="hbox" alignment="CENTER" /> + </children> +</AnchorPane> diff --git a/src/userInterface/TimePickerController.java b/src/userInterface/TimePickerController.java new file mode 100644 index 0000000000000000000000000000000000000000..da845aa884b9fe2981a8bed88ccbd6de7e78bdfa --- /dev/null +++ b/src/userInterface/TimePickerController.java @@ -0,0 +1,223 @@ +package userInterface; + +import java.net.URL; +import java.util.ResourceBundle; + +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import fontAwesome.FontIcon; +import fontAwesome.FontIconType; + +public class TimePickerController implements Initializable +{ + @FXML private HBox hbox; + + private Label labelHours; + private Label labelMinutes; + private Label labelSeconds; + + private Button buttonHoursUp; + private Button buttonHoursDown; + + private Button buttonMinutesUp; + private Button buttonMinutesDown; + + private Button buttonSecondsUp; + private Button buttonSecondsDown; + + private int hours = 0; + private int minutes = 0; + private int seconds = 0; + + private InsertTimeController controller; + + public void setController(InsertTimeController controller) + { + this.controller = controller; + } + + public int getHours() + { + return hours; + } + + public int getMinutes() + { + return minutes; + } + + public int getSeconds() + { + return seconds; + } + + public void setTime(int hours, int minutes, int seconds) + { + this.hours = hours; + this.minutes = minutes; + this.seconds = seconds; + } + + public void refresh(String item, String direction) + { + controller.refresh(this, hours, minutes, seconds, item, direction); + } + + private String getCorrectedString(int number) + { + if(number < 10) + { + return "0" + number; + } + else + { + return "" + number; + } + } + + public void init() + { + labelHours.setText(getCorrectedString(hours)); + labelMinutes.setText(getCorrectedString(minutes)); + labelSeconds.setText(getCorrectedString(seconds)); + } + + @Override + public void initialize(URL location, ResourceBundle resources) + { + FontIcon arrowUp = new FontIcon(FontIconType.ARROW_UP); + arrowUp.setSize(10); + arrowUp.setColor(Color.web("#000000")); + + FontIcon arrowDown = new FontIcon(FontIconType.ARROW_DOWN); + arrowDown.setSize(10); + arrowDown.setColor(Color.web("#000000")); + + //VBoxHours + buttonHoursUp = new Button("", arrowUp); + buttonHoursUp.setOnAction(new EventHandler<ActionEvent>() + { + @Override + public void handle(ActionEvent event) + { + refresh("hours", "up"); + } + }); + + labelHours = new Label("00"); + labelHours.setStyle("-fx-font-size: 18; "); + + buttonHoursDown = new Button("", arrowDown); + buttonHoursDown.setOnAction(new EventHandler<ActionEvent>() + { + @Override + public void handle(ActionEvent event) + { + refresh("hours", "down"); + } + }); + + VBox vboxHours = new VBox(); + vboxHours.getChildren().add(buttonHoursUp); + vboxHours.getChildren().add(labelHours); + vboxHours.getChildren().add(buttonHoursDown); + vboxHours.setAlignment(Pos.CENTER); + + //VBoxMinutes + + arrowUp = new FontIcon(FontIconType.ARROW_UP); + arrowUp.setSize(10); + arrowUp.setColor(Color.web("#000000")); + + arrowDown = new FontIcon(FontIconType.ARROW_DOWN); + arrowDown.setSize(10); + arrowDown.setColor(Color.web("#000000")); + + buttonMinutesUp = new Button("", arrowUp); + buttonMinutesUp.setOnAction(new EventHandler<ActionEvent>() + { + @Override + public void handle(ActionEvent event) + { + refresh("minutes", "up"); + } + }); + + labelMinutes = new Label("00"); + labelMinutes.setStyle("-fx-font-size: 18;"); + + buttonMinutesDown = new Button("", arrowDown); + buttonMinutesDown.setOnAction(new EventHandler<ActionEvent>() + { + @Override + public void handle(ActionEvent event) + { + refresh("minutes", "down"); + } + }); + + VBox vboxMinutes = new VBox(); + vboxMinutes.getChildren().add(buttonMinutesUp); + vboxMinutes.getChildren().add(labelMinutes); + vboxMinutes.getChildren().add(buttonMinutesDown); + vboxMinutes.setAlignment(Pos.CENTER); + + //VBoxSeconds + arrowUp = new FontIcon(FontIconType.ARROW_UP); + arrowUp.setSize(10); + arrowUp.setColor(Color.web("#000000")); + + arrowDown = new FontIcon(FontIconType.ARROW_DOWN); + arrowDown.setSize(10); + arrowDown.setColor(Color.web("#000000")); + + buttonSecondsUp = new Button("", arrowUp); + buttonSecondsUp.setOnAction(new EventHandler<ActionEvent>() + { + @Override + public void handle(ActionEvent event) + { + refresh("seconds", "up"); + } + }); + + labelSeconds = new Label("00"); + labelSeconds.setStyle("-fx-font-size: 18; "); + + buttonSecondsDown = new Button("", arrowDown); + buttonSecondsDown.setOnAction(new EventHandler<ActionEvent>() + { + @Override + public void handle(ActionEvent event) + { + refresh("seconds", "down"); + } + }); + + VBox vboxSeconds = new VBox(); + vboxSeconds.getChildren().add(buttonSecondsUp); + vboxSeconds.getChildren().add(labelSeconds); + vboxSeconds.getChildren().add(buttonSecondsDown); + vboxSeconds.setAlignment(Pos.CENTER); + + //Hinzuf�gen zur HBox + Label separator = new Label(" : "); + separator.setStyle("-fx-font-size: 18; -fx-font-weight: bold;"); + Label separator2 = new Label(" : "); + separator2.setStyle("-fx-font-size: 18; -fx-font-weight: bold;"); + + hbox.getChildren().add(vboxHours); + hbox.getChildren().add(separator); + hbox.getChildren().add(vboxMinutes); + hbox.getChildren().add(separator2); + hbox.getChildren().add(vboxSeconds); + } +} \ No newline at end of file diff --git a/src/userInterface/UserInterfaceController.java b/src/userInterface/UserInterfaceController.java new file mode 100644 index 0000000000000000000000000000000000000000..2f134cd840079aeb8aff3ed89fc1507e451b743a --- /dev/null +++ b/src/userInterface/UserInterfaceController.java @@ -0,0 +1,873 @@ +package userInterface; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Locale; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.regex.Pattern; + +import tools.PathUtils; +import javafx.application.Platform; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Accordion; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableColumn.CellDataFeatures; +import javafx.scene.control.TableRow; +import javafx.scene.control.TableView; +import javafx.scene.control.TitledPane; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.TreeItem; +import javafx.scene.control.TreeView; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.image.Image; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.stage.FileChooser; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; +import javafx.util.Callback; +import charts.ChartGUIController; +import core.ConvertToTime; +import core.Exporter; +import core.Importer; +import core.LogObject; +import core.SQL; + + +public class UserInterfaceController +{ + @FXML private Label aktuellesProjektAusgabe; + @FXML private Label aktuellerTaskAusgabe; + @FXML public Label labelTime; + @FXML private Accordion accordion; + @FXML private TitledPane Projekte; + @FXML private TitledPane gesamtesLog; + @FXML private AnchorPane MainFrame; + @FXML private ToggleButton startButton; + @FXML private TableView<LogObject> table; + @FXML private ScrollPane scrollPane; + + private Stage stage; + private core.Counter stoppUhr; + public boolean stoppUhrL�uftFlag; + public boolean projektExistiertFlag; + private ArrayList<TreeItem<HBox>> aktuelleTasks; + private TreeItem<HBox> item; + private LogObject log; + private long startTimestamp; + private long endTimestamp; + private int longestProject; + private ArrayList<LogObject> logObjects = new ArrayList<LogObject>(); + private final String savePath = PathUtils.getOSindependentPath() + "/Deadlocker/SmartTime/save.db"; + private SQL sql; + private Stage waitingStage = new Stage(); + private Image icon; + private final ResourceBundle bundle = ResourceBundle.getBundle("userInterface/", Locale.GERMANY); + + public void init() + { + PathUtils.checkFolder(new File(new File(savePath).getParent())); + icon = new Image("/userInterface/icon.png"); + + accordion.setExpandedPane(gesamtesLog); + + projektExistiertFlag = false; + stoppUhrL�uftFlag = false; + + labelTime.setText("0 h 0 min 0 sek"); + stoppUhrL�uftFlag = false; + + loadAll(); + + // verwaltet den Start/Stopp-Button + startButton.setOnAction(event -> { + + if(projektExistiertFlag == true) + + if(startButton.isSelected()) + { + stoppUhrL�uftFlag = true; + + labelTime.setText(""); + core.Counter.ausgabe = 0; + + startButton.setText("Stopp"); + + stoppUhr = new core.Counter(); + core.Counter.running = true; + core.Counter.uic = this; + startClock(); + + stoppUhr.start(); + } + else + { + stoppUhrL�uftFlag = false; + startButton.setText("Start"); + + stoppUhr.interrupt(); + + endClock(); + + loadAll(); + } + else + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Kein Projekt ausgew�hlt!"); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + + startButton.setSelected(false); + } + }); + } + + /** + * F�ngt die Aufforderung das Fenster zu schlie�en ab, um vorher noch eine + * Pr�fung duchzuf�hren + */ + public void closeRequest() + { + // Pr�ft, ob die Stoppuhr noch l�uft + if(stoppUhrL�uftFlag == true) + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText(""); + alert.setContentText("Stoppuhr l�uft noch!"); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + else + { + stage.close(); + } + } + + public void setStage(Stage s) + { + stage = s; + } + + public void setLabels(String project, String task) + { + aktuellesProjektAusgabe.setText(project); + aktuellerTaskAusgabe.setText(task); + } + + public void openProjectGUI(ActionEvent e) + { + if( ! stoppUhrL�uftFlag) + { + try + { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("projektFenster.fxml")); + Parent root = (Parent)fxmlLoader.load(); + Stage stage = new Stage(); + stage.setScene(new Scene(root, 455, 300)); + stage.setTitle("Neues Projekt"); + + stage.getIcons().add(icon); + + ProjektFensterController pfc = (ProjektFensterController)fxmlLoader.getController(); + pfc.setStage(stage); + pfc.init(this, savePath, icon); + + stage.setResizable(false); + stage.initModality(Modality.APPLICATION_MODAL); + stage.showAndWait(); + } + catch(IOException d) + { + d.printStackTrace(); + } + } + else + { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Warnung"); + alert.setHeaderText("Stoppuhr l�uft noch!"); + alert.setContentText("Projekt und Task k�nnen nur ge�ndert werden,\nwenn die Stoppuhr nicht l�uft."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + } + + private void createTreeView() + { + // generiert den root-Knoten + Label labelRoot = new Label("Gesamt"); + labelRoot.setPrefWidth((longestProject * 6) + 150); + Label labelRootTime = new Label(completeTime(logObjects)); + labelRootTime.setPrefWidth(150); + + HBox boxRoot = new HBox(); + boxRoot.getChildren().add(labelRoot); + boxRoot.getChildren().add(labelRootTime); + + TreeItem<HBox> gesamt = new TreeItem<HBox>(boxRoot); + gesamt.setExpanded(true); + + try + { + ArrayList<String> projectNames = sql.getProjectNames(); + Collections.sort(projectNames); + + ArrayList<TreeItem<HBox>> alleTasks = new ArrayList<>(); + + for(String projectName : projectNames) + { + Label labelProjekt = new Label(projectName); + labelProjekt.setPrefWidth((longestProject * 6) + 150); + Label labelProjektTime = new Label(completeTime(sql.getByProject(projectName))); + labelProjektTime.setPrefWidth(200); + + HBox box = new HBox(); + box.getChildren().add(labelProjekt); + box.getChildren().add(labelProjektTime); + + item = new TreeItem<HBox>(box); + + aktuelleTasks = new ArrayList<TreeItem<HBox>>(); + + ArrayList<String> taskNames = sql.getTaskNamesByProject(projectName); + Collections.sort(taskNames); + for(String taskName : taskNames) + { + Label labelTask = new Label(taskName); + labelTask.setPrefWidth((longestProject * 6) + 150); + Label labelTaskTime = new Label(completeTime(sql.getByProjectAndTask(projectName, taskName))); + labelTaskTime.setPrefWidth(200); + + HBox box2 = new HBox(); + box2.getChildren().add(labelTask); + box2.getChildren().add(labelTaskTime); + + // und ein neus TreeItem erzeugt, was sp�ter Kind des + // �bergeordneten Knoten mit dem Projektnamen sein wird + aktuelleTasks.add(new TreeItem<HBox>(box2)); + } + + // f�gt alle TreeItems der Ansicht hinzu + item.getChildren().setAll(aktuelleTasks); + alleTasks.add(item); + } + + gesamt.getChildren().setAll(alleTasks); + TreeView<HBox> tree = new TreeView<HBox>(gesamt); + Projekte.setContent(tree); + } + catch(Exception e) + { + e.printStackTrace(); + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Laden der Daten ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + } + + private void loadFromDB() + { + sql = new SQL(savePath); + try + { + logObjects = sql.getLogObjects(); + + longestProject = 0; + + for(LogObject current : logObjects) + { + int length = current.getProject().length(); + if(length > longestProject) + { + longestProject = length; + } + } + } + catch(Exception e) + { + e.printStackTrace(); + try + { + sql.createDB(); + } + catch(Exception ex) + { + ex.printStackTrace(); + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Fehler beim Erstellen der Datenbank."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + } + } + + private void createLogView() + { + table.getItems().clear(); + table.getColumns().clear(); + + TableColumn<LogObject, String> dates = new TableColumn<>("Datum"); + dates.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<LogObject, String>, ObservableValue<String>>() + { + @Override + public ObservableValue<String> call(CellDataFeatures<LogObject, String> param) + { + StringProperty value = new SimpleStringProperty(); + value.set(param.getValue().getDate()); + return value; + } + }); + dates.setStyle("-fx-alignment: CENTER;"); + dates.setComparator(new Comparator<String>() + { + @Override + public int compare(String input1, String input2) + { + // 0 --> input1 == input2 + // 1 --> input1 > input2 + // -1 --> input1 < input2 + + if(input1.equals(input2)) + { + return 0; + } + else + { + String[] date1 = input1.split(Pattern.quote(".")); + String[] date2 = input2.split(Pattern.quote(".")); + + String newDate1 = date1[2] + "." + date1[1] + "." + date1[0]; + String newDate2 = date2[2] + "." + date2[1] + "." + date2[0]; + + return newDate1.compareTo(newDate2); + } + } + }); + + TableColumn<LogObject, String> startTimes = new TableColumn<>("Startzeit"); + startTimes.setCellValueFactory(new PropertyValueFactory<LogObject, String>("startTime")); + startTimes.setStyle("-fx-alignment: CENTER;"); + + TableColumn<LogObject, String> endTimes = new TableColumn<>("Endzeit"); + endTimes.setCellValueFactory(new PropertyValueFactory<LogObject, String>("endTime")); + endTimes.setStyle("-fx-alignment: CENTER;"); + + TableColumn<LogObject, String> projects = new TableColumn<>("Projekt"); + projects.setCellValueFactory(new PropertyValueFactory<LogObject, String>("project")); + projects.setStyle("-fx-alignment: CENTER;"); + + TableColumn<LogObject, String> tasks = new TableColumn<>("Task"); + tasks.setCellValueFactory(new PropertyValueFactory<LogObject, String>("task")); + tasks.setStyle("-fx-alignment: CENTER;"); + + TableColumn<LogObject, String> durations = new TableColumn<>("Dauer"); + durations.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<LogObject, String>, ObservableValue<String>>() + { + @Override + public ObservableValue<String> call(CellDataFeatures<LogObject, String> param) + { + StringProperty value = new SimpleStringProperty(); + value.set(ConvertToTime.ConvertMillisToTime(param.getValue().getDuration())); + return value; + } + }); + durations.setStyle("-fx-alignment: CENTER;"); + + table.getColumns().add(dates); + table.getColumns().add(startTimes); + table.getColumns().add(endTimes); + table.getColumns().add(projects); + table.getColumns().add(tasks); + table.getColumns().add(durations); + + ObservableList<LogObject> objectsForTable = FXCollections.observableArrayList(logObjects); + table.setItems(objectsForTable); + table.setFixedCellSize(26); + table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + table.setOnMousePressed(new EventHandler<MouseEvent>() + { + @SuppressWarnings("unchecked") + @Override + public void handle(MouseEvent event) + { + if(event.isPrimaryButtonDown() && event.getClickCount() == 2) + { + Node node = ((Node)event.getTarget()).getParent(); + TableRow<LogObject> row; + if(node instanceof TableRow) + { + row = (TableRow<LogObject>)node; + } + else + { + // clicking on text part + row = (TableRow<LogObject>)node.getParent(); + } + + editEntry(row.getItem()); + } + } + }); + + table.prefWidthProperty().bind(scrollPane.widthProperty().subtract(2)); + table.prefHeightProperty().bind(scrollPane.heightProperty().subtract(2)); + } + + @FXML + private void charts() + { + try + { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/charts/chartGUI.fxml")); + Parent root = (Parent)fxmlLoader.load(); + Scene scene = new Scene(root, 800, 600); + scene.getStylesheets().add("charts/Chart.css"); + Stage stage = new Stage(); + stage.setScene(scene); + stage.setTitle("Diagramme"); + ChartGUIController controller = (ChartGUIController)fxmlLoader.getController(); + controller.init(savePath, stage, icon); + stage.getIcons().add(icon); + + stage.setResizable(true); + stage.setMinWidth(800); + stage.setMinHeight(600); + stage.initModality(Modality.APPLICATION_MODAL); + stage.showAndWait(); + } + catch(IOException e) + { + e.printStackTrace(); + } + } + + public void loadAll() + { + loadFromDB(); + createLogView(); + createTreeView(); + } + + public void newProject(String project, String task) + { + log = new LogObject(); + log.setProject(project); + log.setTask(task); + } + + private void startClock() + { + stoppUhrL�uftFlag = true; + log.createStartTime(); + startTimestamp = System.currentTimeMillis(); + } + + private void endClock() + { + stoppUhrL�uftFlag = false; + log.createEndTime(); + endTimestamp = System.currentTimeMillis(); + log.setDuration(endTimestamp - startTimestamp); + + SQL sql = new SQL(savePath); + try + { + sql.insert(log); + } + catch(Exception e) + { + e.printStackTrace(); + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Fehler beim Speichern des Eintrags."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + + loadAll(); + } + + private String completeTime(ArrayList<LogObject> list) + { + long total = 0; + for(LogObject current : list) + { + total += current.getDuration(); + } + + return ConvertToTime.ConvertMillisToTime(total); + } + + public void insertTime() + { + try + { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/userInterface/InsertTimeGUI.fxml")); + Parent root = (Parent)fxmlLoader.load(); + Scene scene = new Scene(root, 540, 400); + Stage stage = new Stage(); + stage.setScene(scene); + stage.setTitle("Zeit nachtr�glich einf�gen"); + + InsertTimeController controller = (InsertTimeController)fxmlLoader.getController(); + controller.init(stage, this, savePath, icon); + stage.getIcons().add(icon); + + stage.setResizable(false); + stage.initModality(Modality.APPLICATION_MODAL); + stage.showAndWait(); + } + catch(IOException e) + { + e.printStackTrace(); + } + } + + public void importFromSmartTime() + { + final FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Import von SmartTime bis v4.5.0"); + fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); + fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("SmartTime-Logdateien", "*.log")); + File file = fileChooser.showOpenDialog(stage); + if(file != null) + { + Thread importThread = new Thread() + { + public void run() + { + Platform.runLater(() -> { + showWaitingDialog("Importiere...", "Bitte warten..."); + }); + Importer importer = new Importer(savePath, stage, icon); + importer.importFromSmartTime(file); + Platform.runLater(() -> { + closeWaitingDialog(); + loadAll(); + }); + } + }; + importThread.start(); + } + } + + public void importFromDB() + { + final FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Import von SmartTime Datenbank"); + fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); + fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("SmartTime Datenbank", "*.db")); + File file = fileChooser.showOpenDialog(stage); + if(file != null) + { + Thread importThread = new Thread() + { + public void run() + { + Platform.runLater(() -> { + showWaitingDialog("Importiere...", "Bitte warten..."); + }); + Importer importer = new Importer(savePath, stage, icon); + importer.importFromDB(file); + Platform.runLater(() -> { + closeWaitingDialog(); + loadAll(); + }); + } + }; + importThread.start(); + } + } + + public void importFromJSON() + { + final FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Import von JSON"); + fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); + fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("JSON", "*.json")); + File file = fileChooser.showOpenDialog(stage); + if(file != null) + { + Thread importThread = new Thread() + { + public void run() + { + Platform.runLater(() -> { + showWaitingDialog("Importiere...", "Bitte warten..."); + }); + Importer importer = new Importer(savePath, stage, icon); + importer.importFromJSON(file); + Platform.runLater(() -> { + closeWaitingDialog(); + loadAll(); + }); + } + }; + importThread.start(); + } + } + + public void exportAsDB() + { + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Export als SmartTime Datenbank"); + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("SmartTime-Datenbank", "*.db"); + fileChooser.getExtensionFilters().add(extFilter); + File file = fileChooser.showSaveDialog(stage); + if(file != null) + { + try + { + Files.copy(new File(savePath).toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + catch(IOException e) + { + e.printStackTrace(); + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Exportieren der Daten ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle("Erfolgreich exportiert"); + alert.setHeaderText(""); + alert.setContentText("Export erfolgreich abgeschlossen."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } + } + + public void exportAsJSON() + { + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Export als JSON"); + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("JSON", "*.json"); + fileChooser.getExtensionFilters().add(extFilter); + File file = fileChooser.showSaveDialog(stage); + if(file != null) + { + Thread exportThread = new Thread() + { + public void run() + { + Platform.runLater(() -> { + showWaitingDialog("Exportiere...", "Bitte warten..."); + }); + Exporter exporter = new Exporter(savePath, stage, icon); + exporter.exportAsJSON(file); + Platform.runLater(() -> { + closeWaitingDialog(); + }); + } + }; + exportThread.start(); + } + } + + public void showWaitingDialog(String title, String text) + { + HBox hboxWaiting = new HBox(); + ProgressIndicator indicator = new ProgressIndicator(); + indicator.setPrefWidth(40.0); + indicator.setPrefHeight(40.0); + Label labelWait = new Label(text); + labelWait.setStyle("-fx-font-size: 20;"); + hboxWaiting.getChildren().add(indicator); + hboxWaiting.getChildren().add(labelWait); + hboxWaiting.setAlignment(Pos.CENTER); + HBox.setMargin(labelWait, new Insets(0.0, 0.0, 0.0, 30.0)); + hboxWaiting.setPadding(new Insets(20.0)); + waitingStage = new Stage(); + waitingStage.setTitle(title); + waitingStage.setScene(new Scene(hboxWaiting, 250, 75)); + waitingStage.getIcons().add(icon); + waitingStage.initOwner(stage); + waitingStage.setResizable(false); + waitingStage.initModality(Modality.APPLICATION_MODAL); + waitingStage.setOnCloseRequest(new EventHandler<WindowEvent>() + { + @Override + public void handle(WindowEvent event) + { + event.consume(); + } + }); + waitingStage.show(); + } + + public void closeWaitingDialog() + { + if(waitingStage.isShowing()) + { + waitingStage.close(); + } + } + + private void editEntry(LogObject object) + { + try + { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("editGUI.fxml")); + Parent root = (Parent)fxmlLoader.load(); + Stage stage = new Stage(); + stage.setScene(new Scene(root, 455, 280)); + stage.setTitle("Eintrag bearbeiten"); + + stage.getIcons().add(icon); + + EditController pfc = (EditController)fxmlLoader.getController(); + pfc.setStage(stage); + pfc.init(this, savePath, icon, object); + + stage.setResizable(false); + stage.initModality(Modality.APPLICATION_MODAL); + stage.showAndWait(); + } + catch(IOException d) + { + d.printStackTrace(); + } + } + + public void updateEntry(LogObject oldLog, LogObject newLog) + { + try + { + sql.update(oldLog, newLog); + loadAll(); + } + catch(Exception e) + { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim Aktualisieren des Eintrags ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + e.printStackTrace(); + } + } + + public void deleteEntry(LogObject object) + { + try + { + sql.delete(object); + loadAll(); + } + catch(Exception e) + { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Fehler"); + alert.setHeaderText(""); + alert.setContentText("Beim L�schen des Eintrags ist ein Fehler aufgetreten."); + alert.initOwner(stage); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + e.printStackTrace(); + } + } + + public void deleteDB() + { + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("L�schen"); + alert.setHeaderText(""); + alert.setContentText("M�chten Sie die gesamte Datenbank wirklich unwiederruflich l�schen?"); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + + Optional<ButtonType> result = alert.showAndWait(); + if(result.get() == ButtonType.OK) + { + try + { + sql.deleteDB(); + sql.createDB(); + loadAll(); + } + catch(Exception e) + { + Alert alert2 = new Alert(AlertType.ERROR); + alert2.setTitle("Fehler"); + alert2.setHeaderText(""); + alert2.setContentText("Beim L�schen der Datenbank ist ein Fehler aufgetreten."); + alert2.initOwner(stage); + Stage dialogStage2 = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage2.getIcons().add(icon); + alert2.showAndWait(); + e.printStackTrace(); + } + } + } + + public void about() + { + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle("�ber " + bundle.getString("app.name")); + alert.setHeaderText(bundle.getString("app.name")); + alert.setContentText("Version: " + bundle.getString("version.name") + "\r\nDatum: " + bundle.getString("version.date") + "\r\nAutor: Robert Goldmann\r\n"); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + alert.showAndWait(); + } +} \ No newline at end of file diff --git a/src/userInterface/_de.properties b/src/userInterface/_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..901dfe290c66fe57681714c14a4f44b0aa1f5d01 --- /dev/null +++ b/src/userInterface/_de.properties @@ -0,0 +1,4 @@ +app.name=SmartTime +version.code=28 +version.name=5.0.2 +version.date=04.02.16 \ No newline at end of file diff --git a/src/userInterface/application.css b/src/userInterface/application.css new file mode 100644 index 0000000000000000000000000000000000000000..f21a2f70c496c0b64289b9b8d67c1156ef9882b3 --- /dev/null +++ b/src/userInterface/application.css @@ -0,0 +1,4 @@ +.combo-box { + -fx-font-family: "Arial"; + -fx-font-size: 18px; +} diff --git a/src/userInterface/editGUI.fxml b/src/userInterface/editGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..414f412407a6c1e10b7e89f584786585bae36290 --- /dev/null +++ b/src/userInterface/editGUI.fxml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="455.0" stylesheets="@../../class/userInterface/application.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.EditController"> + <children> + <Button layoutX="66.0" layoutY="221.0" mnemonicParsing="false" onAction="#okButton" prefWidth="92.0" text="OK"> + <font> + <Font size="14.0" /> + </font> + </Button> + <Button fx:id="abbrechenButton" layoutX="298.0" layoutY="221.0" mnemonicParsing="false" onAction="#abbrechenButtond" prefHeight="30.0" prefWidth="92.0" text="Abbrechen"> + <font> + <Font size="14.0" /> + </font> + </Button> + <ComboBox fx:id="dropdown" editable="true" layoutX="144.0" layoutY="63.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + <Label layoutX="34.0" layoutY="65.0" text="Projekt:"> + <font> + <Font name="System Bold" size="22.0" /> + </font> + </Label> + <Label layoutX="60.0" layoutY="132.0" text="Task:"> + <font> + <Font name="System Bold" size="21.0" /> + </font> + </Label> + <ComboBox fx:id="dropdownTasks" editable="true" layoutX="144.0" layoutY="128.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + <Button layoutX="183.0" layoutY="221.0" mnemonicParsing="false" onAction="#buttonDelete" prefHeight="30.0" prefWidth="92.0" text="Löschen"> + <font> + <Font size="14.0" /> + </font> + </Button> + </children> +</AnchorPane> diff --git a/src/userInterface/icon.png b/src/userInterface/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..adda60842424d26b524d45e0e0b169cddb0855bc Binary files /dev/null and b/src/userInterface/icon.png differ diff --git a/src/userInterface/projektFenster.fxml b/src/userInterface/projektFenster.fxml new file mode 100644 index 0000000000000000000000000000000000000000..ffe339d64a6ee3e9349ac76c07a7daccad40bb75 --- /dev/null +++ b/src/userInterface/projektFenster.fxml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="455.0" stylesheets="@../../class/userInterface/application.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.ProjektFensterController"> + <children> + <Button layoutX="109.0" layoutY="223.0" mnemonicParsing="false" onAction="#okButton" prefWidth="100.0" text="OK"> + <font> + <Font size="16.0" /> + </font> + </Button> + <Button fx:id="abbrechenButton" layoutX="253.0" layoutY="223.0" mnemonicParsing="false" onAction="#abbrechenButtond" prefWidth="100.0" text="Abbrechen"> + <font> + <Font size="16.0" /> + </font> + </Button> + <ComboBox fx:id="dropdown" editable="true" layoutX="144.0" layoutY="63.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + <Label layoutX="34.0" layoutY="65.0" text="Projekt:"> + <font> + <Font name="System Bold" size="22.0" /> + </font> + </Label> + <Label layoutX="60.0" layoutY="132.0" text="Task:"> + <font> + <Font name="System Bold" size="21.0" /> + </font> + </Label> + <ComboBox fx:id="dropdownTasks" editable="true" layoutX="144.0" layoutY="128.0" prefHeight="37.0" prefWidth="258.0" visibleRowCount="7" /> + </children> +</AnchorPane> diff --git a/src/userInterface/userInterface.fxml b/src/userInterface/userInterface.fxml new file mode 100644 index 0000000000000000000000000000000000000000..7cb9dce06cd26e597f9fd983aa193e1e6fe96c3a --- /dev/null +++ b/src/userInterface/userInterface.fxml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Accordion?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.Menu?> +<?import javafx.scene.control.MenuBar?> +<?import javafx.scene.control.MenuItem?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.control.TableView?> +<?import javafx.scene.control.TitledPane?> +<?import javafx.scene.control.ToggleButton?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.Pane?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.shape.Line?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.UserInterfaceController"> + <children> + <VBox layoutX="143.0" layoutY="69.0" prefHeight="800.0" prefWidth="650.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> + <children> + <MenuBar> + <menus> + <Menu mnemonicParsing="false" text="Datei"> + <items> + <MenuItem mnemonicParsing="false" onAction="#insertTime" text="Zeit nachträglich einfügen" /> + <MenuItem mnemonicParsing="false" onAction="#deleteDB" text="Datenbank löschen" /> + </items></Menu> + <Menu mnemonicParsing="false" text="Import"> + <items> + <MenuItem mnemonicParsing="false" onAction="#importFromSmartTime" text="von SmartTime bis Version 4.5.0" /> + <MenuItem mnemonicParsing="false" onAction="#importFromDB" text="von SmartTime Datenbank" /> + <MenuItem mnemonicParsing="false" onAction="#importFromJSON" text="von JSON" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="Export"> + <items> + <MenuItem mnemonicParsing="false" onAction="#exportAsDB" text="als SmartTime Datenbank" /> + <MenuItem mnemonicParsing="false" onAction="#exportAsJSON" text="als JSON" /> + </items> + </Menu> + <Menu mnemonicParsing="false" text="?"> + <items> + <MenuItem mnemonicParsing="false" onAction="#about" text="Über" /> + </items> + </Menu> + </menus> + </MenuBar> + <Pane prefHeight="121.0" prefWidth="650.0"> + <children> + <Label layoutX="48.0" layoutY="25.0" text="aktuelles Projekt:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label layoutX="48.0" layoutY="73.0" text="aktuelle Aufgabe:"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Button layoutX="613.0" layoutY="67.0" mnemonicParsing="false" onAction="#openProjectGUI" prefHeight="39.0" prefWidth="107.0" text="Ändern"> + <font> + <Font size="16.0" /> + </font> + </Button> + <Label fx:id="aktuellesProjektAusgabe" layoutX="239.0" layoutY="25.0" text=" "> + <font> + <Font size="18.0" /> + </font> + </Label> + <Label fx:id="aktuellerTaskAusgabe" layoutX="239.0" layoutY="73.0" text=" "> + <font> + <Font size="18.0" /> + </font> + </Label> + </children> + </Pane> + <Line endX="790.0" fill="BLACK" stroke="#cdc6c6" strokeWidth="1.5" translateX="5.0"> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </Line> + <Pane prefHeight="100.0" prefWidth="652.0"> + <children> + <ToggleButton fx:id="startButton" layoutX="49.0" layoutY="23.0" mnemonicParsing="false" prefHeight="49.0" prefWidth="116.0" text="Start"> + <font> + <Font size="16.0" /> + </font> + </ToggleButton> + <Label fx:id="labelTime" layoutX="240.0" layoutY="23.0" prefHeight="49.0" prefWidth="326.0" text=" "> + <font> + <Font name="Arial" size="28.0" /> + </font> + </Label> + <Button layoutX="614.0" layoutY="30.0" mnemonicParsing="false" onAction="#charts" prefHeight="40.0" prefWidth="107.0" text="Diagramme"> + <font> + <Font size="15.0" /> + </font> + </Button> + </children> + </Pane> + <Accordion fx:id="accordion" prefHeight="516.0" prefWidth="652.0"> + <panes> + <TitledPane fx:id="Projekte" animated="false" minHeight="250.0" prefHeight="283.0" prefWidth="652.0" text="Projekte gesamt"> + <content> + <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="650.0" /> + </content> + <font> + <Font size="14.0" /> + </font> + </TitledPane> + <TitledPane fx:id="gesamtesLog" animated="false" text="letzte Aktivitäten"> + <content> + <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> + <children> + <ScrollPane fx:id="scrollPane" layoutX="11.199999809265137" layoutY="11.199999809265137" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> + <content> + <TableView fx:id="table" prefHeight="430.0" prefWidth="784.0" /> + </content> + </ScrollPane> + </children></AnchorPane> + </content> + <font> + <Font size="14.0" /> + </font> + </TitledPane> + </panes> + </Accordion> + </children> + </VBox> + </children> +</AnchorPane>