diff --git a/.classpath b/.classpath deleted file mode 100644 index f23826173add7f3f88b8ef7616a953d76408e784..0000000000000000000000000000000000000000 --- a/.classpath +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" output="target/classes" path="src"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" path="tests"/> - <classpathentry combineaccessrules="false" kind="src" path="/_Tools"/> - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> - <classpathentry kind="output" path="target/classes"/> -</classpath> diff --git a/.gitignore b/.gitignore index ba528a19ef3303cd80651c649f8f6fcedbeeb108..ae91f72929d3edca467a68702753e6a8bdcebe87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ bin/ target/ -certs/ \ No newline at end of file +certs/ + +build/[0-9]*.[0-9]*.[0-9]* \ No newline at end of file diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c0203a7844de00dbfc56e6a35d8ed3c022c..0000000000000000000000000000000000000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/<project>=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 672496e107ed4e070613aad776b4df5146306bd4..0000000000000000000000000000000000000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -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.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/BudgetMasterClient/.classpath b/BudgetMasterClient/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..8e795b1c7e0c65a33e55e6a4fe23c4a11dd9e703 --- /dev/null +++ b/BudgetMasterClient/.classpath @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/BudgetMasterClient/.project b/BudgetMasterClient/.project new file mode 100644 index 0000000000000000000000000000000000000000..1142662018334c939d816c36e78b4bcc114b2114 --- /dev/null +++ b/BudgetMasterClient/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>BudgetMasterClient</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + </natures> +</projectDescription> diff --git a/BudgetMasterClient/.settings/org.eclipse.jdt.core.prefs b/BudgetMasterClient/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..714351aec195a9a572640e6844dcafd51565a2a5 --- /dev/null +++ b/BudgetMasterClient/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.m2e.core.prefs b/BudgetMasterClient/.settings/org.eclipse.m2e.core.prefs similarity index 100% rename from .settings/org.eclipse.m2e.core.prefs rename to BudgetMasterClient/.settings/org.eclipse.m2e.core.prefs diff --git a/BudgetMasterClient/pom.xml b/BudgetMasterClient/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..0fd1b201a4cdfd1bc86058a0aba07acd18e5f381 --- /dev/null +++ b/BudgetMasterClient/pom.xml @@ -0,0 +1,111 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>de.deadlocker8</groupId> + <artifactId>BudgetMasterClient</artifactId> + <version>1.6.0</version> + <name>BudgetMasterClient</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.7.0</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <!-- LAUNCH4J --> + <plugin> + <groupId>com.akathist.maven.plugins.launch4j</groupId> + <artifactId>launch4j-maven-plugin</artifactId> + <version>1.7.21</version> + <executions> + <execution> + <id>l4j-clui</id> + <phase>package</phase> + <goals> + <goal>launch4j</goal> + </goals> + <configuration> + <headerType>gui</headerType> + <jar>../build/${project.version}/BudgetMasterClient-v${project.version}.jar</jar> + <outfile>../build/${project.version}/BudgetMasterClient-v${project.version}.exe</outfile> + <downloadUrl>http://java.com/download</downloadUrl> + <classPath> + <mainClass>de.deadlocker8.budgetmasterclient.main.Main</mainClass> + </classPath> + <jre> + <bundledJre64Bit>false</bundledJre64Bit> + <bundledJreAsFallback>false</bundledJreAsFallback> + <minVersion>1.8.0</minVersion> + <jdkPreference>preferJre</jdkPreference> + <runtimeBits>64/32</runtimeBits> + </jre> + <icon>../build/icon.ico</icon> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <outputDirectory>../build/${project.version}</outputDirectory> + <finalName>BudgetMasterClient-v${project.version}</finalName> + <appendAssemblyId>false</appendAssemblyId> + <archive> + <manifest> + <mainClass>de.deadlocker8.budgetmasterclient.main.Main</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <id>make-assembly</id> <!-- this is used for inheritance merges --> + <phase>package</phase> <!-- bind to the packaging phase --> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>2.9.7</version> + </dependency> + <dependency> + <groupId>de.deadlocker8</groupId> + <artifactId>BudgetMasterCore</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>com.itextpdf</groupId> + <artifactId>itextpdf</artifactId> + <version>5.0.6</version> + </dependency> + <dependency> + <groupId>org.controlsfx</groupId> + <artifactId>controlsfx</artifactId> + <version>8.40.12</version> + </dependency> + <dependency> + <groupId>de.deadlocker8</groupId> + <artifactId>tools</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/main/Main.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/main/Main.java similarity index 50% rename from src/de/deadlocker8/budgetmaster/main/Main.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/main/Main.java index 68dec6f3fa6cff1e32a8786b3672fac7afe95529..0931c1111789c583f1a412046d00c46919277132 100644 --- a/src/de/deadlocker8/budgetmaster/main/Main.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/main/Main.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.main; +package de.deadlocker8.budgetmasterclient.main; import java.io.File; import java.util.Locale; @@ -6,11 +6,8 @@ import java.util.Locale; import de.deadlocker8.budgetmaster.logic.Settings; import de.deadlocker8.budgetmaster.logic.utils.FileHelper; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.controller.SplashScreenController; +import de.deadlocker8.budgetmasterclient.ui.controller.SplashScreenController; import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; import logger.FileOutputMode; @@ -21,60 +18,38 @@ import tools.PathUtils; public class Main extends Application { public static Stage primaryStage; - + @Override public void start(Stage stage) { primaryStage = stage; - - //load correct language + + // load correct language Settings settings = FileHelper.loadSettings(); if(settings != null && settings.getLanguage() != null) { Localization.loadLanguage(settings.getLanguage().getLocale()); } - - try - { - Image icon = new Image("/de/deadlocker8/budgetmaster/resources/icon.png"); - FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml")); - loader.setResources(Localization.getBundle()); - Parent root = (Parent)loader.load(); - - Scene scene = new Scene(root, 450, 230); - ((SplashScreenController)loader.getController()).init(stage, icon, getParameters().getNamed().get("update") != null); - - stage.setResizable(false); - stage.getIcons().add(icon); - stage.setTitle(Localization.getString(Strings.APP_NAME)); - stage.setScene(scene); - stage.show(); - } - catch(Exception e) - { - Logger.error(e); - } + Image icon = new Image("/de/deadlocker8/budgetmaster/icon.png"); + new SplashScreenController(stage, icon, getParameters().getNamed().get("update") != null); } @Override public void init() throws Exception { - Localization.init("de/deadlocker8/budgetmaster/resources/languages/"); + Localization.init("de/deadlocker8/budgetmaster/languages/"); Localization.loadLanguage(Locale.ENGLISH); - + Parameters params = getParameters(); String logLevelParam = params.getNamed().get("loglevel"); Logger.setLevel(logLevelParam); - + File logFolder = new File(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER)); PathUtils.checkFolder(logFolder); Logger.enableFileOutput(logFolder, System.out, System.err, FileOutputMode.COMBINED); - Logger.appInfo(Localization.getString(Strings.APP_NAME), - Localization.getString(Strings.VERSION_NAME), - Localization.getString(Strings.VERSION_CODE), - Localization.getString(Strings.VERSION_DATE)); + Logger.appInfo(Localization.getString(Strings.APP_NAME), Localization.getString(Strings.VERSION_NAME), Localization.getString(Strings.VERSION_CODE), Localization.getString(Strings.VERSION_DATE)); } public static void main(String[] args) diff --git a/src/de/deadlocker8/budgetmaster/ui/Refreshable.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/Refreshable.java similarity index 52% rename from src/de/deadlocker8/budgetmaster/ui/Refreshable.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/Refreshable.java index 763856fcdde5bf6b7b2534bca34aa06d745dfe08..0553784baa98791f79d47d486fa50ce1401e3b62 100644 --- a/src/de/deadlocker8/budgetmaster/ui/Refreshable.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/Refreshable.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui; +package de.deadlocker8.budgetmasterclient.ui; public interface Refreshable { diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/Styleable.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/Styleable.java new file mode 100644 index 0000000000000000000000000000000000000000..693e63a97830639711e1c774382b32f2b4ad46f9 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/Styleable.java @@ -0,0 +1,6 @@ +package de.deadlocker8.budgetmasterclient.ui; + +public interface Styleable +{ + public void applyStyle(); +} diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/ButtonCategoryCell.java similarity index 91% rename from src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/ButtonCategoryCell.java index 1158ed1c078ea8c2b04c8feaab89b94a0c301ce6..dc6394c3ab4170de143990ed19f2f115c110386a 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/ButtonCategoryCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/ButtonCategoryCell.java @@ -1,6 +1,6 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/CategoryBudgetCell.java similarity index 91% rename from src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/CategoryBudgetCell.java index 207c868f65d88c321397e0bedca1f5ea6c2abf87..b72a3c43c154271fdad1b8d3246f9d337ac53a21 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/CategoryBudgetCell.java @@ -1,9 +1,9 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.category.CategoryBudget; import de.deadlocker8.budgetmaster.logic.utils.Helpers; -import de.deadlocker8.budgetmaster.ui.controller.HomeController; +import de.deadlocker8.budgetmasterclient.ui.controller.HomeController; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/CategoryCell.java similarity index 95% rename from src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/CategoryCell.java index 9e80a8bf73ff7edbf3d06c292cf7bba5969db41a..908c651ebf7e790a02e610907a1f19f498b29c7b 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/CategoryCell.java @@ -1,11 +1,11 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; import java.util.Optional; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.controller.CategoryController; +import de.deadlocker8.budgetmasterclient.ui.controller.CategoryController; import fontAwesome.FontIconType; import javafx.geometry.Insets; import javafx.geometry.Pos; diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/LanguageCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/LanguageCell.java similarity index 90% rename from src/de/deadlocker8/budgetmaster/ui/cells/LanguageCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/LanguageCell.java index d7da4df94a8325a5aee359f03de9d46f5cac5c69..a798301141339e64a98d2a899f88ef523ff9bede 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/LanguageCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/LanguageCell.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; import de.deadlocker8.budgetmaster.logic.utils.LanguageType; import javafx.geometry.Insets; @@ -28,7 +28,7 @@ public class LanguageCell extends ListCell<LanguageType> { HBox hbox = new HBox(); - Image image = new Image("de/deadlocker8/budgetmaster/resources/flags/" + item.getIconName() + ".png"); + Image image = new Image("de/deadlocker8/budgetmaster/flags/" + item.getIconName() + ".png"); ImageView imageView = new ImageView(image); imageView.setFitWidth(HEIGHT); imageView.setFitHeight(HEIGHT); diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/PaymentCell.java similarity index 61% rename from src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/PaymentCell.java index 2fcb0e413f099020171e66e81940291d0e4f37eb..6219baf6ba69c2689393c6ba768729efd08d6d54 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/PaymentCell.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; import java.text.DateFormat; import java.text.ParseException; @@ -6,35 +6,44 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Optional; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.Payment; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.controller.PaymentController; +import de.deadlocker8.budgetmasterclient.ui.controller.PaymentController; import fontAwesome.FontIconType; +import javafx.animation.FadeTransition; import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.scene.Node; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.ButtonBar.ButtonData; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.Tooltip; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Stage; +import javafx.util.Duration; import logger.Logger; import tools.ConvertTo; import tools.Localization; public class PaymentCell extends ListCell<Payment> { - private final double HEIGHT = 40.0; + private final double HEIGHT = 30.0; private PaymentController paymentController; public PaymentCell(PaymentController paymentController) @@ -70,21 +79,21 @@ public class PaymentCell extends ListCell<Payment> labelDate.setPrefHeight(HEIGHT); labelDate.setAlignment(Pos.CENTER); labelDate.getStyleClass().add("greylabel"); - labelDate.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121"); - labelDate.setMinWidth(75); + labelDate.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121"); + labelDate.setMinWidth(60); hbox.getChildren().add(labelDate); Label labelRepeating = new Label(); if(item instanceof RepeatingPaymentEntry) { - labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 20, Color.web("#212121"))); + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 18, Color.web("#212121"))); } else { - labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 20, Color.TRANSPARENT)); + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 18, Color.TRANSPARENT)); } labelRepeating.setPrefHeight(HEIGHT); - labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121"); + labelRepeating.setStyle("-fx-font-size: 15; -fx-text-fill: #212121"); labelRepeating.setAlignment(Pos.CENTER); labelRepeating.getStyleClass().add("greylabel"); hbox.getChildren().add(labelRepeating); @@ -96,19 +105,34 @@ public class PaymentCell extends ListCell<Payment> labelCircle.setAlignment(Pos.CENTER); labelCircle.getStyleClass().add("greylabel"); String textColor = ConvertTo.toRGBHex(ConvertTo.getAppropriateTextColor(Color.web(category.getColor()))); - labelCircle.setStyle("-fx-background-color: " + category.getColor() + "; -fx-background-radius: 50%; -fx-text-fill: " + textColor + "; -fx-font-weight: bold; -fx-font-size: 20;"); + labelCircle.setStyle("-fx-background-color: " + category.getColor() + "; -fx-background-radius: 50%; -fx-text-fill: " + textColor + "; -fx-font-weight: bold; -fx-font-size: 18;"); Tooltip tooltip = new Tooltip(category.getName()); tooltip.setStyle("-fx-font-size: 14"); labelCircle.setTooltip(tooltip); - hbox.getChildren().add(labelCircle); + hbox.getChildren().add(labelCircle); + + VBox vboxNameAndDescription = new VBox(); + vboxNameAndDescription.setSpacing(2); + vboxNameAndDescription.setAlignment(Pos.CENTER_LEFT); + vboxNameAndDescription.setMinHeight(HEIGHT + 12); - Label labelName = new Label(item.getName()); - labelName.setPrefHeight(HEIGHT); - labelName.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121"); - labelName.setAlignment(Pos.CENTER); - labelName.getStyleClass().add("greylabel"); - hbox.getChildren().add(labelName); - HBox.setMargin(labelName, new Insets(0, 0, 0, 20)); + Label labelName = new Label(item.getName()); + labelName.setStyle("-fx-font-size: 15; -fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelName.setAlignment(Pos.CENTER_LEFT); + labelName.getStyleClass().add("greylabel"); + vboxNameAndDescription.getChildren().add(labelName); + + if(item.getDescription() != null && !item.getDescription().equals("")) + { + Label labelDescription = new Label(Helpers.getFlatText(item.getDescription())); + labelDescription.setStyle("-fx-font-size: 14; -fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-style: italic"); + labelDescription.setAlignment(Pos.CENTER_LEFT); + labelDescription.getStyleClass().add("greylabel"); + vboxNameAndDescription.getChildren().add(labelDescription); + } + + hbox.getChildren().add(vboxNameAndDescription); + HBox.setMargin(vboxNameAndDescription, new Insets(0, 0, 0, 20)); Region r = new Region(); hbox.getChildren().add(r); @@ -116,7 +140,7 @@ public class PaymentCell extends ListCell<Payment> Label labelBudget = new Label(Helpers.getCurrencyString(item.getAmount(), paymentController.getController().getSettings().getCurrency())); labelBudget.setPrefHeight(HEIGHT); - labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #247A2D"); + labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #247A2D"); labelBudget.setAlignment(Pos.CENTER); labelBudget.getStyleClass().add("greylabel"); labelBudget.setMinWidth(90); @@ -130,9 +154,9 @@ public class PaymentCell extends ListCell<Payment> else { labelBudget.setText(labelBudget.getText()); - labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #CC0000"); + labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #CC0000"); } - + Button buttonDelete = new Button(); buttonDelete.setGraphic(Helpers.getFontIcon(FontIconType.TRASH, 16, Color.web("#212121"))); buttonDelete.setPrefHeight(HEIGHT); @@ -156,6 +180,14 @@ public class PaymentCell extends ListCell<Payment> ButtonType buttonTypeCancel = new ButtonType(Localization.getString(Strings.CANCEL), ButtonData.CANCEL_CLOSE); alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeCancel); + + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getButtonTypes().stream().map(dialogPane::lookupButton).forEach(button -> button.addEventHandler(KeyEvent.KEY_PRESSED, (e) -> { + if(KeyCode.ENTER.equals(e.getCode()) && e.getTarget() instanceof Button) + { + ((Button)e.getTarget()).fire(); + } + })); Optional<ButtonType> result = alert.showAndWait(); if(result.get() == buttonTypeOne) @@ -185,6 +217,13 @@ public class PaymentCell extends ListCell<Payment> } hbox.setPadding(new Insets(10, 8, 10, 5)); + + // payment is selected after search + Payment selectedPayment = paymentController.getController().getSelectedPayment(); + selectPayment(selectedPayment, item, hbox); + + hbox.setPadding(new Insets(8, 8, 8, 5)); + hbox.setAlignment(Pos.CENTER_LEFT); setStyle("-fx-background: transparent; -fx-border-color: #545454; -fx-border-width: 0 0 1 0"); setGraphic(hbox); setAlignment(Pos.CENTER); @@ -196,4 +235,51 @@ public class PaymentCell extends ListCell<Payment> setGraphic(null); } } + + private void selectPayment(Payment selectedPayment, Payment item, Node noteToFade) + { + if(selectedPayment == null) + return; + + if(selectedPayment instanceof NormalPayment) + { + if(item instanceof NormalPayment) + { + if(item.getID() != selectedPayment.getID()) + { + return; + } + } + else + { + return; + } + } + + if(selectedPayment instanceof RepeatingPayment) + { + if(item instanceof RepeatingPaymentEntry) + { + RepeatingPaymentEntry itemRepeating = (RepeatingPaymentEntry)item; + if(itemRepeating.getRepeatingPaymentID() != selectedPayment.getID()) + { + return; + } + } + else + { + return; + } + } + + FadeTransition ft = new FadeTransition(Duration.millis(750), noteToFade); + ft.setFromValue(1.0); + ft.setToValue(0.0); + ft.setCycleCount(4); + ft.setAutoReverse(true); + ft.play(); + ft.setOnFinished((event)->{ + paymentController.getController().setSelectedPayment(null); + }); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/RepeatingDayCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/RepeatingDayCell.java similarity index 85% rename from src/de/deadlocker8/budgetmaster/ui/cells/RepeatingDayCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/RepeatingDayCell.java index 2a32ee4bac775591b1f82cedc5c5bbf4446bcbdd..4a811dab12fe392be39b877b9400a24902fd03ad 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/RepeatingDayCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/RepeatingDayCell.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; import javafx.scene.control.ListCell; diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/SearchCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/SearchCell.java new file mode 100644 index 0000000000000000000000000000000000000000..a639e3f8c343cd0f825d81aa7f2fdf2a70de938a --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/SearchCell.java @@ -0,0 +1,175 @@ +package de.deadlocker8.budgetmasterclient.ui.cells; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmasterclient.ui.controller.SearchController; +import fontAwesome.FontIconType; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import logger.Logger; +import tools.ConvertTo; + +public class SearchCell extends ListCell<Payment> +{ + private final double HEIGHT = 30.0; + private SearchController searchController; + + public SearchCell(SearchController searchController) + { + super(); + this.searchController = searchController; + } + + @Override + protected void updateItem(Payment item, boolean empty) + { + super.updateItem(item, empty); + + if(!empty) + { + Category category = searchController.getController().getCategoryHandler().getCategory(item.getCategoryID()); + + HBox hbox = new HBox(); + + String dateString = item.getDate(); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try + { + Date date = format.parse(dateString); + DateFormat finalFormat = new SimpleDateFormat("dd.MM.yy"); + dateString = finalFormat.format(date); + } + catch(ParseException e) + { + Logger.error(e); + } + Label labelDate = new Label(dateString); + labelDate.setPrefHeight(HEIGHT); + labelDate.setAlignment(Pos.CENTER); + labelDate.getStyleClass().add("greylabel"); + labelDate.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121"); + labelDate.setMinWidth(60); + hbox.getChildren().add(labelDate); + + Label labelRepeating = new Label(); + if(item instanceof RepeatingPayment) + { + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 18, Color.web("#212121"))); + } + else + { + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 18, Color.TRANSPARENT)); + } + labelRepeating.setPrefHeight(HEIGHT); + labelRepeating.setStyle("-fx-font-size: 15; -fx-text-fill: #212121"); + labelRepeating.setAlignment(Pos.CENTER); + labelRepeating.getStyleClass().add("greylabel"); + hbox.getChildren().add(labelRepeating); + HBox.setMargin(labelRepeating, new Insets(0, 20, 0, 15)); + + Label labelCircle = new Label(category.getName().substring(0, 1).toUpperCase()); + labelCircle.setMinWidth(HEIGHT); + labelCircle.setMinHeight(HEIGHT); + labelCircle.setAlignment(Pos.CENTER); + labelCircle.getStyleClass().add("greylabel"); + String textColor = ConvertTo.toRGBHex(ConvertTo.getAppropriateTextColor(Color.web(category.getColor()))); + labelCircle.setStyle("-fx-background-color: " + category.getColor() + "; -fx-background-radius: 50%; -fx-text-fill: " + textColor + "; -fx-font-weight: bold; -fx-font-size: 18;"); + Tooltip tooltip = new Tooltip(category.getName()); + tooltip.setStyle("-fx-font-size: 14"); + labelCircle.setTooltip(tooltip); + hbox.getChildren().add(labelCircle); + + VBox vboxNameAndDescription = new VBox(); + vboxNameAndDescription.setSpacing(2); + vboxNameAndDescription.setAlignment(Pos.CENTER_LEFT); + vboxNameAndDescription.setMinHeight(HEIGHT + 12); + + Label labelName = new Label(item.getName()); + labelName.setStyle("-fx-font-size: 15; -fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelName.setAlignment(Pos.CENTER_LEFT); + labelName.getStyleClass().add("greylabel"); + vboxNameAndDescription.getChildren().add(labelName); + + if(item.getDescription() != null && !item.getDescription().equals("")) + { + Label labelDescription = new Label(Helpers.getFlatText(item.getDescription())); + labelDescription.setStyle("-fx-font-size: 14; -fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-style: italic"); + labelDescription.setAlignment(Pos.CENTER_LEFT); + labelDescription.getStyleClass().add("greylabel"); + vboxNameAndDescription.getChildren().add(labelDescription); + } + + hbox.getChildren().add(vboxNameAndDescription); + HBox.setMargin(vboxNameAndDescription, new Insets(0, 0, 0, 20)); + + Region r = new Region(); + hbox.getChildren().add(r); + HBox.setHgrow(r, Priority.ALWAYS); + + Label labelBudget = new Label(Helpers.getCurrencyString(item.getAmount(), searchController.getController().getSettings().getCurrency())); + labelBudget.setPrefHeight(HEIGHT); + labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #247A2D"); + labelBudget.setAlignment(Pos.CENTER); + labelBudget.getStyleClass().add("greylabel"); + labelBudget.setMinWidth(90); + hbox.getChildren().add(labelBudget); + HBox.setMargin(labelBudget, new Insets(0, 0, 0, 20)); + + if(item.isIncome()) + { + labelBudget.setText("+" + labelBudget.getText()); + } + else + { + labelBudget.setText(labelBudget.getText()); + labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #CC0000"); + } + + Button buttonGoto = new Button(); + buttonGoto.setGraphic(Helpers.getFontIcon(FontIconType.EXTERNAL_LINK_SQUARE, 16, Color.web("#212121"))); + buttonGoto.setPrefHeight(HEIGHT); + buttonGoto.getStyleClass().add("greylabel"); + buttonGoto.setStyle("-fx-background-color: transparent"); + buttonGoto.setOnAction((event) -> { + DateTime newDate = DateTime.parse(item.getDate(), DateTimeFormat.forPattern("YYYY-MM-dd")); + searchController.getController().setSelectedPayment(item); + searchController.getController().setDate(newDate); + searchController.cancel(); + }); + hbox.getChildren().add(buttonGoto); + HBox.setMargin(buttonGoto, new Insets(0, 0, 0, 10)); + + hbox.setPadding(new Insets(8, 8, 8, 5)); + hbox.setAlignment(Pos.CENTER_LEFT); + setStyle("-fx-background: transparent; -fx-border-color: #545454; -fx-border-width: 0 0 1 0"); + setGraphic(hbox); + setAlignment(Pos.CENTER); + } + else + { + setStyle("-fx-background: transparent"); + setText(null); + setGraphic(null); + } + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/SmallCategoryCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/SmallCategoryCell.java similarity index 93% rename from src/de/deadlocker8/budgetmaster/ui/cells/SmallCategoryCell.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/SmallCategoryCell.java index dba566d87328ed7005f923e258acc8f3e8b06556..ad70f8c2b2d9542df7f526bbf41558fe1b4a1a6a 100644 --- a/src/de/deadlocker8/budgetmaster/ui/cells/SmallCategoryCell.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/SmallCategoryCell.java @@ -1,6 +1,6 @@ -package de.deadlocker8.budgetmaster.ui.cells; +package de.deadlocker8.budgetmasterclient.ui.cells; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/report/table/ReportTableRatingCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/report/table/ReportTableRatingCell.java new file mode 100644 index 0000000000000000000000000000000000000000..3131ef8d89a920fc03653f9305a2bd6bb3e24db6 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/report/table/ReportTableRatingCell.java @@ -0,0 +1,36 @@ +package de.deadlocker8.budgetmasterclient.ui.cells.report.table; + +import de.deadlocker8.budgetmaster.logic.report.ReportItem; +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import fontAwesome.FontIconType; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; + +public class ReportTableRatingCell extends TableCell<ReportItem, Integer> +{ + @Override + protected void updateItem(Integer item, boolean empty) + { + if(!empty) + { + Label labelRepeating = new Label(); + if(item > 0) + { + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.PLUS, 14, Colors.TEXT)); + } + else + { + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.MINUS, 14, Colors.TEXT)); + } + labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121"); + labelRepeating.setAlignment(Pos.CENTER); + setGraphic(labelRepeating); + } + else + { + setGraphic(null); + } + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/report/table/ReportTableRepeatingCell.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/report/table/ReportTableRepeatingCell.java new file mode 100644 index 0000000000000000000000000000000000000000..c608583eca9323eeceaeed85077a76f8f3124f4b --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/cells/report/table/ReportTableRepeatingCell.java @@ -0,0 +1,37 @@ +package de.deadlocker8.budgetmasterclient.ui.cells.report.table; + +import de.deadlocker8.budgetmaster.logic.report.ReportItem; +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import fontAwesome.FontIconType; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.paint.Color; + +public class ReportTableRepeatingCell extends TableCell<ReportItem, Boolean> +{ + @Override + protected void updateItem(Boolean item, boolean empty) + { + if(!empty) + { + Label labelRepeating = new Label(); + if(item) + { + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 16, Colors.TEXT)); + } + else + { + labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 16, Color.TRANSPARENT)); + } + labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121"); + labelRepeating.setAlignment(Pos.CENTER); + setGraphic(labelRepeating); + } + else + { + setGraphic(null); + } + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickController.java similarity index 98% rename from src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickController.java index ccda4ff2e78fe4c466b0e6633fa91e6e606d35f7..9b3fa2c26e32f6bc8fd18a8266b642343503b02c 100644 --- a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickController.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.colorPick; +package de.deadlocker8.budgetmasterclient.ui.colorPick; import java.util.function.Consumer; diff --git a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickGUI.fxml similarity index 100% rename from src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickGUI.fxml diff --git a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorView.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java similarity index 95% rename from src/de/deadlocker8/budgetmaster/ui/colorPick/ColorView.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java index 6e3d4f022ec3d41b1777a76deeaecf624cbaf6ed..7547dcc02c5057121f7ffd1f56c9d09061f40c5d 100644 --- a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorView.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java @@ -1,9 +1,9 @@ -package de.deadlocker8.budgetmaster.ui.colorPick; +package de.deadlocker8.budgetmasterclient.ui.colorPick; import java.util.ArrayList; import java.util.function.Consumer; -import de.deadlocker8.budgetmaster.ui.controller.NewCategoryController; +import de.deadlocker8.budgetmasterclient.ui.controller.NewCategoryController; import fontAwesome.FontIcon; import fontAwesome.FontIconType; import javafx.fxml.FXMLLoader; @@ -145,8 +145,8 @@ public class ColorView extends GridPane rectangle.getStyleClass().add("color-view-item"); // dotted border - if(color == startColor) - { + if(ConvertTo.toRGBHex(color).equals(ConvertTo.toRGBHex(startColor))) + { lastSelectedNode = rectangle; rectangle.getStrokeDashArray().add(3.0); } diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/BaseController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/BaseController.java new file mode 100644 index 0000000000000000000000000000000000000000..d55d410e1620af51f662415683d3bd475499c824 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/BaseController.java @@ -0,0 +1,54 @@ +package de.deadlocker8.budgetmasterclient.ui.controller; + +import java.io.IOException; +import java.util.ResourceBundle; + +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; +import logger.Logger; + +public class BaseController +{ + private Parent parent; + private Stage stage; + + public void load(String fxmlFileName, ResourceBundle resourceBundle) + { + try + { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(fxmlFileName)); + if(resourceBundle != null) + { + fxmlLoader.setResources(resourceBundle); + } + fxmlLoader.setController(this); + parent = (Parent)fxmlLoader.load(); + } + catch(IOException e) + { + Logger.error(e); + } + + createNewStage(); + initStage(stage); + init(); + } + + public Stage getStage() + { + return stage; + } + + public void createNewStage() + { + Scene scene = new Scene(parent); + stage = new Stage(); + stage.setScene(scene); + } + + public void initStage(Stage stage){}; + + public void init() {}; +} diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/CategoryController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/CategoryController.java new file mode 100644 index 0000000000000000000000000000000000000000..a4c587b2fceeecd418c2b72e82f8fedae0659b1f --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/CategoryController.java @@ -0,0 +1,126 @@ +package de.deadlocker8.budgetmasterclient.ui.controller; + + +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.CategoryCell; +import fontAwesome.FontIconType; +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.AnchorPane; +import javafx.scene.paint.Color; +import logger.Logger; +import tools.ConvertTo; +import tools.Localization; + +public class CategoryController extends BaseController implements Refreshable, Styleable +{ + @FXML private AnchorPane anchorPaneMain; + @FXML private Button buttonCategory; + @FXML private ListView<Category> listView; + + private Controller controller; + + public void init(Controller controller) + { + this.controller = controller; + + CategoryController thisController = this; + listView.setCellFactory(param -> { + CategoryCell cell = new CategoryCell(thisController); + cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> { + if(event.getClickCount() == 2) + { + // don't allow editing of category "none" + if(cell.getItem().getID() != 1) + { + newCategory(true, cell.getItem()); + } + } + }); + return cell; + }); + + listView.getSelectionModel().selectedIndexProperty().addListener((ChangeListener<Number>)(observable, oldValue, newValue) -> Platform.runLater(() -> listView.getSelectionModel().select(-1))); + + Label labelPlaceholder = new Label(Localization.getString(Strings.CATEGORIES_PLACEHOLDER)); + labelPlaceholder.setStyle("-fx-font-size: 16"); + listView.setPlaceholder(labelPlaceholder); + + applyStyle(); + + refreshListView(); + } + + public void refreshListView() + { + listView.getItems().clear(); + + if(controller.getCategoryHandler() != null) + { + ArrayList<Category> categories = controller.getCategoryHandler().getCategoriesWithoutNone(); + if(categories != null && categories.size() > 0) + { + listView.getItems().setAll(categories); + } + } + } + + public void createNewCategory() + { + newCategory(false, null); + } + + public void newCategory(boolean edit, Category category) + { + new NewCategoryController(controller.getStage(), controller, this, edit, category); + } + + public void deleteCategory(int ID) + { + try + { + ServerConnection connection = new ServerConnection(controller.getSettings()); + connection.deleteCategory(ID); + controller.refresh(controller.getFilterSettings()); + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); + } + } + + public Controller getController() + { + return controller; + } + + @Override + public void refresh() + { + refreshListView(); + } + + @Override + public void applyStyle() + { + buttonCategory.setGraphic(Helpers.getFontIcon(FontIconType.PLUS, 18, Color.WHITE)); + + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + buttonCategory.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ChartController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ChartController.java similarity index 82% rename from src/de/deadlocker8/budgetmaster/ui/controller/ChartController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ChartController.java index 8ae13536db2ccd8b2d37daa015a857f9ccc73f84..8ddc953455a4a15eb6bda5a23e34eb98b40f8454 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/ChartController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ChartController.java @@ -1,33 +1,31 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.io.File; -import java.io.IOException; import java.time.LocalDate; import java.util.ArrayList; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; -import de.deadlocker8.budgetmaster.logic.CategoryInOutSum; -import de.deadlocker8.budgetmaster.logic.MonthInOutSum; import de.deadlocker8.budgetmaster.logic.charts.CategoriesChart; +import de.deadlocker8.budgetmaster.logic.charts.CategoryInOutSum; import de.deadlocker8.budgetmaster.logic.charts.ChartExportable; import de.deadlocker8.budgetmaster.logic.charts.LegendType; import de.deadlocker8.budgetmaster.logic.charts.MonthBarChart; +import de.deadlocker8.budgetmaster.logic.charts.MonthInOutSum; import de.deadlocker8.budgetmaster.logic.charts.MonthLineChart; import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.utils.UIHelpers; import fontAwesome.FontIconType; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; import javafx.scene.control.Accordion; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; @@ -40,16 +38,14 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; -import javafx.stage.Modality; import javafx.stage.Stage; -import javafx.util.Callback; import logger.Logger; import tools.AlertGenerator; import tools.ConvertTo; import tools.Localization; import tools.Worker; -public class ChartController implements Refreshable +public class ChartController implements Refreshable, Styleable { @FXML private AnchorPane anchorPaneMain; @FXML private Accordion accordion; @@ -78,42 +74,18 @@ public class ChartController implements Refreshable public void init(Controller controller) { this.controller = controller; - - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - vboxChartCategories.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - vboxChartCategories.setSpacing(20); - vboxChartMonth.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - - buttonChartCategoriesShow.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); - buttonChartCategoriesShow.setGraphic(Helpers.getFontIcon(FontIconType.CHECK, 16, Color.WHITE)); - - buttonChartCategoriesExport.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); - buttonChartCategoriesExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 16, Color.WHITE)); - - buttonChartMonthShow.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); - buttonChartMonthShow.setGraphic(Helpers.getFontIcon(FontIconType.CHECK, 16, Color.WHITE)); - - buttonChartMonthExport.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); - buttonChartMonthExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 16, Color.WHITE)); - datePickerEnd.setDayCellFactory(new Callback<DatePicker, DateCell>() + datePickerEnd.setDayCellFactory(param -> new DateCell() { @Override - public DateCell call(DatePicker param) + public void updateItem(LocalDate item, boolean empty) { - return new DateCell() + super.updateItem(item, empty); + if(item.isBefore(datePickerStart.getValue().plusDays(1))) { - @Override - public void updateItem(LocalDate item, boolean empty) - { - super.updateItem(item, empty); - if(item.isBefore(datePickerStart.getValue().plusDays(1))) - { - setDisable(true); - setStyle("-fx-background-color: #ffc0cb;"); - } - } - }; + setDisable(true); + setStyle("-fx-background-color: #ffc0cb;"); + } } }); @@ -129,6 +101,8 @@ public class ChartController implements Refreshable accordion.setExpandedPane(accordion.getPanes().get(0)); vboxChartMonth.setSpacing(15); + + applyStyle(); } public void buttonChartCategoriesShow() @@ -195,26 +169,7 @@ public class ChartController implements Refreshable { Worker.runLater(() -> { Platform.runLater(() -> { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent root = (Parent)fxmlLoader.load(); - Stage newStage = new Stage(); - newStage.initOwner(controller.getStage()); - newStage.initModality(Modality.APPLICATION_MODAL); - newStage.setTitle(Localization.getString(Strings.TITLE_CHART_EXPORT)); - newStage.setScene(new Scene(root)); - newStage.getIcons().add(controller.getIcon()); - newStage.setResizable(false); - ExportChartController newController = fxmlLoader.getController(); - newController.init(newStage, this, chart); - newStage.show(); - } - catch(IOException e) - { - Logger.error(e); - } + new ExportChartController(controller.getStage(), this, chart); }); }); } @@ -231,10 +186,10 @@ public class ChartController implements Refreshable String endYear = comboBoxEndYear.getValue(); String startDateString = "01-" + startMonth + "-" + startYear; - DateTime startDate = DateTime.parse(startDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY")); + DateTime startDate = DateTime.parse(startDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY").withLocale(controller.getSettings().getLanguage().getLocale())); String endDateString = "01-" + endMonth + "-" + endYear; - DateTime endDate = DateTime.parse(endDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY")); + DateTime endDate = DateTime.parse(endDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY").withLocale(controller.getSettings().getLanguage().getLocale())); if(endDate.isBefore(startDate)) { @@ -275,7 +230,7 @@ public class ChartController implements Refreshable } } - public Controller getControlle() + public Controller getController() { return controller; } @@ -293,7 +248,7 @@ public class ChartController implements Refreshable @Override public void refresh() { - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_CHARTS), controller.getStage(), controller.getIcon()); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_CHARTS), controller.getStage(), controller.getIcon()); // prepare chart categories LocalDate startDate = LocalDate.parse(controller.getCurrentDate().withDayOfMonth(1).toString("yyyy-MM-dd")); @@ -303,10 +258,10 @@ public class ChartController implements Refreshable datePickerEnd.setValue(endDate); // chart month - comboBoxStartMonth.setValue(controller.getCurrentDate().minusMonths(5).toString("MMMM")); + comboBoxStartMonth.setValue(controller.getCurrentDate().minusMonths(5).monthOfYear().getAsText(controller.getSettings().getLanguage().getLocale())); comboBoxStartYear.setValue(String.valueOf(controller.getCurrentDate().minusMonths(5).getYear())); - comboBoxEndMonth.setValue(controller.getCurrentDate().plusMonths(6).toString("MMMM")); + comboBoxEndMonth.setValue(controller.getCurrentDate().plusMonths(6).monthOfYear().getAsText(controller.getSettings().getLanguage().getLocale())); comboBoxEndYear.setValue(String.valueOf(controller.getCurrentDate().plusMonths(6).getYear())); Worker.runLater(() -> { @@ -321,4 +276,25 @@ public class ChartController implements Refreshable }); }); } + + @Override + public void applyStyle() + { + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + vboxChartCategories.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + vboxChartCategories.setSpacing(20); + vboxChartMonth.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + + buttonChartCategoriesShow.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); + buttonChartCategoriesShow.setGraphic(Helpers.getFontIcon(FontIconType.CHECK, 16, Color.WHITE)); + + buttonChartCategoriesExport.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); + buttonChartCategoriesExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 16, Color.WHITE)); + + buttonChartMonthShow.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); + buttonChartMonthShow.setGraphic(Helpers.getFontIcon(FontIconType.CHECK, 16, Color.WHITE)); + + buttonChartMonthExport.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE)); + buttonChartMonthExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 16, Color.WHITE)); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/Controller.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java similarity index 68% rename from src/de/deadlocker8/budgetmaster/ui/controller/Controller.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java index 93f7f2c65fc81e03b0958586fc7b00ecf5674512..2dbef46aa9cf9d86e7ce49edd5f4bc4b52c886af 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/Controller.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.io.IOException; import java.util.ArrayList; @@ -6,19 +6,23 @@ import java.util.Optional; import org.joda.time.DateTime; -import de.deadlocker8.budgetmaster.logic.CategoryBudget; -import de.deadlocker8.budgetmaster.logic.CategoryHandler; import de.deadlocker8.budgetmaster.logic.FilterSettings; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.PaymentHandler; import de.deadlocker8.budgetmaster.logic.Settings; +import de.deadlocker8.budgetmaster.logic.category.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.category.CategoryHandler; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.PaymentHandler; +import de.deadlocker8.budgetmaster.logic.search.SearchPreferences; import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; +import de.deadlocker8.budgetmaster.logic.tag.TagHandler; import de.deadlocker8.budgetmaster.logic.updater.Updater; import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.utils.UIHelpers; import fontAwesome.FontIconType; import javafx.animation.FadeTransition; import javafx.animation.SequentialTransition; @@ -30,10 +34,13 @@ 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.DialogPane; import javafx.scene.control.Label; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.image.Image; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; import javafx.util.Duration; @@ -43,10 +50,10 @@ import tools.ConvertTo; import tools.Localization; import tools.Worker; -public class Controller +public class Controller extends BaseController { @FXML private AnchorPane anchorPaneMain; - @FXML private Label labelMonth; + @FXML private Button buttonDate; @FXML private Button buttonLeft; @FXML private Button buttonRight; @FXML private Button buttonToday; @@ -67,8 +74,7 @@ public class Controller private ReportController reportController; private SettingsController settingsController; - private Stage stage; - private Image icon = new Image("de/deadlocker8/budgetmaster/resources/icon.png"); + private Image icon = new Image("de/deadlocker8/budgetmaster/icon.png"); private Settings settings; private DateTime currentDate; private ArrayList<CategoryBudget> categoryBudgets; @@ -76,21 +82,42 @@ public class Controller private CategoryHandler categoryHandler; private FilterSettings filterSettings; private Updater updater; + private Payment selectedPayment; + private SearchPreferences searchPreferences; private boolean alertIsShowing = false; - - public void init(Stage stage, Settings settings) + private static final String DATE_FORMAT = "MMMM yyyy"; + + public Controller(Settings settings) { - this.stage = stage; - this.settings = settings; - - stage.setOnCloseRequest((event)->{ + this.settings = settings; + load("/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml", Localization.getBundle()); + getStage().show(); + } + + @Override + public void initStage(Stage stage) + { + stage.setTitle(Localization.getString(Strings.APP_NAME)); + stage.getIcons().add(icon); + stage.setResizable(true); + stage.setWidth(660); + stage.setHeight(725); + stage.setMinWidth(660); + stage.setMinHeight(650); + stage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css"); + } + + @Override + public void init() + { + getStage().setOnCloseRequest((event)->{ Worker.shutdown(); System.exit(0); }); currentDate = DateTime.now(); - labelMonth.setText(currentDate.toString("MMMM yyyy")); + buttonDate.setText(currentDate.toString(DATE_FORMAT)); filterSettings = new FilterSettings(); paymentHandler = new PaymentHandler(); @@ -104,37 +131,30 @@ public class Controller initUI(); } + private <T> T loadTab(String fileName, Tab tab) throws IOException + { + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(fileName)); + fxmlLoader.setResources(Localization.getBundle()); + Parent nodeTab = (Parent)fxmlLoader.load(); + tab.setContent(nodeTab); + return fxmlLoader.getController(); + } + private void initUI() { try { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent nodeTabHome = (Parent)fxmlLoader.load(); - homeController = fxmlLoader.getController(); - homeController.init(this); - tabHome.setContent(nodeTabHome); - - fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent nodeTabPayment = (Parent)fxmlLoader.load(); - paymentController = fxmlLoader.getController(); + homeController = loadTab("/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml", tabHome); + homeController.init(this); + + paymentController = loadTab("/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml", tabPayments); paymentController.init(this); - tabPayments.setContent(nodeTabPayment); - - fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent nodeTabCategory = (Parent)fxmlLoader.load(); - categoryController = fxmlLoader.getController(); + + categoryController = loadTab("/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml", tabCategories); categoryController.init(this); - tabCategories.setContent(nodeTabCategory); - - fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent nodeTabChart = (Parent)fxmlLoader.load(); - chartController = fxmlLoader.getController(); + + chartController = loadTab("/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml", tabCharts); chartController.init(this); - tabCharts.setContent(nodeTabChart); tabCharts.selectedProperty().addListener((a,b,c)->{ if(c) { @@ -142,48 +162,56 @@ public class Controller } }); - fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent nodeTabReport = (Parent)fxmlLoader.load(); - reportController = fxmlLoader.getController(); + reportController = loadTab("/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml", tabReports); reportController.init(this); - tabReports.setContent(nodeTabReport); - - fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent nodeTabSettings = (Parent)fxmlLoader.load(); - settingsController = fxmlLoader.getController(); - settingsController.init(this); - tabSettings.setContent(nodeTabSettings); + tabReports.selectedProperty().addListener((a,b,c)->{ + if(c) + { + reportController.refresh(); + } + }); + + settingsController = loadTab("/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml", tabSettings); + settingsController.init(this); } catch(IOException e) { Logger.error(e); Platform.runLater(() -> { - AlertGenerator.showAlert(AlertType.ERROR, Localization.getString(Strings.TITLE_ERROR), "", Localization.getString(Strings.ERROR_CREATE_UI), icon, stage, null, false); + AlertGenerator.showAlert(AlertType.ERROR, Localization.getString(Strings.TITLE_ERROR), "", Localization.getString(Strings.ERROR_CREATE_UI), icon, getStage(), null, false); }); } - buttonLeft.setGraphic(Helpers.getFontIcon(FontIconType.CHEVRON_LEFT, 20, Colors.TEXT)); + buttonLeft.setGraphic(Helpers.getFontIcon(FontIconType.CHEVRON_LEFT, 20, Colors.TEXT)); buttonRight.setGraphic(Helpers.getFontIcon(FontIconType.CHEVRON_RIGHT, 20, Colors.TEXT)); buttonToday.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR_ALT, 20, Colors.TEXT)); buttonAbout.setGraphic(Helpers.getFontIcon(FontIconType.INFO, 20, Colors.TEXT)); // apply theme anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_MAIN)); - labelMonth.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); labelNotification.setStyle("-fx-text-fill: #FFFFFF; -fx-font-size: 16; -fx-font-weight: bold; -fx-background-color: transparent;"); + + buttonDate.setStyle("-fx-padding: 0; -fx-background-color: transparent; -fx-font-weight: bold; -fx-font-size: 24; -fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + buttonDate.getStyleClass().add("button-hoverable"); + buttonLeft.setStyle("-fx-background-color: transparent;"); + buttonLeft.getStyleClass().add("button-hoverable"); + buttonRight.setStyle("-fx-background-color: transparent;"); + buttonRight.getStyleClass().add("button-hoverable"); + buttonToday.setStyle("-fx-background-color: transparent;"); + buttonToday.getStyleClass().add("button-hoverable"); + buttonAbout.setStyle("-fx-background-color: transparent;"); + buttonAbout.getStyleClass().add("button-hoverable"); if(!settings.isComplete()) { Platform.runLater(() -> { toggleAllTabsExceptSettings(true); tabPane.getSelectionModel().select(tabSettings); - AlertGenerator.showAlert(AlertType.INFORMATION, Localization.getString(Strings.TITLE_INFO), "", Localization.getString(Strings.INFO_FIRST_START), icon, stage, null, false); + AlertGenerator.showAlert(AlertType.INFORMATION, Localization.getString(Strings.TITLE_INFO), "", Localization.getString(Strings.INFO_FIRST_START), icon, getStage(), null, false); }); } else @@ -192,11 +220,6 @@ public class Controller } } - public Stage getStage() - { - return stage; - } - public Image getIcon() { return icon; @@ -236,7 +259,7 @@ public class Controller public void previousMonth() { currentDate = currentDate.minusMonths(1); - labelMonth.setText(currentDate.toString("MMMM yyyy")); + buttonDate.setText(currentDate.toString(DATE_FORMAT)); refresh(filterSettings); } @@ -244,7 +267,7 @@ public class Controller public void nextMonth() { currentDate = currentDate.plusMonths(1); - labelMonth.setText(currentDate.toString("MMMM yyyy")); + buttonDate.setText(currentDate.toString(DATE_FORMAT)); refresh(filterSettings); } @@ -252,7 +275,15 @@ public class Controller public void today() { currentDate = DateTime.now(); - labelMonth.setText(currentDate.toString("MMMM yyyy")); + buttonDate.setText(currentDate.toString(DATE_FORMAT)); + + refresh(filterSettings); + } + + public void setDate(DateTime newDate) + { + currentDate = newDate; + buttonDate.setText(currentDate.toString(DATE_FORMAT)); refresh(filterSettings); } @@ -261,6 +292,11 @@ public class Controller { return currentDate; } + + public void openDatePicker() + { + new DatePickerController(getStage(), this, currentDate); + } public void showConnectionErrorAlert(String errorMessage) { @@ -286,7 +322,7 @@ public class Controller Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); dialogStage.getIcons().add(icon); - dialogStage.initOwner(stage); + dialogStage.initOwner(getStage()); alert.showAndWait(); alertIsShowing = false; }); @@ -297,12 +333,15 @@ public class Controller { homeController.refresh(); paymentController.refresh(); - categoryController.refresh(); - reportController.refresh(); + categoryController.refresh(); if(tabCharts.isSelected()) { chartController.refresh(); } + if(tabReports.isSelected()) + { + reportController.refresh(); + } } public ArrayList<CategoryBudget> getCategoryBudgets() @@ -319,7 +358,7 @@ public class Controller { return categoryHandler; } - + public FilterSettings getFilterSettings() { return filterSettings; @@ -345,8 +384,34 @@ public class Controller buttonLeft.setDisable(disable); buttonRight.setDisable(disable); buttonToday.setDisable(disable); + buttonDate.setDisable(disable); } + public void setSelectedPayment(Payment payment) + { + selectedPayment = payment; + } + + public Payment getSelectedPayment() + { + return selectedPayment; + } + + public SearchPreferences getSearchPreferences() + { + return searchPreferences; + } + + public void setSearchPreferences(SearchPreferences searchPreferences) + { + this.searchPreferences = searchPreferences; + } + + public PaymentController getPaymentController() + { + return paymentController; + } + public void checkForUpdates(boolean showNotification) { try @@ -377,10 +442,18 @@ public class Controller ButtonType buttonTypeTwo = new ButtonType(Localization.getString(Strings.CANCEL)); alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo); + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getButtonTypes().stream().map(dialogPane::lookupButton).forEach(button -> button.addEventHandler(KeyEvent.KEY_PRESSED, (event) -> { + if(KeyCode.ENTER.equals(event.getCode()) && event.getTarget() instanceof Button) + { + ((Button)event.getTarget()).fire(); + } + })); + Optional<ButtonType> result = alert.showAndWait(); if (result.get() == buttonTypeOne) { - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_UPDATE), stage, icon); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_UPDATE), getStage(), icon); Worker.runLater(() -> { try @@ -404,7 +477,7 @@ public class Controller Localization.getString(Strings.TITLE_ERROR), "", Localization.getString(Strings.ERROR_UPDATER_DOWNLOAD_LATEST_VERSION, ex.getMessage()), - icon, null, null, true); + icon, getStage(), null, true); } }); } @@ -439,14 +512,14 @@ public class Controller Localization.getString(Strings.AUTHOR), creditLines, icon, - stage, + getStage(), null, false); } public void refresh(FilterSettings newFilterSettings) { - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATA), stage, icon); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATA), getStage(), icon); Worker.runLater(() -> { try @@ -464,13 +537,13 @@ public class Controller Localization.getString(Strings.TITLE_WARNING), "", Localization.getString(Strings.WARNING_SERVER_VERSION, serverVersion.getVersionName(), Localization.getString(Strings.VERSION_NAME)), - icon, stage, null, false); + icon, getStage(), null, false); if(modalStage != null) { modalStage.close(); }; - categoryHandler = new CategoryHandler(null); + categoryHandler = new CategoryHandler(null); toggleAllTabsExceptSettings(true); tabPane.getSelectionModel().select(tabSettings); }); @@ -479,25 +552,37 @@ public class Controller } catch(Exception e1) { + Logger.error(e1); Platform.runLater(()->{ - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_SERVER_VERSION, Localization.getString(Strings.UNDEFINED), Localization.getString(Strings.VERSION_NAME)), - icon, stage, null, false); - if(modalStage != null) { modalStage.close(); - }; - categoryHandler = new CategoryHandler(null); - toggleAllTabsExceptSettings(true); - tabPane.getSelectionModel().select(tabSettings); + } }); + + if(e1.getMessage().contains("404")) + { + //old server + Platform.runLater(()->{ + AlertGenerator.showAlert(AlertType.WARNING, + Localization.getString(Strings.TITLE_WARNING), + "", + Localization.getString(Strings.WARNING_SERVER_VERSION, Localization.getString(Strings.UNDEFINED), Localization.getString(Strings.VERSION_NAME)), + icon, getStage(), null, false); + + categoryHandler = new CategoryHandler(null); + toggleAllTabsExceptSettings(true); + tabPane.getSelectionModel().select(tabSettings); + }); + } + else + { + //normal connection error (e.g. server not running) + showConnectionErrorAlert(ExceptionHandler.getMessageForException(e1)); + } return; } - paymentHandler = new PaymentHandler(); paymentHandler.getPayments().addAll(connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear())); paymentHandler.getPayments().addAll(connection.getRepeatingPayments(currentDate.getYear(), currentDate.getMonthOfYear())); @@ -512,7 +597,7 @@ public class Controller categoryHandler = new CategoryHandler(connection.getCategories()); categoryBudgets = connection.getCategoryBudgets(currentDate.getYear(), currentDate.getMonthOfYear()); - paymentHandler.filter(newFilterSettings); + paymentHandler.filter(newFilterSettings, new TagHandler(settings)); Platform.runLater(() -> { if(modalStage != null) diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/DatePickerController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/DatePickerController.java new file mode 100644 index 0000000000000000000000000000000000000000..7de27b30b12246dd740a86ebdd42373146a5106d --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/DatePickerController.java @@ -0,0 +1,123 @@ +package de.deadlocker8.budgetmasterclient.ui.controller; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import fontAwesome.FontIconType; +import javafx.fxml.FXML; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Spinner; +import javafx.scene.control.SpinnerValueFactory; +import javafx.scene.paint.Color; +import javafx.stage.Modality; +import javafx.stage.Stage; +import tools.AlertGenerator; +import tools.ConvertTo; +import tools.Localization; + +public class DatePickerController extends BaseController implements Styleable +{ + @FXML private ComboBox<String> comboBoxMonth; + @FXML private Spinner<Integer> spinnerYear; + @FXML private Button buttonCancel; + @FXML private Button buttonConfirm; + + private Stage parentStage; + private Controller controller; + private DateTime currentDate; + + public DatePickerController(Stage parentStage, Controller controller, DateTime currentDate) + { + this.parentStage = parentStage; + this.controller = controller; + this.currentDate = currentDate; + load("/de/deadlocker8/budgetmaster/ui/fxml/DatePickerGUI.fxml", Localization.getBundle()); + getStage().showAndWait(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setTitle(Localization.getString(Strings.TITLE_DATEPICKER)); + stage.getIcons().add(controller.getIcon()); + stage.setResizable(false); + } + + @Override + public void init() + { + SpinnerValueFactory<Integer> spinnerYearValueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 3000, currentDate.getYear()); + spinnerYear.setValueFactory(spinnerYearValueFactory); + spinnerYear.setEditable(false); + spinnerYear.focusedProperty().addListener((observable, oldValue, newValue) -> { + if(!newValue) + { + spinnerYear.increment(0); // won't change value, but will commit editor + } + }); + + comboBoxMonth.getItems().addAll(Helpers.getMonthList()); + comboBoxMonth.setValue(Helpers.getMonthList().get(currentDate.getMonthOfYear()-1)); + + applyStyle(); + } + + public void confirm() + { + String year = String.valueOf(spinnerYear.getValue()); + if(year == null || year.equals("")) + { + AlertGenerator.showAlert(AlertType.WARNING, + Localization.getString(Strings.TITLE_WARNING), + "", + Localization.getString(Strings.WARNING_EMPTY_YEAR), + controller.getIcon(), + getStage(), + null, + false); + return; + } + + if(year.length() > 4) + { + AlertGenerator.showAlert(AlertType.WARNING, + Localization.getString(Strings.TITLE_WARNING), + "", + Localization.getString(Strings.WARNING_WRONG_YEAR), + controller.getIcon(), + getStage(), + null, + false); + return; + } + + String dateString = year + "-" + (Helpers.getMonthList().indexOf(comboBoxMonth.getValue()) + 1); + DateTime newDate = DateTime.parse(dateString, DateTimeFormat.forPattern("YYYY-MM")); + + getStage().close(); + controller.setDate(newDate); + } + + public void cancel() + { + getStage().close(); + } + + @Override + public void applyStyle() + { + buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); + buttonConfirm.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE)); + + buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonConfirm.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ExportChartController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ExportChartController.java similarity index 77% rename from src/de/deadlocker8/budgetmaster/ui/controller/ExportChartController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ExportChartController.java index 7fccd8c7d477058f3d1287c9d4278db31112821f..43ebe49ac556a87a80aa14b2475a33f824ea7748 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/ExportChartController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ExportChartController.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.awt.Desktop; import java.io.File; @@ -11,6 +11,7 @@ import de.deadlocker8.budgetmaster.logic.charts.ChartExportable; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.Styleable; import fontAwesome.FontIconType; import javafx.embed.swing.SwingFXUtils; import javafx.fxml.FXML; @@ -18,20 +19,24 @@ 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.DialogPane; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.control.TextFormatter; import javafx.scene.image.WritableImage; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; import javafx.stage.FileChooser; +import javafx.stage.Modality; import javafx.stage.Stage; import logger.Logger; import tools.AlertGenerator; import tools.ConvertTo; import tools.Localization; -public class ExportChartController +public class ExportChartController extends BaseController implements Styleable { @FXML private AnchorPane anchorPaneMain; @FXML private TextField textFieldWidth; @@ -42,15 +47,33 @@ public class ExportChartController @FXML private Button buttonCancel; private ChartController controller; - private Stage stage; + private Stage parentStage; private ChartExportable chart; private File savePath; - - public void init(Stage stage, ChartController controller, ChartExportable chart) + + public ExportChartController(Stage parentStage, ChartController controller, ChartExportable chart) { + this.parentStage = parentStage; this.controller = controller; - this.stage = stage; this.chart = chart; + load("/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml", Localization.getBundle()); + getStage().showAndWait(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setTitle(Localization.getString(Strings.TITLE_CHART_EXPORT)); + stage.getIcons().add(controller.getController().getIcon()); + stage.setResizable(false); + } + + @Override + public void init() + { + applyStyle(); this.savePath = controller.getLastExportPath(); if(savePath != null) @@ -59,18 +82,7 @@ public class ExportChartController } textFieldWidth.setText(String.valueOf((int)chart.getSuggestedWidth())); - textFieldHeight.setText(String.valueOf((int)chart.getSuggestedHeight())); - - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - - buttonChooseFile.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); - buttonChooseFile.setGraphic(Helpers.getFontIcon(FontIconType.FOLDER_OPEN, 14, Color.WHITE)); - - buttonExport.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); - buttonExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 14, Color.WHITE)); - - buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); - buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 14, Color.WHITE)); + textFieldHeight.setText(String.valueOf((int)chart.getSuggestedHeight())); textFieldWidth.setTextFormatter(new TextFormatter<>(c -> { if(c.getControlNewText().isEmpty()) @@ -116,7 +128,7 @@ public class ExportChartController fileChooser.setInitialFileName(savePath.getName()); } fileChooser.getExtensionFilters().add(extFilter); - File file = fileChooser.showSaveDialog(stage); + File file = fileChooser.showSaveDialog(getStage()); if(file != null) { savePath = file; @@ -133,8 +145,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_WARNING), "", Localization.getString(Strings.WARNING_EMPTY_WIDTH_IN_PIXELS), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); return; @@ -151,8 +163,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_WARNING), "", Localization.getString(Strings.WARNING_INTEGER_WIDTH_IN_PIXELS), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); return; @@ -165,8 +177,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_WARNING), "", Localization.getString(Strings.WARNING_EMPTY_HEIGHT_IN_PIXELS), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); return; @@ -183,8 +195,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_WARNING), "", Localization.getString(Strings.WARNING_INTEGER_HEIGHT_IN_PIXELS), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); return; @@ -196,8 +208,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_WARNING), "", Localization.getString(Strings.WARNING_EMPTY_SAVEPATH_CHART), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); return; @@ -208,22 +220,28 @@ public class ExportChartController try { ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", savePath); - controller.getControlle().showNotification(Localization.getString(Strings.NOTIFICATION_CHART_EXPORT)); - - stage.close(); Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle(Localization.getString(Strings.INFO_TITLE_CHART_EXPORT)); + alert.initOwner(controller.getController().getStage()); alert.setHeaderText(""); alert.setContentText(Localization.getString(Strings.INFO_TEXT_CHART_EXPORT)); Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); - dialogStage.getIcons().add(controller.getControlle().getIcon()); + dialogStage.getIcons().add(controller.getController().getIcon()); ButtonType buttonTypeOne = new ButtonType(Localization.getString(Strings.INFO_TEXT_CHART_EXPORT_OPEN_FOLDER)); ButtonType buttonTypeTwo = new ButtonType(Localization.getString(Strings.INFO_TEXT_CHART_EXPORT_OPEN_CHART)); ButtonType buttonTypeThree = new ButtonType(Localization.getString(Strings.OK)); alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree); + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getButtonTypes().stream().map(dialogPane::lookupButton).forEach(button -> button.addEventHandler(KeyEvent.KEY_PRESSED, (event) -> { + if(KeyCode.ENTER.equals(event.getCode()) && event.getTarget() instanceof Button) + { + ((Button)event.getTarget()).fire(); + } + })); + Optional<ButtonType> result = alert.showAndWait(); if (result.get() == buttonTypeOne) { @@ -238,8 +256,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_ERROR), "", Localization.getString(Strings.ERROR_OPEN_FOLDER, e1.getMessage()), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); } @@ -257,8 +275,8 @@ public class ExportChartController Localization.getString(Strings.TITLE_ERROR), "", Localization.getString(Strings.ERROR_OPEN_CHART, e1.getMessage()), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); } @@ -275,18 +293,34 @@ public class ExportChartController Localization.getString(Strings.TITLE_ERROR), "", Localization.getString(Strings.ERROR_CHART_EXPORT, e.getMessage()), - controller.getControlle().getIcon(), - stage, + controller.getController().getIcon(), + getStage(), null, false); } - stage.close(); + getStage().close(); + controller.getController().showNotification(Localization.getString(Strings.NOTIFICATION_CHART_EXPORT)); controller.setLastExportPath(savePath); } public void cancel() { - stage.close(); + getStage().close(); + } + + @Override + public void applyStyle() + { + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + + buttonChooseFile.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + buttonChooseFile.setGraphic(Helpers.getFontIcon(FontIconType.FOLDER_OPEN, 14, Color.WHITE)); + + buttonExport.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + buttonExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 14, Color.WHITE)); + + buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 14, Color.WHITE)); } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/FilterController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/FilterController.java similarity index 51% rename from src/de/deadlocker8/budgetmaster/ui/controller/FilterController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/FilterController.java index 0acf4e391f139ef6b32491bd14779fbdefdcce99..870246f417cedc957e94c2779856288873d61b93 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/FilterController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/FilterController.java @@ -1,24 +1,37 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.util.ArrayList; -import de.deadlocker8.budgetmaster.logic.Category; import de.deadlocker8.budgetmaster.logic.FilterSettings; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerTagConnection; +import de.deadlocker8.budgetmaster.logic.tag.Tag; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.Styleable; import fontAwesome.FontIconType; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.stage.Modality; import javafx.stage.Stage; +import logger.Logger; import tools.ConvertTo; +import tools.Localization; -public class FilterController +public class FilterController extends BaseController implements Styleable { + @FXML private ScrollPane scrollPane; + @FXML private VBox vboxMain; @FXML private CheckBox checkBoxIncome; @FXML private CheckBox checkBoxPayment; @FXML private CheckBox checkBoxNoRepeating; @@ -26,31 +39,48 @@ public class FilterController @FXML private CheckBox checkBoxRepeatEveryXDays; @FXML private VBox vboxCategories; @FXML private TextField textFieldSearch; + @FXML private VBox vboxTags; @FXML private Button buttonCancel; @FXML private Button buttonReset; @FXML private Button buttonFilter; @FXML private Button buttonCategoryAll; @FXML private Button buttonCategoryNone; + @FXML private Button buttonTagsAll; + @FXML private Button buttonTagsNone; + @FXML private Label labelSeparator; + @FXML private Label labelSeparatorHorizontalLeft; + @FXML private Label labelSeparatorHorizontalRight; - private Stage stage; + private Stage parentStage; private Controller controller; private FilterSettings filterSetttings; - - public void init(Stage stage, Controller controller, FilterSettings filterSettings) + private ArrayList<Tag> allTags; + + public FilterController(Stage parentStage, Controller controller, FilterSettings filterSettings) { - this.stage = stage; + this.parentStage = parentStage; this.controller = controller; this.filterSetttings = filterSettings; + load("/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml", Localization.getBundle()); + getStage().showAndWait(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setTitle(Localization.getString(Strings.TITLE_FILTER)); + stage.getIcons().add(controller.getIcon()); + stage.setResizable(true); + stage.setMinHeight(600); + stage.setMinWidth(475); + } - buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); - buttonReset.setGraphic(Helpers.getFontIcon(FontIconType.UNDO, 17, Color.WHITE)); - buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 17, Color.WHITE)); - - buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); - buttonReset.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); - buttonFilter.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); - buttonCategoryAll.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 13;"); - buttonCategoryNone.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 13;"); + @Override + public void init() + { + applyStyle(); for(Category currentCategory : controller.getCategoryHandler().getCategories()) { @@ -60,7 +90,36 @@ public class FilterController newCheckBox.setStyle("-fx-font-size: 14;"); vboxCategories.getChildren().add(newCheckBox); } - + + try + { + ServerTagConnection connection = new ServerTagConnection(controller.getSettings()); + allTags = connection.getTags(); + for(Tag currentTag : allTags) + { + CheckBox newCheckBox = new CheckBox(); + newCheckBox.setText(currentTag.getName()); + newCheckBox.setUserData(currentTag.getID()); + newCheckBox.setStyle("-fx-font-size: 14;"); + vboxTags.getChildren().add(newCheckBox); + } + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); + return; + } + + textFieldSearch.setOnKeyPressed((event)->{ + if(event.getCode().equals(KeyCode.ENTER)) + { + filter(); + } + }); + + vboxMain.prefWidthProperty().bind(scrollPane.widthProperty().subtract(5)); + vboxMain.prefHeightProperty().bind(scrollPane.heightProperty().subtract(5)); preselect(); } @@ -73,7 +132,6 @@ public class FilterController checkBoxRepeatEveryXDays.setSelected(filterSetttings.isRepeatingEveryXDaysAllowed()); ArrayList<Integer> allowedCategoryIDs = filterSetttings.getAllowedCategoryIDs(); - for(Node node : vboxCategories.getChildren()) { CheckBox currentCheckBox = (CheckBox)node; @@ -82,6 +140,16 @@ public class FilterController currentCheckBox.setSelected(true); } } + + ArrayList<Integer> allowedTagIDs = filterSetttings.getAllowedTagIDs(); + for(Node node : vboxTags.getChildren()) + { + CheckBox currentCheckBox = (CheckBox)node; + if(allowedTagIDs == null || allowedTagIDs.contains(currentCheckBox.getUserData())) + { + currentCheckBox.setSelected(true); + } + } textFieldSearch.setText(filterSetttings.getName()); } @@ -115,24 +183,39 @@ public class FilterController { name = null; } + + ArrayList<Integer> allowedTagIDs = new ArrayList<>(); + for(Node node : vboxTags.getChildren()) + { + CheckBox currentCheckBox = (CheckBox)node; + if(currentCheckBox.isSelected()) + { + allowedTagIDs.add((int)currentCheckBox.getUserData()); + } + } - FilterSettings newFilterSettings = new FilterSettings(isIncomeAllowed, isPaymentAllowed, isNoRepeatingAllowed, isMonthlyRepeatingAllowed, isRepeatingEveryXDaysAllowed, allowedCategoryIDs, name); + if(allowedTagIDs.size() == allTags.size()) + { + allowedTagIDs = null; + } + + FilterSettings newFilterSettings = new FilterSettings(isIncomeAllowed, isPaymentAllowed, isNoRepeatingAllowed, isMonthlyRepeatingAllowed, isRepeatingEveryXDaysAllowed, allowedCategoryIDs, allowedTagIDs, name); controller.setFilterSettings(newFilterSettings); controller.refresh(newFilterSettings); - stage.close(); + getStage().close(); } public void reset() { - filterSetttings = new FilterSettings(); - preselect(); + filterSetttings = new FilterSettings(); + getStage().close(); controller.setFilterSettings(filterSetttings); controller.refresh(filterSetttings); } public void cancel() { - stage.close(); + getStage().close(); } public void enableAllCategories() @@ -150,4 +233,50 @@ public class FilterController ((CheckBox)node).setSelected(false); } } + + public void enableAllTags() + { + for(Node node : vboxTags.getChildren()) + { + ((CheckBox)node).setSelected(true); + } + } + + public void disableAllTags() + { + for(Node node : vboxTags.getChildren()) + { + ((CheckBox)node).setSelected(false); + } + } + + @Override + public void applyStyle() + { + buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); + buttonReset.setGraphic(Helpers.getFontIcon(FontIconType.UNDO, 17, Color.WHITE)); + buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 17, Color.WHITE)); + + scrollPane.setStyle("-fx-background-color: transparent"); + + labelSeparator.setStyle("-fx-background-color: #CCCCCC;"); + labelSeparator.setMinWidth(1); + labelSeparator.setMaxWidth(1); + + labelSeparatorHorizontalLeft.setStyle("-fx-background-color: #CCCCCC;"); + labelSeparatorHorizontalLeft.setMinHeight(1); + labelSeparatorHorizontalLeft.setMaxHeight(1); + + labelSeparatorHorizontalRight.setStyle("-fx-background-color: #CCCCCC;"); + labelSeparatorHorizontalRight.setMinHeight(1); + labelSeparatorHorizontalRight.setMaxHeight(1); + + buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonReset.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonFilter.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonCategoryAll.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 13;"); + buttonCategoryNone.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 13;"); + buttonTagsAll.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 13;"); + buttonTagsNone.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 13;"); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/HomeController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/HomeController.java similarity index 73% rename from src/de/deadlocker8/budgetmaster/ui/controller/HomeController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/HomeController.java index 6516d0fdd82913bb3011ba0d39a518228557852f..3f508660024cb93ebda4d1a086377678f75941ea 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/HomeController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/HomeController.java @@ -1,28 +1,26 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.util.ArrayList; import de.deadlocker8.budgetmaster.logic.Budget; -import de.deadlocker8.budgetmaster.logic.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.category.CategoryBudget; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.Refreshable; -import de.deadlocker8.budgetmaster.ui.cells.CategoryBudgetCell; +import de.deadlocker8.budgetmasterclient.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.CategoryBudgetCell; import javafx.application.Platform; import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.control.Label; -import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.control.ProgressBar; import javafx.scene.layout.AnchorPane; -import javafx.util.Callback; import tools.ConvertTo; import tools.Localization; -public class HomeController implements Refreshable +public class HomeController implements Refreshable, Styleable { @FXML private AnchorPane anchorPaneMain; @FXML private Label labelBudget; @@ -37,35 +35,15 @@ public class HomeController implements Refreshable this.controller = controller; HomeController thisController = this; - listView.setCellFactory(new Callback<ListView<CategoryBudget>, ListCell<CategoryBudget>>() - { - @Override - public ListCell<CategoryBudget> call(ListView<CategoryBudget> param) - { - return new CategoryBudgetCell(thisController); - } - }); + listView.setCellFactory(param -> new CategoryBudgetCell(thisController)); Label labelPlaceholder = new Label(Localization.getString(Strings.HOME_PLACEHOLDER)); labelPlaceholder.setStyle("-fx-font-size: 16"); listView.setPlaceholder(labelPlaceholder); - listView.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() - { - @Override - public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) - { - Platform.runLater(new Runnable() - { - public void run() - { - listView.getSelectionModel().select(-1); - } - }); - } - }); + listView.getSelectionModel().selectedIndexProperty().addListener((ChangeListener<Number>)(observable, oldValue, newValue) -> Platform.runLater(() -> listView.getSelectionModel().select(-1))); - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + applyStyle(); } private void refreshListView() @@ -121,4 +99,10 @@ public class HomeController implements Refreshable refreshListView(); refreshCounter(); } + + @Override + public void applyStyle() + { + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ModalController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ModalController.java similarity index 84% rename from src/de/deadlocker8/budgetmaster/ui/controller/ModalController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ModalController.java index d86c8cbc3cccfbcb48d12a916d012bdab5c0e31d..b173d805b38430363d7c586fb8ad6380c3347408 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/ModalController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ModalController.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import javafx.fxml.FXML; import javafx.scene.control.Label; diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/NewCategoryController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/NewCategoryController.java similarity index 78% rename from src/de/deadlocker8/budgetmaster/ui/controller/NewCategoryController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/NewCategoryController.java index 1f9454e41a31bd0d4987d9d44e7e2b7ee5458bc9..d5a37d753dc62b57d631d34e32f5f9ee619d4752 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/NewCategoryController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/NewCategoryController.java @@ -1,60 +1,83 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.util.ArrayList; import org.controlsfx.control.PopOver; import org.controlsfx.control.PopOver.ArrowLocation; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.colorPick.ColorView; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.colorPick.ColorView; import fontAwesome.FontIconType; import javafx.fxml.FXML; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.paint.Color; +import javafx.stage.Modality; import javafx.stage.Stage; import javafx.util.Duration; import tools.AlertGenerator; import tools.ConvertTo; import tools.Localization; -public class NewCategoryController +public class NewCategoryController extends BaseController implements Styleable { @FXML private TextField textFieldName; @FXML private Button buttonColor; @FXML private Button buttonCancel; @FXML private Button buttonSave; - private Stage stage; + private Stage parentStage; private Controller controller; private CategoryController categoryController; private boolean edit; private Color color; private PopOver colorChooser; private ColorView colorView; - private Category category; - - public void init(Stage stage, Controller controller, CategoryController categoryController, boolean edit, Category category) + private Category category; + + public NewCategoryController(Stage parentStage, Controller controller, CategoryController categoryController, boolean edit, Category category) { - this.stage = stage; + this.parentStage = parentStage; this.controller = controller; this.categoryController = categoryController; this.edit = edit; this.color = null; this.category = category; + load("/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml", Localization.getBundle()); + getStage().showAndWait(); + } - buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); - buttonSave.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE)); - - buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); - buttonSave.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); - buttonColor.setStyle("-fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;"); + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + + if(edit) + { + stage.setTitle(Localization.getString(Strings.TITLE_CATEGORY_EDIT)); + } + else + { + stage.setTitle(Localization.getString(Strings.TITLE_CATEGORY_NEW)); + } + + stage.getIcons().add(controller.getIcon()); + stage.setResizable(false); + stage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css"); + } + + @Override + public void init() + { + applyStyle(); buttonColor.prefWidthProperty().bind(textFieldName.widthProperty()); @@ -75,7 +98,7 @@ public class NewCategoryController } }); - stage.setOnCloseRequest(event -> { + getStage().setOnCloseRequest(event -> { if(colorChooser != null) { colorChooser.hide(Duration.millis(0)); @@ -168,12 +191,23 @@ public class NewCategoryController } } - stage.close(); + getStage().close(); categoryController.getController().refresh(controller.getFilterSettings()); } public void cancel() { - stage.close(); + getStage().close(); + } + + @Override + public void applyStyle() + { + buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); + buttonSave.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE)); + + buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonSave.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonColor.setStyle("-fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;"); } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/NewPaymentController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/NewPaymentController.java similarity index 54% rename from src/de/deadlocker8/budgetmaster/ui/controller/NewPaymentController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/NewPaymentController.java index bed43daa5ef76ca69c2ba29dc85d44ff50bf030a..e2e5f75e823feea28abe183f4d821bcb36d54b25 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/NewPaymentController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/NewPaymentController.java @@ -1,25 +1,30 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.time.LocalDate; import java.util.ArrayList; import org.joda.time.DateTime; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.Payment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerTagConnection; +import de.deadlocker8.budgetmaster.logic.tag.Tag; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.cells.ButtonCategoryCell; -import de.deadlocker8.budgetmaster.ui.cells.RepeatingDayCell; -import de.deadlocker8.budgetmaster.ui.cells.SmallCategoryCell; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.ButtonCategoryCell; +import de.deadlocker8.budgetmasterclient.ui.cells.RepeatingDayCell; +import de.deadlocker8.budgetmasterclient.ui.cells.SmallCategoryCell; +import de.deadlocker8.budgetmasterclient.ui.tagField.TagField; import fontAwesome.FontIconType; import javafx.fxml.FXML; +import javafx.geometry.Insets; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; @@ -28,20 +33,27 @@ import javafx.scene.control.DateCell; import javafx.scene.control.DatePicker; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; +import javafx.scene.control.ScrollPane; import javafx.scene.control.Spinner; import javafx.scene.control.SpinnerValueFactory; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.control.ToggleGroup; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.stage.Modality; import javafx.stage.Stage; import logger.Logger; import tools.AlertGenerator; import tools.ConvertTo; import tools.Localization; -public class NewPaymentController +public class NewPaymentController extends BaseController implements Styleable { + @FXML private ScrollPane scrollPane; + @FXML private VBox vboxContent; @FXML private TextField textFieldName; @FXML private TextField textFieldAmount; @FXML private Button buttonCancel; @@ -56,54 +68,119 @@ public class NewPaymentController @FXML private RadioButton radioButtonDay; @FXML private Label labelText1, labelText2, labelText3; @FXML private TextArea textArea; + @FXML private HBox hboxTags; + @FXML private Button buttonTagsHelp; - private Stage stage; + private Stage parentStage; private Controller controller; private PaymentController paymentController; private boolean isPayment; private boolean edit; private Payment payment; private ButtonCategoryCell buttonCategoryCell; - - public void init(Stage stage, Controller controller, PaymentController paymentController, boolean isPayment, boolean edit, Payment payment) + private TagField tagField; + private ArrayList<Tag> previousTags; + + public NewPaymentController(Stage parentStage, Controller controller, PaymentController paymentController, boolean isPayment, boolean edit, Payment payment) { - this.stage = stage; + this.parentStage = parentStage; this.controller = controller; this.paymentController = paymentController; this.isPayment = isPayment; this.edit = edit; this.payment = payment; - - buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); - buttonSave.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE)); + load("/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml", Localization.getBundle()); + getStage().showAndWait(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + String titlePart; - buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); - buttonSave.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + titlePart = isPayment ? Localization.getString(Strings.TITLE_PAYMENT) : Localization.getString(Strings.TITLE_INCOME); - SpinnerValueFactory<Integer> valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 1000, 0); - spinnerRepeatingPeriod.setValueFactory(valueFactory); - spinnerRepeatingPeriod.setEditable(true); - spinnerRepeatingPeriod.focusedProperty().addListener((observable, oldValue, newValue) -> { - if(!newValue) + if(edit) + { + stage.setTitle(Localization.getString(Strings.TITLE_PAYMENT_EDIT, titlePart)); + } + else + { + stage.setTitle(Localization.getString(Strings.TITLE_PAYMENT_NEW, titlePart)); + } + + stage.getIcons().add(controller.getIcon()); + stage.setResizable(true); + stage.setMinHeight(600); + stage.setMinWidth(450); + stage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css"); + } + + @Override + public void init() + { + vboxContent.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25)); + vboxContent.prefHeightProperty().bind(scrollPane.heightProperty().subtract(10)); + + applyStyle(); + + tagField = new TagField(new ArrayList<Tag>(), new ArrayList<Tag>(), this); + hboxTags.getChildren().add(tagField); + tagField.maxWidthProperty().bind(hboxTags.widthProperty()); + HBox.setHgrow(tagField, Priority.ALWAYS); + + previousTags = new ArrayList<>(); + + initRepeatingArea(); + + if(edit) + { + prefill(); + } + else + { + comboBoxCategory.setValue(controller.getCategoryHandler().getCategory(1)); + checkBoxRepeat.setSelected(false); + radioButtonPeriod.setSelected(true); + toggleRepeatingArea(false); + + //preselect correct month and year + DateTime currentDate = controller.getCurrentDate(); + if(DateTime.now().getDayOfMonth() > currentDate.dayOfMonth().withMaximumValue().getDayOfMonth()) { - spinnerRepeatingPeriod.increment(0); // won't change value, but will commit editor + currentDate = currentDate.dayOfMonth().withMaximumValue(); + } + + LocalDate currentLocalDate = LocalDate.now().withYear(currentDate.getYear()) + .withMonth(currentDate.getMonthOfYear()) + .withDayOfMonth(currentDate.getDayOfMonth()); + datePicker.setValue(currentLocalDate); + datePickerEnddate.setValue(currentLocalDate); + + try + { + ServerTagConnection serverTagConnection = new ServerTagConnection(controller.getSettings()); + tagField.setAllTags(serverTagConnection.getTags()); + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); } - }); - - comboBoxRepeatingDay.setCellFactory((view) -> { - return new RepeatingDayCell(); - }); - ArrayList<Integer> days = new ArrayList<>(); - for(int i = 1; i <= 31; i++) - { - days.add(i); } - comboBoxRepeatingDay.getItems().addAll(days); - comboBoxCategory.setCellFactory((view) -> { - return new SmallCategoryCell(); - }); - comboBoxRepeatingDay.setValue(1); + datePicker.setEditable(false); + } + + public Controller getController() + { + return controller; + } + + private void initComboBoxCategory() + { buttonCategoryCell = new ButtonCategoryCell(Color.WHITE); comboBoxCategory.setButtonCell(buttonCategoryCell); comboBoxCategory.setStyle("-fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;"); @@ -111,11 +188,10 @@ public class NewPaymentController comboBoxCategory.setStyle("-fx-background-color: " + newValue.getColor() + "; -fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;"); buttonCategoryCell.setColor(Color.web(newValue.getColor())); }); - - checkBoxRepeat.selectedProperty().addListener((listener, oldValue, newValue) -> { - toggleRepeatingArea(newValue); + comboBoxCategory.setCellFactory((view) -> { + return new SmallCategoryCell(); }); - + comboBoxCategory.getItems().clear(); try { @@ -129,16 +205,26 @@ public class NewPaymentController { comboBoxCategory.getItems().add(currentCategory); } - } - + } } } catch(Exception e) { controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); - stage.close(); + getStage().close(); return; } + } + + private void initRepeatingArea() + { + checkBoxRepeat.selectedProperty().addListener((listener, oldValue, newValue) -> { + toggleRepeatingArea(newValue); + }); + + initSpinnerRepeatingPeriod(); + initComboBoxRepeatingDay(); + initComboBoxCategory(); final ToggleGroup toggleGroup = new ToggleGroup(); radioButtonPeriod.setToggleGroup(toggleGroup); @@ -161,21 +247,71 @@ public class NewPaymentController } } }); + } + + private void initSpinnerRepeatingPeriod() + { + SpinnerValueFactory<Integer> valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 1000, 0); + spinnerRepeatingPeriod.setValueFactory(valueFactory); + spinnerRepeatingPeriod.setEditable(false); + spinnerRepeatingPeriod.focusedProperty().addListener((observable, oldValue, newValue) -> { + if(!newValue) + { + spinnerRepeatingPeriod.increment(0); // won't change value, but will commit editor + } + }); + } + + private void initComboBoxRepeatingDay() + { + comboBoxRepeatingDay.setCellFactory((view) -> { + return new RepeatingDayCell(); + }); + ArrayList<Integer> days = new ArrayList<>(); + for(int i = 1; i <= 31; i++) + { + days.add(i); + } + comboBoxRepeatingDay.getItems().addAll(days); + comboBoxRepeatingDay.setValue(1); + } + + private void prefill() + { + textFieldName.setText(payment.getName()); + textFieldAmount.setText(Helpers.NUMBER_FORMAT.format(Math.abs(payment.getAmount()/100.0)).replace(".", ",")); + comboBoxCategory.setValue(controller.getCategoryHandler().getCategory(payment.getCategoryID())); + datePicker.setValue(LocalDate.parse(payment.getDate())); + textArea.setText(payment.getDescription()); - if(edit) + try { - //prefill - textFieldName.setText(payment.getName()); - textFieldAmount.setText(Helpers.NUMBER_FORMAT.format(Math.abs(payment.getAmount()/100.0)).replace(".", ",")); - comboBoxCategory.setValue(controller.getCategoryHandler().getCategory(payment.getCategoryID())); - datePicker.setValue(LocalDate.parse(payment.getDate())); - textArea.setText(payment.getDescription()); + ServerTagConnection serverTagConnection = new ServerTagConnection(controller.getSettings()); + tagField.setAllTags(serverTagConnection.getTags()); + + if(payment instanceof RepeatingPayment) + { + //search gets RepeatingPayments instead of RepeatingPaymenEntries --> convert it to RepeatingPaymentEntry to maintain compatibility + RepeatingPayment tempPayment = (RepeatingPayment)payment; + payment = new RepeatingPaymentEntry(-1, + tempPayment.getID(), + tempPayment.getDate(), + tempPayment.getAmount(), + tempPayment.getCategoryID(), + tempPayment.getName(), + tempPayment.getDescription(), + tempPayment.getRepeatInterval(), + tempPayment.getRepeatEndDate(), + tempPayment.getRepeatMonthDay()); + } if(payment instanceof RepeatingPaymentEntry) { try { RepeatingPaymentEntry currentPayment = (RepeatingPaymentEntry)payment; + previousTags = serverTagConnection.getAllTagsForRepeatingPayment(currentPayment.getRepeatingPaymentID()); + tagField.setTags(new ArrayList<>(previousTags)); ServerConnection connection = new ServerConnection(controller.getSettings()); RepeatingPayment repeatingPayment = connection.getRepeatingPayment(currentPayment.getRepeatingPaymentID()); @@ -209,89 +345,60 @@ public class NewPaymentController } } else - { + { + previousTags = serverTagConnection.getAllTagsForPayment((NormalPayment)payment); + tagField.setTags(new ArrayList<>(previousTags)); checkBoxRepeat.setSelected(false); radioButtonPeriod.setSelected(true); toggleRepeatingArea(false); - } - } - else - { - comboBoxCategory.getSelectionModel().select(0); - checkBoxRepeat.setSelected(false); - radioButtonPeriod.setSelected(true); - toggleRepeatingArea(false); - - //preselect correct month and year - DateTime currentDate = controller.getCurrentDate(); - if(DateTime.now().getDayOfMonth() > currentDate.dayOfMonth().withMaximumValue().getDayOfMonth()) - { - currentDate = currentDate.dayOfMonth().withMaximumValue(); - } - - LocalDate currentLocalDate = LocalDate.now().withYear(currentDate.getYear()) - .withMonth(currentDate.getMonthOfYear()) - .withDayOfMonth(currentDate.getDayOfMonth()); - datePicker.setValue(currentLocalDate); + } + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); } - - datePicker.setEditable(false); + } + + private void showWarning(String message) + { + AlertGenerator.showAlert(AlertType.WARNING, + Localization.getString(Strings.TITLE_WARNING), + "", + message, + controller.getIcon(), + controller.getStage(), + null, + false); } + @FXML public void save() { String name = textFieldName.getText(); if(name == null || name.equals("")) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_EMPTY_PAYMENT_NAME), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_EMPTY_PAYMENT_NAME)); return; } if(name.length() > 150) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_NAME_CHARACTER_LIMIT_REACHED_150), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_NAME_CHARACTER_LIMIT_REACHED_150)); return; } String amountText = textFieldAmount.getText(); if(!amountText.matches("^-?\\d+(,\\d+)*(\\.\\d+(e\\d+)?)?$")) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_PAYMENT_AMOUNT), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_PAYMENT_AMOUNT)); return; } LocalDate date = datePicker.getValue(); if(date == null) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_EMPTY_PAYMENT_DATE), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_EMPTY_PAYMENT_DATE)); return; } @@ -307,14 +414,7 @@ public class NewPaymentController { if(description.length() > 150) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_DESCRIPTION_CHARACTER_LIMIT_REACHED_150), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_DESCRIPTION_CHARACTER_LIMIT_REACHED_150)); return; } } @@ -322,6 +422,8 @@ public class NewPaymentController { description = ""; } + + Payment finalPayment; int repeatingInterval = 0; int repeatingDay = 0; @@ -338,27 +440,13 @@ public class NewPaymentController if(repeatingInterval == 0 && repeatingDay == 0) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_PAYMENT_REPEATING), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_PAYMENT_REPEATING)); return; } if(datePickerEnddate.getValue() != null && datePickerEnddate.getValue().isBefore(date)) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_ENDDATE_BEFORE_STARTDATE), - controller.getIcon(), - controller.getStage(), - null, - false); + showWarning(Localization.getString(Strings.WARNING_ENDDATE_BEFORE_STARTDATE)); return; } @@ -377,12 +465,17 @@ public class NewPaymentController { connection.deleteRepeatingPayment((RepeatingPaymentEntry)payment); } - connection.addRepeatingPayment(newPayment); + int id = connection.addRepeatingPayment(newPayment); + finalPayment = newPayment; + previousTags = new ArrayList<>(); + finalPayment.setID(id); } catch(Exception e) { Logger.error(e); controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); + getStage().close(); + return; } } else @@ -391,12 +484,16 @@ public class NewPaymentController try { ServerConnection connection = new ServerConnection(controller.getSettings()); - connection.addRepeatingPayment(newPayment); + int id = connection.addRepeatingPayment(newPayment); + finalPayment = newPayment; + finalPayment.setID(id); } catch(Exception e) { Logger.error(e); controller.showConnectionErrorAlert(e.getMessage()); + getStage().close(); + return; } } } @@ -405,24 +502,29 @@ public class NewPaymentController if(edit) { NormalPayment newPayment = new NormalPayment(payment.getID(), amount, Helpers.getDateString(date), comboBoxCategory.getValue().getID(), name, description); + int id = payment.getID(); try { ServerConnection connection = new ServerConnection(controller.getSettings()); if(payment instanceof RepeatingPaymentEntry) { //if old one was repeating it should be deleted - connection.deleteRepeatingPayment((RepeatingPaymentEntry)payment); - connection.addNormalPayment(newPayment); + connection.deleteRepeatingPayment((RepeatingPaymentEntry)payment); + id = connection.addNormalPayment(newPayment); } else { connection.updateNormalPayment(newPayment); - } + } + finalPayment = newPayment; + finalPayment.setID(id); } catch(Exception e) { Logger.error(e); controller.showConnectionErrorAlert(e.getMessage()); + getStage().close(); + return; } } else @@ -431,23 +533,49 @@ public class NewPaymentController try { ServerConnection connection = new ServerConnection(controller.getSettings()); - connection.addNormalPayment(newPayment); + int id = connection.addNormalPayment(newPayment); + finalPayment = newPayment; + finalPayment.setID(id); } catch(Exception e) { Logger.error(e); controller.showConnectionErrorAlert(e.getMessage()); + getStage().close(); + return; } } } + + try + { + saveTags(tagField.getTags(), finalPayment); + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(e.getMessage()); + } - stage.close(); + getStage().close(); paymentController.getController().refresh(controller.getFilterSettings()); } public void cancel() { - stage.close(); + getStage().close(); + } + + @FXML + public void showTagsHelp() + { + AlertGenerator.showAlert(AlertType.INFORMATION, + Localization.getString(Strings.TITLE_TAGS), + "", + Localization.getString(Strings.INFO_TAGS), + controller.getIcon(), + getStage(), + null, false); } private void toggleRepeatingArea(boolean selected) @@ -486,4 +614,82 @@ public class NewPaymentController comboBoxRepeatingDay.setDisable(selected); labelText3.setDisable(selected); } + + private boolean tagListContainsTag(ArrayList<Tag> tags, String name) + { + for(Tag paymentTag: tags) + { + if(name.equals(paymentTag.getName())) + { + return true; + } + } + return false; + } + + private void saveTags(ArrayList<Tag> tags, Payment payment) throws Exception + { + ServerTagConnection serverTagConnection = new ServerTagConnection(controller.getSettings()); + + //check for deleted tags + for(Tag currentTag : previousTags) + { + if(!tagListContainsTag(tags, currentTag.getName())) + { + if(payment instanceof RepeatingPayment) + { + RepeatingPayment repeatingPayment = (RepeatingPayment)payment; + serverTagConnection.deleteTagMatchForRepeatingPayment(currentTag.getID(), repeatingPayment); + } + else + { + NormalPayment normalPayment = (NormalPayment)payment; + serverTagConnection.deleteTagMatchForPayment(currentTag.getID(), normalPayment); + } + } + } + + //check for new tags + for(Tag paymentTag : tags) + { + if(!tagListContainsTag(previousTags, paymentTag.getName())) + { + String name = paymentTag.getName(); + Tag existingTag = serverTagConnection.getTag(name); + if(existingTag == null) + { + serverTagConnection.addTag(new Tag(-1, name)); + existingTag = serverTagConnection.getTag(name); + } + + if(payment instanceof RepeatingPayment) + { + RepeatingPayment repeatingPayment = (RepeatingPayment)payment; + serverTagConnection.addTagMatchForRepeatingPayment(existingTag.getID(), repeatingPayment); + } + else + { + NormalPayment normalPayment = (NormalPayment)payment; + serverTagConnection.addTagMatchForPayment(existingTag.getID(), normalPayment); + } + } + } + } + + @Override + public void applyStyle() + { + buttonTagsHelp.setGraphic(Helpers.getFontIcon(FontIconType.QUESTION, 13, Colors.TEXT)); + buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); + buttonSave.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE)); + + scrollPane.setStyle("-fx-background-color: transparent"); + buttonTagsHelp.setStyle("-fx-background-color: transparent; -fx-border-radius: 50%; -fx-border-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + buttonTagsHelp.getStyleClass().add("button-hoverable"); + buttonTagsHelp.setPrefWidth(18); + buttonTagsHelp.setPrefHeight(18); + buttonTagsHelp.setPadding(new Insets(0)); + buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonSave.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/PaymentController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/PaymentController.java similarity index 65% rename from src/de/deadlocker8/budgetmaster/ui/controller/PaymentController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/PaymentController.java index 2bb601cbb26fac82b26b615788bb067b262c2bab..c489114a84a5498c9fc8b417b2abe22c752185b2 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/PaymentController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/PaymentController.java @@ -1,30 +1,25 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; -import java.io.IOException; import java.util.ArrayList; import de.deadlocker8.budgetmaster.logic.Budget; import de.deadlocker8.budgetmaster.logic.FilterSettings; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.Payment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.Refreshable; -import de.deadlocker8.budgetmaster.ui.cells.PaymentCell; +import de.deadlocker8.budgetmasterclient.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.PaymentCell; import fontAwesome.FontIconType; import javafx.application.Platform; import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.event.EventHandler; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ListCell; @@ -32,14 +27,12 @@ import javafx.scene.control.ListView; import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; -import javafx.stage.Modality; -import javafx.stage.Stage; import javafx.util.Callback; import logger.Logger; import tools.ConvertTo; import tools.Localization; -public class PaymentController implements Refreshable +public class PaymentController implements Refreshable, Styleable { @FXML private AnchorPane anchorPaneMain; @FXML private Label labelIncome; @@ -51,6 +44,7 @@ public class PaymentController implements Refreshable @FXML private Button buttonNewIncome; @FXML private Button buttonFilter; @FXML private Button buttonNewPayment; + @FXML private Button buttonSearch; private Controller controller; @@ -65,22 +59,17 @@ public class PaymentController implements Refreshable public ListCell<Payment> call(ListView<Payment> param) { PaymentCell cell = new PaymentCell(thisController); - cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() - { - @Override - public void handle(MouseEvent event) - { - if(event.getClickCount() == 2) - { - // don't allow editing of payment "rest" - if(cell.getItem().getCategoryID() != 2) - { - payment(!cell.getItem().isIncome(), true, cell.getItem()); - } + cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> { + if(event.getClickCount() == 2) + { + // don't allow editing of payment "rest" + if(cell.getItem().getCategoryID() != 2) + { + payment(!cell.getItem().isIncome(), true, cell.getItem()); } } }); - cell.prefWidthProperty().bind(listView.widthProperty().subtract(2)); + cell.prefWidthProperty().bind(listView.widthProperty().subtract(20)); return cell; } }); @@ -89,36 +78,9 @@ public class PaymentController implements Refreshable labelPlaceholder.setStyle("-fx-font-size: 16"); listView.setPlaceholder(labelPlaceholder); - listView.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() - { - @Override - public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) - { - Platform.runLater(new Runnable() - { - public void run() - { - listView.getSelectionModel().select(-1); - } - }); - } - }); - - buttonNewIncome.setGraphic(Helpers.getFontIcon(FontIconType.DOWNLOAD, 18, Color.WHITE)); - buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 18, Color.WHITE)); - buttonNewPayment.setGraphic(Helpers.getFontIcon(FontIconType.UPLOAD, 18, Color.WHITE)); - labelFilterActive.setGraphic(Helpers.getFontIcon(FontIconType.WARNING, 13, Colors.TEXT)); + listView.getSelectionModel().selectedIndexProperty().addListener((ChangeListener<Number>)(observable, oldValue, newValue) -> Platform.runLater(() -> listView.getSelectionModel().select(-1))); - // apply theme - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - labelIncome.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelIncomes.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelPayment.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelPayments.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelFilterActive.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - buttonNewIncome.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - buttonFilter.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - buttonNewPayment.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + applyStyle(); } public void newIncome() @@ -132,42 +94,11 @@ public class PaymentController implements Refreshable } public void payment(boolean isPayment, boolean edit, Payment payment) - { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent root = (Parent)fxmlLoader.load(); - Stage newStage = new Stage(); - newStage.initOwner(controller.getStage()); - newStage.initModality(Modality.APPLICATION_MODAL); - String titlePart; - - titlePart = isPayment ? Localization.getString(Strings.TITLE_PAYMENT) : Localization.getString(Strings.TITLE_INCOME); - - if(edit) - { - newStage.setTitle(Localization.getString(Strings.TITLE_PAYMENT_EDIT, titlePart)); - } - else - { - newStage.setTitle(Localization.getString(Strings.TITLE_PAYMENT_NEW, titlePart)); - } - - newStage.setScene(new Scene(root)); - newStage.getIcons().add(controller.getIcon()); - newStage.setResizable(false); - NewPaymentController newController = fxmlLoader.getController(); - newController.init(newStage, controller, this, isPayment, edit, payment); - newStage.show(); - } - catch(IOException e) - { - Logger.error(e); - } + { + new NewPaymentController(controller.getStage(), controller, this, isPayment, edit, payment); } - private void refreshListView() + private void refreshListView(Payment selectedPayment) { listView.getItems().clear(); @@ -175,6 +106,7 @@ public class PaymentController implements Refreshable if(payments != null) { listView.getItems().setAll(payments); + listView.scrollTo(controller.getPaymentHandler().getPosition(selectedPayment)); } } @@ -200,7 +132,7 @@ public class PaymentController implements Refreshable } catch(Exception e) { - e.printStackTrace(); + Logger.error(e); controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); } } @@ -215,7 +147,7 @@ public class PaymentController implements Refreshable } catch(Exception e) { - e.printStackTrace(); + Logger.error(e); controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); } } @@ -234,33 +166,19 @@ public class PaymentController implements Refreshable } catch(Exception e) { - e.printStackTrace(); + Logger.error(e); controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); } } public void filter() + { + new FilterController(controller.getStage(), controller, controller.getFilterSettings()); + } + + public void search() { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent root = (Parent)fxmlLoader.load(); - Stage newStage = new Stage(); - newStage.initOwner(controller.getStage()); - newStage.initModality(Modality.APPLICATION_MODAL); - newStage.setTitle(Localization.getString(Strings.TITLE_FILTER)); - newStage.setScene(new Scene(root)); - newStage.getIcons().add(controller.getIcon()); - newStage.setResizable(false); - FilterController newController = fxmlLoader.getController(); - newController.init(newStage, controller, controller.getFilterSettings()); - newStage.showAndWait(); - } - catch(IOException e) - { - Logger.error(e); - } + new SearchController(controller.getStage(), controller); } public Controller getController() @@ -271,7 +189,7 @@ public class PaymentController implements Refreshable @Override public void refresh() { - refreshListView(); + refreshListView(controller.getSelectedPayment()); refreshCounter(); if(controller.getFilterSettings().equals(new FilterSettings())) @@ -283,4 +201,25 @@ public class PaymentController implements Refreshable labelFilterActive.setVisible(true); } } + + @Override + public void applyStyle() + { + buttonNewIncome.setGraphic(Helpers.getFontIcon(FontIconType.DOWNLOAD, 18, Color.WHITE)); + buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 18, Color.WHITE)); + buttonNewPayment.setGraphic(Helpers.getFontIcon(FontIconType.UPLOAD, 18, Color.WHITE)); + labelFilterActive.setGraphic(Helpers.getFontIcon(FontIconType.WARNING, 13, Colors.TEXT)); + buttonSearch.setGraphic(Helpers.getFontIcon(FontIconType.SEARCH, 18, Color.WHITE)); + + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + labelIncome.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelIncomes.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelPayment.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelPayments.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelFilterActive.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + buttonNewIncome.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + buttonFilter.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + buttonNewPayment.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + buttonSearch.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ReportController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ReportController.java similarity index 75% rename from src/de/deadlocker8/budgetmaster/ui/controller/ReportController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ReportController.java index 81da39453c883d315ec8d04c095094739c083245..a99a28ee7b3f6ae657f70273fcabfbf49deee779 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/ReportController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/ReportController.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.awt.Desktop; import java.io.File; @@ -14,10 +14,10 @@ import org.joda.time.DateTime; import de.deadlocker8.budgetmaster.logic.Budget; import de.deadlocker8.budgetmaster.logic.FilterSettings; -import de.deadlocker8.budgetmaster.logic.Payment; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; import de.deadlocker8.budgetmaster.logic.comparators.DateComparator; import de.deadlocker8.budgetmaster.logic.comparators.RatingComparator; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; import de.deadlocker8.budgetmaster.logic.report.ColumnFilter; import de.deadlocker8.budgetmaster.logic.report.ColumnOrder; import de.deadlocker8.budgetmaster.logic.report.ColumnType; @@ -25,50 +25,51 @@ import de.deadlocker8.budgetmaster.logic.report.ReportGenerator; import de.deadlocker8.budgetmaster.logic.report.ReportItem; import de.deadlocker8.budgetmaster.logic.report.ReportPreferences; import de.deadlocker8.budgetmaster.logic.report.ReportSorting; +import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; +import de.deadlocker8.budgetmaster.logic.tag.TagHandler; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.FileHelper; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Refreshable; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.report.table.ReportTableRatingCell; +import de.deadlocker8.budgetmasterclient.ui.cells.report.table.ReportTableRepeatingCell; +import de.deadlocker8.budgetmasterclient.utils.UIHelpers; import fontAwesome.FontIconType; 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.fxml.FXML; -import javafx.fxml.FXMLLoader; import javafx.geometry.Pos; import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.Scene; 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.CheckBox; +import javafx.scene.control.DialogPane; import javafx.scene.control.Label; -import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; -import javafx.scene.control.TableColumn.CellDataFeatures; import javafx.scene.control.TableColumn.SortType; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.stage.FileChooser; -import javafx.stage.Modality; import javafx.stage.Stage; -import javafx.util.Callback; import logger.Logger; import tools.AlertGenerator; import tools.ConvertTo; import tools.Localization; import tools.Worker; -public class ReportController implements Refreshable +public class ReportController implements Refreshable, Styleable { @FXML private AnchorPane anchorPaneMain; @FXML private Label labelPayments; @@ -82,7 +83,8 @@ public class ReportController implements Refreshable private Controller controller; private ColumnFilter columnFilter; - private String initialReportPath; + private String initialReportFileName; + private ReportPreferences reportPreferences; private TableColumn<ReportItem, Integer> columnPosition; private TableColumn<ReportItem, String> columnDate; @@ -90,28 +92,15 @@ public class ReportController implements Refreshable private TableColumn<ReportItem, String> columnCategory; private TableColumn<ReportItem, Integer> columnName; private TableColumn<ReportItem, String> columnDescription; + private TableColumn<ReportItem, String> columnTags; private TableColumn<ReportItem, Integer> columnRating; private TableColumn<ReportItem, String> columnAmount; public void init(Controller controller) { this.controller = controller; - - buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 18, Color.WHITE)); - buttonGenerate.setGraphic(Helpers.getFontIcon(FontIconType.COGS, 18, Color.WHITE)); - labelFilterActive.setGraphic(Helpers.getFontIcon(FontIconType.WARNING, 16, Colors.TEXT)); - initTable(); - - // apply theme - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - labelFilterActive.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - buttonFilter.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - buttonGenerate.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - checkBoxIncludeBudget.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-size: 14;"); - checkBoxSplitTable.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-size: 14;"); - checkBoxIncludeCategoryBudgets.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-size: 14;"); - + applyStyle(); applyReportPreferences(); } @@ -191,6 +180,15 @@ public class ReportController implements Refreshable tableView.getSortOrder().add(columnIsRepeating); } break; + case TAGS: + initColumnTags(activated); + toggleColumn(columnTags, activated); + if(sortType != null) + { + columnTags.setSortType(sortType); + tableView.getSortOrder().add(columnTags); + } + break; default: break; } @@ -203,7 +201,7 @@ public class ReportController implements Refreshable Object loadedObject = FileHelper.loadObjectFromJSON("reportPreferences", new ReportPreferences()); if(loadedObject != null) { - ReportPreferences reportPreferences = (ReportPreferences)loadedObject; + reportPreferences = (ReportPreferences)loadedObject; checkBoxIncludeBudget.setSelected(reportPreferences.isIncludeBudget()); checkBoxSplitTable.setSelected(reportPreferences.isSplitTable()); checkBoxIncludeCategoryBudgets.setSelected(reportPreferences.isIncludeCategoryBudgets()); @@ -268,27 +266,22 @@ public class ReportController implements Refreshable { columnDate = new TableColumn<>(); columnDate.setUserData(ColumnType.DATE); - columnDate.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ReportItem, String>, ObservableValue<String>>() - { - @Override - public ObservableValue<String> call(CellDataFeatures<ReportItem, String> param) - { - String dateString = param.getValue().getDate(); - try - { - DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - Date date = format.parse(dateString); - DateFormat finalFormat = new SimpleDateFormat("dd.MM.yy"); - dateString = finalFormat.format(date); - return new SimpleStringProperty(dateString); - } - catch(Exception e) - { - Logger.error(e); - return null; - } - } - }); + columnDate.setCellValueFactory(param -> { + String dateString = param.getValue().getDate(); + try + { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Date date = format.parse(dateString); + DateFormat finalFormat = new SimpleDateFormat("dd.MM.yy"); + dateString = finalFormat.format(date); + return new SimpleStringProperty(dateString); + } + catch(Exception e) + { + Logger.error(e); + return null; + } + }); columnDate.setStyle("-fx-alignment: CENTER;"); HBox hboxColumnDate = new HBox(); @@ -315,40 +308,9 @@ public class ReportController implements Refreshable columnIsRepeating = new TableColumn<>(); columnIsRepeating.setUserData(ColumnType.REPEATING); columnIsRepeating.setCellValueFactory(new PropertyValueFactory<ReportItem, Boolean>("repeating")); - columnIsRepeating.setCellFactory(new Callback<TableColumn<ReportItem, Boolean>, TableCell<ReportItem, Boolean>>() - { - @Override - public TableCell<ReportItem, Boolean> call(TableColumn<ReportItem, Boolean> param) - { - TableCell<ReportItem, Boolean> cell = new TableCell<ReportItem, Boolean>() - { - @Override - public void updateItem(Boolean item, boolean empty) - { - if(!empty) - { - Label labelRepeating = new Label(); - if(item) - { - labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 16, Colors.TEXT)); - } - else - { - labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 16, Color.TRANSPARENT)); - } - labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121"); - labelRepeating.setAlignment(Pos.CENTER); - setGraphic(labelRepeating); - } - else - { - setGraphic(null); - } - } - }; - return cell; - } - }); + columnIsRepeating.setCellFactory(param -> { + return new ReportTableRepeatingCell(); + }); columnIsRepeating.setStyle("-fx-alignment: CENTER;"); HBox hboxColumnIsRepeating = new HBox(); @@ -374,14 +336,7 @@ public class ReportController implements Refreshable { columnCategory = new TableColumn<>(); columnCategory.setUserData(ColumnType.CATEGORY); - columnCategory.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ReportItem, String>, ObservableValue<String>>() - { - @Override - public ObservableValue<String> call(CellDataFeatures<ReportItem, String> param) - { - return new SimpleStringProperty(param.getValue().getCategory().getName()); - } - }); + columnCategory.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getCategory().getName())); columnCategory.setStyle("-fx-alignment: CENTER;"); HBox hboxColumnCategory = new HBox(); @@ -451,46 +406,40 @@ public class ReportController implements Refreshable columnDescription.setGraphic(hboxColumnDescription); tableView.getColumns().add(columnDescription); } + + private void initColumnTags(boolean activated) + { + columnTags = new TableColumn<>(); + columnTags.setUserData(ColumnType.TAGS); + columnTags.setCellValueFactory(new PropertyValueFactory<ReportItem, String>("tags")); + columnTags.setStyle("-fx-alignment: CENTER;"); + + HBox hboxColumnTags = new HBox(); + hboxColumnTags.setAlignment(Pos.CENTER); + hboxColumnTags.setSpacing(3); + + CheckBox checkBoxTags = new CheckBox(); + hboxColumnTags.getChildren().add(checkBoxTags); + + Label labelColumnTags = new Label(Localization.getString(Strings.REPORT_TAGS)); + hboxColumnTags.getChildren().add(labelColumnTags); + + checkBoxTags.selectedProperty().addListener((a, b, c)->{ + toggleColumn(columnTags, c); + }); + checkBoxTags.setSelected(activated); + columnTags.setGraphic(hboxColumnTags); + tableView.getColumns().add(columnTags); + } private void initColumnRating(boolean activated) { columnRating = new TableColumn<>(); columnRating.setUserData(ColumnType.RATING); columnRating.setCellValueFactory(new PropertyValueFactory<ReportItem, Integer>("amount")); - columnRating.setCellFactory(new Callback<TableColumn<ReportItem, Integer>, TableCell<ReportItem, Integer>>() - { - @Override - public TableCell<ReportItem, Integer> call(TableColumn<ReportItem, Integer> param) - { - TableCell<ReportItem, Integer> cell = new TableCell<ReportItem, Integer>() - { - @Override - public void updateItem(Integer item, boolean empty) - { - if(!empty) - { - Label labelRepeating = new Label(); - if(item > 0) - { - labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.PLUS, 14, Colors.TEXT)); - } - else - { - labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.MINUS, 14, Colors.TEXT)); - } - labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121"); - labelRepeating.setAlignment(Pos.CENTER); - setGraphic(labelRepeating); - } - else - { - setGraphic(null); - } - } - }; - return cell; - } - }); + columnRating.setCellFactory(param -> { + return new ReportTableRatingCell(); + }); columnRating.setStyle("-fx-alignment: CENTER;"); HBox hboxColumnRating = new HBox(); @@ -527,17 +476,12 @@ public class ReportController implements Refreshable { columnAmount = new TableColumn<>(); columnAmount.setUserData(ColumnType.AMOUNT); - columnAmount.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ReportItem, String>, ObservableValue<String>>() - { - @Override - public ObservableValue<String> call(CellDataFeatures<ReportItem, String> param) - { - StringProperty value = new SimpleStringProperty(); - double amount = param.getValue().getAmount() / 100.0; - value.set(Helpers.getCurrencyString(amount, controller.getSettings().getCurrency())); - return value; - } - }); + columnAmount.setCellValueFactory(param -> { + StringProperty value = new SimpleStringProperty(); + double amount = param.getValue().getAmount() / 100.0; + value.set(Helpers.getCurrencyString(amount, controller.getSettings().getCurrency())); + return value; + }); columnAmount.setStyle("-fx-alignment: CENTER;"); HBox hboxColumnAmount = new HBox(); @@ -575,31 +519,14 @@ public class ReportController implements Refreshable public void filter() { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent root = (Parent)fxmlLoader.load(); - Stage newStage = new Stage(); - newStage.initOwner(controller.getStage()); - newStage.initModality(Modality.APPLICATION_MODAL); - newStage.setTitle(Localization.getString(Strings.TITLE_FILTER)); - newStage.setScene(new Scene(root)); - newStage.getIcons().add(controller.getIcon()); - newStage.setResizable(false); - FilterController newController = fxmlLoader.getController(); - newController.init(newStage, controller, controller.getFilterSettings()); - newStage.show(); - } - catch(IOException e) - { - Logger.error(e); - } + new FilterController(controller.getStage(), controller, controller.getFilterSettings()); } private ArrayList<ReportItem> createReportItems(ArrayList<Payment> payments) { ArrayList<ReportItem> reportItems = new ArrayList<>(); + TagHandler tagHander = new TagHandler(controller.getSettings()); + for(int i = 0; i < payments.size(); i++) { Payment currentPayment = payments.get(i); @@ -607,10 +534,20 @@ public class ReportController implements Refreshable reportItem.setPosition(i + 1); reportItem.setDate(currentPayment.getDate()); reportItem.setAmount(currentPayment.getAmount()); - reportItem.setDescription(currentPayment.getDescription()); reportItem.setName(currentPayment.getName()); + reportItem.setDescription(currentPayment.getDescription()); reportItem.setRepeating(currentPayment instanceof RepeatingPaymentEntry); reportItem.setCategory(controller.getCategoryHandler().getCategory(currentPayment.getCategoryID())); + + try + { + reportItem.setTags(tagHander.getTagsAsString(currentPayment)); + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); + } reportItems.add(reportItem); } @@ -620,14 +557,16 @@ public class ReportController implements Refreshable private void refreshTableView() { - tableView.getItems().clear(); + Platform.runLater(()->{tableView.getItems().clear();}); ArrayList<Payment> payments = controller.getPaymentHandler().getPayments(); if(payments != null) { ArrayList<ReportItem> reportItems = createReportItems(payments); - ObservableList<ReportItem> objectsForTable = FXCollections.observableArrayList(reportItems); - tableView.setItems(objectsForTable); + Platform.runLater(()->{; + ObservableList<ReportItem> objectsForTable = FXCollections.observableArrayList(reportItems); + tableView.setItems(objectsForTable); + }); } } @@ -654,16 +593,23 @@ public class ReportController implements Refreshable { reportSorting.setColumnType(ColumnType.DATE); reportSorting.setSortType(SortType.DESCENDING); - } + } + + String reportFolderPath = null; + if(reportPreferences != null) + { + reportFolderPath = reportPreferences.getReportFolderPath(); + } return new ReportPreferences(columnOrder, checkBoxIncludeBudget.isSelected(), checkBoxSplitTable.isSelected(), checkBoxIncludeCategoryBudgets.isSelected(), - reportSorting); + reportSorting, + reportFolderPath); } - private void saveReportPreferences(ReportPreferences reportPreferences) + private void saveReportPreferences() { try { @@ -676,20 +622,28 @@ public class ReportController implements Refreshable } public void generate() - { - ReportPreferences reportPreferences = getReportPreferences(); - saveReportPreferences(reportPreferences); - + { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle(Localization.getString(Strings.TITLE_REPORT_SAVE)); FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PDF (*.pdf)", "*.pdf"); - fileChooser.setInitialFileName(initialReportPath); - fileChooser.getExtensionFilters().add(extFilter); - File file = fileChooser.showSaveDialog(controller.getStage()); + fileChooser.setInitialFileName(initialReportFileName); + fileChooser.getExtensionFilters().add(extFilter); + + String initialReportFolder = reportPreferences.getReportFolderPath(); + if(initialReportFolder != null) + { + fileChooser.setInitialDirectory(new File(initialReportFolder)); + } + + File file = fileChooser.showSaveDialog(controller.getStage()); if(file != null) { Budget budget = new Budget(controller.getPaymentHandler().getPayments()); + reportPreferences = getReportPreferences(); + reportPreferences.setReportFolderPath(file.getParentFile().getAbsolutePath()); + saveReportPreferences(); + ReportGenerator reportGenerator = new ReportGenerator(new ArrayList<ReportItem>(tableView.getItems()), controller.getCategoryBudgets(), reportPreferences, @@ -698,7 +652,7 @@ public class ReportController implements Refreshable controller.getCurrentDate(), budget); - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_REPORT), controller.getStage(), controller.getIcon()); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_REPORT), controller.getStage(), controller.getIcon()); Worker.runLater(() -> { try @@ -716,6 +670,7 @@ public class ReportController implements Refreshable Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle(Localization.getString(Strings.INFO_TITLE_REPORT_SAVE)); alert.setHeaderText(""); + alert.initOwner(controller.getStage()); alert.setContentText(Localization.getString(Strings.INFO_TEXT_REPORT_SAVE)); Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); dialogStage.getIcons().add(controller.getIcon()); @@ -725,6 +680,14 @@ public class ReportController implements Refreshable ButtonType buttonTypeThree = new ButtonType(Localization.getString(Strings.OK)); alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree); + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getButtonTypes().stream().map(dialogPane::lookupButton).forEach(button -> button.addEventHandler(KeyEvent.KEY_PRESSED, (event) -> { + if(KeyCode.ENTER.equals(event.getCode()) && event.getTarget() instanceof Button) + { + ((Button)event.getTarget()).fire(); + } + })); + Optional<ButtonType> result = alert.showAndWait(); if (result.get() == buttonTypeOne) { @@ -800,6 +763,8 @@ public class ReportController implements Refreshable @Override public void refresh() { + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_REPORT_TAB), controller.getStage(), controller.getIcon()); + if(controller.getFilterSettings().equals(new FilterSettings())) { labelFilterActive.setVisible(false); @@ -809,15 +774,43 @@ public class ReportController implements Refreshable labelFilterActive.setVisible(true); } - saveReportPreferences(getReportPreferences()); - refreshTableView(); - applyReportPreferences(); - tableView.refresh(); - DateTime currentDate = controller.getCurrentDate(); String currentMonth = currentDate.toString("MM"); String currentYear = currentDate.toString("YYYY"); - initialReportPath = Localization.getString(Strings.REPORT_INITIAL_FILENAME, currentYear, currentMonth); + initialReportFileName = Localization.getString(Strings.REPORT_INITIAL_FILENAME, currentYear, currentMonth); + + reportPreferences = getReportPreferences(); + saveReportPreferences(); + + Worker.runLater(() -> { + refreshTableView(); + + Platform.runLater(() -> { + if(modalStage != null) + { + modalStage.close(); + } + + applyReportPreferences(); + tableView.refresh(); + }); + }); + } + + @Override + public void applyStyle() + { + buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 18, Color.WHITE)); + buttonGenerate.setGraphic(Helpers.getFontIcon(FontIconType.COGS, 18, Color.WHITE)); + labelFilterActive.setGraphic(Helpers.getFontIcon(FontIconType.WARNING, 16, Colors.TEXT)); + + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + labelFilterActive.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + buttonFilter.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + buttonGenerate.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + checkBoxIncludeBudget.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-size: 14;"); + checkBoxSplitTable.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-size: 14;"); + checkBoxIncludeCategoryBudgets.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT) + "; -fx-font-size: 14;"); } } \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SearchController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SearchController.java new file mode 100644 index 0000000000000000000000000000000000000000..1fab017b8c4b1537d727d2b6798dcc4e0f380c50 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SearchController.java @@ -0,0 +1,332 @@ +package de.deadlocker8.budgetmasterclient.ui.controller; + +import java.util.ArrayList; + +import org.controlsfx.control.RangeSlider; + +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.search.SearchPreferences; +import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.SearchCell; +import de.deadlocker8.budgetmasterclient.utils.UIHelpers; +import fontAwesome.FontIconType; +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.fxml.FXML; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.TextField; +import javafx.scene.control.TextFormatter; +import javafx.scene.input.KeyCode; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.paint.Color; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.util.Callback; +import logger.Logger; +import tools.ConvertTo; +import tools.Localization; +import tools.Worker; + +public class SearchController extends BaseController implements Styleable +{ + @FXML private CheckBox checkBoxName; + @FXML private CheckBox checkBoxDescription; + @FXML private CheckBox checkBoxCategoryName; + @FXML private CheckBox checkBoxTags; + @FXML private TextField textFieldSearch; + @FXML private CheckBox checkBoxSearchByAmount; + @FXML private TextField textFieldAmountMin; + @FXML private TextField textFieldAmountMax; + @FXML private HBox hboxRangeSlider; + @FXML private Label labelSeparator; + @FXML private HBox hboxSearchByAmount; + @FXML private Button buttonCancel; + @FXML private Button buttonSearch; + @FXML private ListView<Payment> listView; + + private Stage parentStage; + private Controller controller; + private RangeSlider rangeSlider; + + public SearchController(Stage parentStage, Controller controller) + { + this.parentStage = parentStage; + this.controller = controller; + load("/de/deadlocker8/budgetmaster/ui/fxml/SearchGUI.fxml", Localization.getBundle()); + getStage().showAndWait(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setTitle(Localization.getString(Strings.TITLE_SEARCH)); + stage.getIcons().add(controller.getIcon()); + stage.setResizable(true); + stage.setMinWidth(500); + stage.setMinHeight(500); + stage.setWidth(650); + } + + @Override + public void init() + { + SearchController thisController = this; + listView.setCellFactory(new Callback<ListView<Payment>, ListCell<Payment>>() + { + @Override + public ListCell<Payment> call(ListView<Payment> param) + { + SearchCell cell = new SearchCell(thisController); + cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> { + if(event.getClickCount() == 2) + { + // don't allow editing of payment "rest" + if(cell.getItem().getCategoryID() != 2) + { + controller.getPaymentController().payment(!cell.getItem().isIncome(), true, cell.getItem()); + } + } + }); + cell.prefWidthProperty().bind(listView.widthProperty().subtract(2)); + return cell; + } + }); + + Label labelPlaceholder = new Label(Localization.getString(Strings.PAYMENTS_PLACEHOLDER)); + labelPlaceholder.setStyle("-fx-font-size: 16"); + listView.setPlaceholder(labelPlaceholder); + + listView.getSelectionModel().selectedIndexProperty().addListener((ChangeListener<Number>)(observable, oldValue, newValue) -> Platform.runLater(() -> listView.getSelectionModel().select(-1))); + + checkBoxName.setSelected(true); + + textFieldSearch.setOnKeyPressed((event)->{ + if(event.getCode().equals(KeyCode.ENTER)) + { + search(); + } + }); + + checkBoxSearchByAmount.selectedProperty().addListener((a, b, c)->{ + hboxSearchByAmount.setDisable(!c); + }); + + hboxSearchByAmount.setDisable(true); + + int maximum; + try + { + maximum = getMaxAmountFromServer(); + } + catch(Exception e) + { + Logger.error(e); + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); + return; + } + + rangeSlider = new RangeSlider(); + rangeSlider.setMin(0); + rangeSlider.setMax(maximum); + rangeSlider.setLowValue(rangeSlider.getMin()); + rangeSlider.setHighValue(rangeSlider.getMax()); + rangeSlider.setShowTickMarks(true); + rangeSlider.setShowTickLabels(true); + rangeSlider.setMajorTickUnit(getMayorTickUnit(maximum)); + rangeSlider.setMinorTickCount(0); + rangeSlider.lowValueProperty().addListener((a, b, c)->{ + textFieldAmountMin.setText(String.valueOf(c.intValue())); + }); + rangeSlider.highValueProperty().addListener((a, b, c)->{ + textFieldAmountMax.setText(String.valueOf(c.intValue())); + }); + hboxRangeSlider.getChildren().add(rangeSlider); + hboxRangeSlider.setAlignment(Pos.CENTER); + HBox.setHgrow(rangeSlider, Priority.ALWAYS); + + textFieldAmountMin.setTextFormatter(new TextFormatter<>(c -> { + if(c.getControlNewText().isEmpty() || c.getControlNewText().matches("[0-9]*")) + { + return c; + } + else + { + return null; + } + })); + + textFieldAmountMax.setTextFormatter(new TextFormatter<>(c -> { + if(c.getControlNewText().isEmpty() || c.getControlNewText().matches("[0-9]*")) + { + return c; + } + else + { + return null; + } + })); + + textFieldAmountMin.textProperty().addListener((a, b, c)->{ + setRangeSliderAmountMin(); + }); + + textFieldAmountMax.textProperty().addListener((a, b, c)->{ + setRangeSliderAmountMax(); + }); + + textFieldAmountMin.setText("0"); + textFieldAmountMax.setText(String.valueOf(maximum)); + + //prefill + SearchPreferences searchPreferences = controller.getSearchPreferences(); + if(controller.getSearchPreferences() != null) + { + textFieldSearch.setText(searchPreferences.getLastQuery()); + checkBoxName.setSelected(searchPreferences.isSearchName()); + checkBoxDescription.setSelected(searchPreferences.isSearchDescription()); + checkBoxCategoryName.setSelected(searchPreferences.isSearchCategorNames()); + checkBoxTags.setSelected(searchPreferences.isSearchTags()); + checkBoxSearchByAmount.setSelected(searchPreferences.isSearchAmount()); + rangeSlider.setLowValue(searchPreferences.getMinAmount()); + rangeSlider.setHighValue(searchPreferences.getMaxAmount()); + } + + applyStyle(); + } + + private void setRangeSliderAmountMin() + { + String text = textFieldAmountMin.getText(); + if(text != null && !text.equals("")) + { + rangeSlider.setLowValue(Integer.parseInt(text)); + } + } + + private void setRangeSliderAmountMax() + { + String text = textFieldAmountMax.getText(); + if(text != null && !text.equals("")) + { + rangeSlider.setHighValue(Integer.parseInt(text)); + } + } + + private int getMaxAmountFromServer() throws Exception + { + ServerConnection connection = new ServerConnection(controller.getSettings()); + return connection.getMaxAmount(); + } + + private int getMayorTickUnit(int maximum) + { + if(maximum < 10) + return 1; + + if(maximum < 100) + return 5; + + int length = String.valueOf(maximum).length(); + return (int)Math.pow(10, length-2); + } + + public void search() + { + String query = textFieldSearch.getText().trim(); + if(controller.getSearchPreferences() == null) + { + controller.setSearchPreferences(new SearchPreferences()); + } + SearchPreferences searchPreferences = controller.getSearchPreferences(); + searchPreferences.setLastQuery(query); + searchPreferences.setSearchName(checkBoxName.isSelected()); + searchPreferences.setSearchDescription(checkBoxDescription.isSelected()); + searchPreferences.setSearchCategorNames(checkBoxCategoryName.isSelected()); + searchPreferences.setSearchTags(checkBoxTags.isSelected()); + searchPreferences.setSearchAmount(checkBoxSearchByAmount.isSelected()); + searchPreferences.setMinAmount((int)rangeSlider.getLowValue()); + searchPreferences.setMaxAmount((int)rangeSlider.getHighValue()); + + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_SEARCH), getStage(), controller.getIcon()); + + Worker.runLater(() -> { + try + { + ServerConnection connection = new ServerConnection(controller.getSettings()); + ArrayList<Payment> payments = connection.getPaymentsForSearch(query, + checkBoxName.isSelected(), + checkBoxDescription.isSelected(), + checkBoxCategoryName.isSelected(), + checkBoxTags.isSelected(), + checkBoxSearchByAmount.isSelected(), + (int)rangeSlider.getLowValue()*100, + (int)rangeSlider.getHighValue()*100); + + Platform.runLater(() -> { + listView.getItems().clear(); + if(payments != null) + { + listView.getItems().setAll(payments); + } + + if(modalStage != null) + { + modalStage.close(); + } + }); + } + catch(Exception e) + { + Logger.error(e); + Platform.runLater(() -> { + if(modalStage != null) + { + modalStage.close(); + } + controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); + }); + } + }); + + textFieldSearch.requestFocus(); + textFieldSearch.positionCaret(textFieldSearch.getText().length()); + } + + public void cancel() + { + getStage().close(); + } + + public Controller getController() + { + return controller; + } + + @Override + public void applyStyle() + { + labelSeparator.setStyle("-fx-background-color: #CCCCCC;"); + labelSeparator.setMinHeight(1); + labelSeparator.setMaxHeight(1); + + buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE)); + buttonSearch.setGraphic(Helpers.getFontIcon(FontIconType.SEARCH, 17, Color.WHITE)); + + buttonCancel.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + buttonSearch.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;"); + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/SettingsController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java similarity index 87% rename from src/de/deadlocker8/budgetmaster/ui/controller/SettingsController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java index 9871c6bf1421c7e723b8d4539892649e32d84008..523b1672a4b0a793fe2c5800ad83cde6b27604ea 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/SettingsController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.io.File; import java.io.IOException; @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Optional; import de.deadlocker8.budgetmaster.logic.Settings; +import de.deadlocker8.budgetmaster.logic.database.Database; import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; import de.deadlocker8.budgetmaster.logic.updater.Updater; @@ -14,14 +15,12 @@ import de.deadlocker8.budgetmaster.logic.utils.FileHelper; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.LanguageType; import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.main.Main; -import de.deadlocker8.budgetmaster.ui.cells.LanguageCell; -import de.deadlocker8.budgetmasterserver.logic.database.Database; +import de.deadlocker8.budgetmasterclient.main.Main; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.cells.LanguageCell; +import de.deadlocker8.budgetmasterclient.utils.UIHelpers; import javafx.application.Platform; import javafx.fxml.FXML; -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.control.Button; @@ -29,14 +28,19 @@ import javafx.scene.control.ButtonBar.ButtonData; import javafx.scene.control.ButtonType; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; +import javafx.scene.control.DialogPane; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; +import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.control.TextInputDialog; import javafx.scene.control.ToggleGroup; import javafx.scene.image.Image; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; import javafx.stage.FileChooser; import javafx.stage.Stage; import logger.Logger; @@ -48,9 +52,11 @@ import tools.Localization; import tools.RandomCreations; import tools.Worker; -public class SettingsController +public class SettingsController implements Styleable { @FXML private AnchorPane anchorPaneMain; + @FXML private ScrollPane scrollPane; + @FXML private HBox hboxSettings; @FXML private Label labelClientSecret; @FXML private TextField textFieldClientSecret; @FXML private TextField textFieldURL; @@ -79,8 +85,7 @@ public class SettingsController { this.controller = controller; - textFieldClientSecret.setText("******"); - radioButtonRestDeactivated.setSelected(true); + textFieldClientSecret.setText("******"); comboBoxLanguage.setCellFactory((view) -> { return new LanguageCell(true); @@ -116,17 +121,12 @@ public class SettingsController checkboxEnableAutoUpdate.setSelected(controller.getSettings().isAutoUpdateCheckEnabled()); } + else + { + radioButtonRestDeactivated.setSelected(true); + } - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - labelClientSecret.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelSecret.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelURL.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - labelCurrency.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); - buttonSave.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - buttonExportDB.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); - buttonImportDB.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); - buttonDeleteDB.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_RED) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); - buttonSearchUpdates.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + applyStyle(); textFieldURL.setPromptText(Localization.getString(Strings.URL_PLACEHOLDER)); textFieldCurrency.setPromptText(Localization.getString(Strings.CURRENCY_PLACEHOLDER)); @@ -136,6 +136,8 @@ public class SettingsController radioButtonRestActivated.setToggleGroup(toggleGroup); radioButtonRestDeactivated.setToggleGroup(toggleGroup); + hboxSettings.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25)); + refreshLabelsUpdate(); } @@ -309,7 +311,7 @@ public class SettingsController if(controller.getSettings().isAutoUpdateCheckEnabled()) { - controller.checkForUpdates(false); + controller.checkForUpdates(false); refreshLabelsUpdate(); } @@ -327,6 +329,14 @@ public class SettingsController ButtonType buttonTypeTwo = new ButtonType(Localization.getString(Strings.INFO_TEXT_LANGUAGE_CHANGED_RESTART_LATER)); alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo); + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getButtonTypes().stream().map(dialogPane::lookupButton).forEach(button -> button.addEventHandler(KeyEvent.KEY_PRESSED, (event) -> { + if(KeyCode.ENTER.equals(event.getCode()) && event.getTarget() instanceof Button) + { + ((Button)event.getTarget()).fire(); + } + })); + Optional<ButtonType> result = alert.showAndWait(); if (result.get() == buttonTypeOne) { @@ -334,27 +344,8 @@ public class SettingsController Localization.loadLanguage(controller.getSettings().getLanguage().getLocale()); - try - { - Image icon = new Image("/de/deadlocker8/budgetmaster/resources/icon.png"); - FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml")); - loader.setResources(Localization.getBundle()); - Parent root = (Parent)loader.load(); - - Scene scene = new Scene(root, 450, 230); - - ((SplashScreenController)loader.getController()).init(Main.primaryStage, icon, false); - - Main.primaryStage.setResizable(false); - Main.primaryStage.getIcons().add(icon); - Main.primaryStage.setTitle(Localization.getString(Strings.APP_NAME)); - Main.primaryStage.setScene(scene); - Main.primaryStage.show(); - } - catch(Exception e) - { - Logger.error(e); - } + Image icon = new Image("/de/deadlocker8/budgetmaster/icon.png"); + new SplashScreenController(Main.primaryStage, icon, false); } else { @@ -372,7 +363,7 @@ public class SettingsController File file = fileChooser.showSaveDialog(controller.getStage()); if(file != null) { - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATABASE_EXPORT), controller.getStage(), controller.getIcon()); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATABASE_EXPORT), controller.getStage(), controller.getIcon()); Worker.runLater(() -> { try @@ -424,7 +415,12 @@ public class SettingsController try { database = FileHelper.loadDatabaseJSON(file); - if(database.getCategories() == null || database.getNormalPayments() == null || database.getRepeatingPayments() == null) + System.out.println(database); + if(database.getCategories() == null + || database.getNormalPayments() == null + || database.getRepeatingPayments() == null + || database.getTags() == null + || database.getTagMatches() == null) { AlertGenerator.showAlert(AlertType.ERROR, Localization.getString(Strings.TITLE_ERROR), @@ -451,7 +447,7 @@ public class SettingsController return; } - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATABASE_IMPORT), controller.getStage(), controller.getIcon()); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATABASE_IMPORT), controller.getStage(), controller.getIcon()); Worker.runLater(() -> { try @@ -509,8 +505,16 @@ public class SettingsController ButtonType buttonTypeDelete = new ButtonType(Localization.getString(Strings.INFO_TEXT_DATABASE_IMPORT_DIALOG_DELETE)); ButtonType buttonTypeAppend = new ButtonType(Localization.getString(Strings.INFO_TEXT_DATABASE_IMPORT_DIALOG_APPEND)); ButtonType buttonTypeCancel = new ButtonType(Localization.getString(Strings.CANCEL), ButtonData.CANCEL_CLOSE); - alert.getButtonTypes().setAll(buttonTypeDelete, buttonTypeAppend, buttonTypeCancel); + + DialogPane dialogPane = alert.getDialogPane(); + dialogPane.getButtonTypes().stream().map(dialogPane::lookupButton).forEach(button -> button.addEventHandler(KeyEvent.KEY_PRESSED, (event) -> { + if(KeyCode.ENTER.equals(event.getCode()) && event.getTarget() instanceof Button) + { + ((Button)event.getTarget()).fire(); + } + })); + Optional<ButtonType> result = alert.showAndWait(); if(result.get() == buttonTypeDelete) { @@ -544,7 +548,7 @@ public class SettingsController { if(result.get().equals(verificationCode)) { - Stage modalStage = Helpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATABASE_DELETE), controller.getStage(), controller.getIcon()); + Stage modalStage = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_DATABASE_DELETE), controller.getStage(), controller.getIcon()); Worker.runLater(() -> { try @@ -589,13 +593,30 @@ public class SettingsController controller.getStage(), null, false); - deleteDB(); + deleteDatabase(importPending); } } } public void checkForUpdates() { - controller.checkForUpdates(true); + controller.checkForUpdates(true); + refreshLabelsUpdate(); + } + + @Override + public void applyStyle() + { + anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); + scrollPane.setStyle("-fx-background-color: transparent"); + labelClientSecret.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelSecret.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelURL.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + labelCurrency.setStyle("-fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + buttonSave.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + buttonExportDB.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + buttonImportDB.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + buttonDeleteDB.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_RED) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); + buttonSearchUpdates.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;"); } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/SplashScreenController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SplashScreenController.java similarity index 65% rename from src/de/deadlocker8/budgetmaster/ui/controller/SplashScreenController.java rename to BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SplashScreenController.java index 810442be8db65abf86b50b66f573b35249dcd4d0..28071b5355d3ce73337c65457637e12afd880ad5 100644 --- a/src/de/deadlocker8/budgetmaster/ui/controller/SplashScreenController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SplashScreenController.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.ui.controller; +package de.deadlocker8.budgetmasterclient.ui.controller; import java.io.IOException; @@ -7,13 +7,12 @@ import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.FileHelper; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.Styleable; +import de.deadlocker8.budgetmasterclient.ui.customAlert.CustomAlertController; import fontAwesome.FontIconType; import javafx.application.Platform; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; import javafx.geometry.Insets; -import javafx.scene.Parent; -import javafx.scene.Scene; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -29,34 +28,52 @@ import tools.ConvertTo; import tools.HashUtils; import tools.Localization; -public class SplashScreenController +public class SplashScreenController extends BaseController implements Styleable { @FXML private ImageView imageViewLogo; @FXML private Label labelVersion; @FXML private PasswordField textFieldPassword; @FXML private Button buttonLogin; - private Stage stage; + private Stage parentStage; private Image icon; private Settings settings; private boolean isFirstStart; - - public void init(Stage stage, Image icon, boolean isStartingAfterUpdate) + private boolean isStartingAfterUpdate; + + public SplashScreenController(Stage parentStage, Image icon, boolean isStartingAfterUpdate) { - this.stage = stage; + this.parentStage = parentStage; this.icon = icon; - + this.isStartingAfterUpdate = isStartingAfterUpdate; + load("/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml", Localization.getBundle()); + getStage().show(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.setWidth(450); + stage.setHeight(250); + stage.setResizable(false); + stage.getIcons().add(icon); + stage.setTitle(Localization.getString(Strings.APP_NAME)); + } + + @Override + public void init() + { imageViewLogo.setImage(icon); labelVersion.setText("v" + Localization.getString(Strings.VERSION_NAME)); - buttonLogin.setGraphic(Helpers.getFontIcon(FontIconType.SIGN_IN, 18, Color.WHITE)); - buttonLogin.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - buttonLogin.setPadding(new Insets(3, 7, 3, 7)); + applyStyle(); - textFieldPassword.setOnKeyReleased((event)->{ + textFieldPassword.setOnKeyReleased((event)->{ if(event.getCode() == KeyCode.ENTER) { + event.consume(); login(); } }); @@ -69,7 +86,7 @@ public class SplashScreenController Localization.getString(Strings.INFO_HEADER_TEXT_START_AFTER_UPDATE, Localization.getString(Strings.VERSION_NAME)), Localization.getString(Strings.INFO_TEXT_START_AFTER_UPDATE), icon, - stage, + getStage(), null, false); }); @@ -87,7 +104,7 @@ public class SplashScreenController Localization.getString(Strings.INFO_HEADER_TEXT_WELCOME), Localization.getString(Strings.INFO_TEXT_WELCOME_FIRST_START), icon, - stage, + getStage(), null, false); }); @@ -104,7 +121,7 @@ public class SplashScreenController Localization.getString(Strings.INFO_HEADER_TEXT_WELCOME), Localization.getString(Strings.INFO_TEXT_WELCOME_COMPATIBILITY), icon, - stage, + getStage(), null, false); }); @@ -122,15 +139,8 @@ public class SplashScreenController String password = textFieldPassword.getText().trim(); if(password == null || password.isEmpty()) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_EMPTY_PASSWORD), - icon, - stage, - null, - false); - return; + new CustomAlertController(getStage(), this, AlertType.WARNING, Localization.getString(Strings.TITLE_WARNING), Localization.getString(Strings.WARNING_EMPTY_PASSWORD)); + return; } if(isFirstStart) @@ -141,20 +151,14 @@ public class SplashScreenController { FileHelper.saveSettings(settings); - stage.close(); + getStage().close(); openBudgetMaster(); } catch(IOException e) { Logger.error(e); - AlertGenerator.showAlert(AlertType.ERROR, - Localization.getString(Strings.TITLE_ERROR), - "", - Localization.getString(Strings.ERROR_PASSWORD_SAVE), - icon, - stage, - null, - false); + new CustomAlertController(getStage(), this, AlertType.WARNING, Localization.getString(Strings.TITLE_ERROR), Localization.getString(Strings.ERROR_PASSWORD_SAVE)); + return; } } else @@ -162,44 +166,30 @@ public class SplashScreenController //check password if(!HashUtils.hash(password, Helpers.SALT).equals(settings.getClientSecret())) { - AlertGenerator.showAlert(AlertType.WARNING, - Localization.getString(Strings.TITLE_WARNING), - "", - Localization.getString(Strings.WARNING_WRONG_PASSWORD), - icon, - stage, - null, - false); + new CustomAlertController(getStage(), this, AlertType.WARNING, Localization.getString(Strings.TITLE_WARNING), Localization.getString(Strings.WARNING_WRONG_PASSWORD)); return; } - stage.close(); + getStage().close(); openBudgetMaster(); } } private void openBudgetMaster() { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent root = (Parent)fxmlLoader.load(); - Stage newStage = new Stage(); - newStage.setTitle(Localization.getString(Strings.APP_NAME)); - newStage.setScene(new Scene(root, 650, 700)); - newStage.getIcons().add(icon); - newStage.setResizable(true); - newStage.setMinHeight(650); - newStage.setMinWidth(610); - newStage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css"); - Controller newController = fxmlLoader.getController(); - newController.init(newStage, settings); - newStage.show(); - } - catch(IOException e) - { - Logger.error(e); - } + new Controller(settings); + } + + public Image getIcon() + { + return icon; + } + + @Override + public void applyStyle() + { + buttonLogin.setGraphic(Helpers.getFontIcon(FontIconType.SIGN_IN, 18, Color.WHITE)); + buttonLogin.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); + buttonLogin.setPadding(new Insets(3, 7, 3, 7)); } } \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlert.fxml b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlert.fxml new file mode 100644 index 0000000000000000000000000000000000000000..8d850119d369ce4a86164590ee6aee6590961979 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlert.fxml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.image.ImageView?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> + +<AnchorPane fx:id="anchorPaneMain" prefHeight="90.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <VBox layoutX="14.0" layoutY="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <children> + <HBox spacing="14.0" VBox.vgrow="ALWAYS"> + <children> + <ImageView fx:id="imageView" fitHeight="45.0" fitWidth="45.0" pickOnBounds="true" preserveRatio="true" /> + <Label fx:id="labelMessage" maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS"> + <HBox.margin> + <Insets top="3.0" /> + </HBox.margin></Label> + </children> + </HBox> + <HBox alignment="CENTER_RIGHT"> + <children> + <Button minWidth="75.0" mnemonicParsing="false" onAction="#confirm" prefWidth="75.0" text="%ok" /> + </children> + </HBox> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlertController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlertController.java new file mode 100644 index 0000000000000000000000000000000000000000..79e903d39f15162f8b838e43ac3e60467756e2ea --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlertController.java @@ -0,0 +1,87 @@ +package de.deadlocker8.budgetmasterclient.ui.customAlert; + +import de.deadlocker8.budgetmasterclient.ui.controller.BaseController; +import de.deadlocker8.budgetmasterclient.ui.controller.SplashScreenController; +import javafx.fxml.FXML; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Modality; +import javafx.stage.Stage; +import tools.Localization; + +public class CustomAlertController extends BaseController +{ + @FXML private AnchorPane anchorPaneMain; + @FXML private ImageView imageView; + @FXML private Label labelMessage; + + private Stage parentStage; + private SplashScreenController controller; + private AlertType alertType; + private String title; + private String message; + + public CustomAlertController(Stage parentStage, SplashScreenController controller, AlertType alertType, String title, String message) + { + this.parentStage = parentStage; + this.controller = controller; + this.alertType = alertType; + this.title = title; + this.message = message; + load("/de/deadlocker8/budgetmaster/ui/customAlert/CustomAlert.fxml", Localization.getBundle()); + getStage().showAndWait(); + } + + @Override + public void initStage(Stage stage) + { + stage.initOwner(parentStage); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setTitle(title); + stage.getIcons().add(controller.getIcon()); + stage.setResizable(false); + } + + @Override + public void init() + { + labelMessage.setText(message); + + getStage().getScene().setOnKeyReleased((event)->{ + event.consume(); + if(event.getCode().equals(KeyCode.ENTER)) + { + confirm(); + } + }); + + switch(alertType) + { + case CONFIRMATION: + imageView.setImage(new Image("/com/sun/javafx/scene/control/skin/modena/dialog-confirmation.png")); + break; + case ERROR: + imageView.setImage(new Image("/com/sun/javafx/scene/control/skin/modena/dialog-error.png")); + break; + case INFORMATION: + imageView.setImage(new Image("/com/sun/javafx/scene/control/skin/modena/dialog-information.png")); + break; + case WARNING: + imageView.setImage(new Image("/com/sun/javafx/scene/control/skin/modena/dialog-warning.png")); + break; + default: + imageView.setImage(new Image("/com/sun/javafx/scene/control/skin/modena/dialog-information.png")); + break; + } + } + + @FXML + public void confirm() + { + getStage().close(); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/tagField/TagField.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/tagField/TagField.java new file mode 100644 index 0000000000000000000000000000000000000000..536a52cdcf4cd1c33542a1170e4ad3895a4b64ea --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/tagField/TagField.java @@ -0,0 +1,223 @@ +package de.deadlocker8.budgetmasterclient.ui.tagField; + +import java.util.ArrayList; +import java.util.Collection; + +import org.controlsfx.control.textfield.AutoCompletionBinding; +import org.controlsfx.control.textfield.TextFields; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmaster.logic.utils.Colors; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.controller.NewPaymentController; +import fontAwesome.FontIconType; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.ScrollPane.ScrollBarPolicy; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import javafx.util.Callback; +import tools.AlertGenerator; +import tools.ConvertTo; +import tools.Localization; + +public class TagField extends VBox +{ + private ArrayList<Tag> tags; + private ArrayList<Tag> allTags; + private HBox hboxTags; + private TextField textField; + private NewPaymentController parentController; + + public TagField(ArrayList<Tag> tags, ArrayList<Tag> allAvailableTags, NewPaymentController parentController) + { + this.tags = tags; + this.allTags = allAvailableTags; + this.parentController = parentController; + + this.hboxTags = initHboxTags(); + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setContent(hboxTags); + scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER); + scrollPane.setMinHeight(50); + scrollPane.setStyle("-fx-background-color: #FFFFFF; -fx-background-radius: 5px; -fx-border-color: #000000; -fx-border-width: 1 1 0 1; -fx-border-radius: 5px 5px 0 0"); + + this.getChildren().add(scrollPane); + VBox.setVgrow(scrollPane, Priority.ALWAYS); + + textField = new TextField(); + textField.setStyle("-fx-background-color: #FFFFFF; -fx-border-color: #000000; -fx-border-width: 1; -fx-background-radius: 5px; -fx-border-radius: 0 0 5px 5px"); + textField.setPromptText(Localization.getString(Strings.TAGFIELD_PLACEHOLDER)); + textField.setMaxWidth(Double.MAX_VALUE); + textField.setOnKeyPressed((event)->{ + if(event.getCode().equals(KeyCode.ENTER)) + { + addTag(textField.getText().trim()); + } + else if(event.getCode().equals(KeyCode.DOWN)) + { + textField.setText(" "); + textField.setText(""); + } + }); + + TextFields.bindAutoCompletion(textField, new Callback<AutoCompletionBinding.ISuggestionRequest, Collection<String>>() + { + @Override + public Collection<String> call(org.controlsfx.control.textfield.AutoCompletionBinding.ISuggestionRequest param) + { + ArrayList<String> completions = getCompletions(allTags); + ArrayList<String> remainingCompletions = new ArrayList<>(); + for(String currentCompletion : completions) + { + if(currentCompletion.toLowerCase().contains(param.getUserText().toLowerCase())) + { + remainingCompletions.add(currentCompletion); + } + } + + return remainingCompletions; + } + }); + this.getChildren().add(textField); + + this.setStyle("-fx-background-color: #FFFFFF; -fx-background-radius: 5px;"); + + refresh(false); + } + + private HBox initHboxTags() + { + HBox newHboxTags = new HBox(); + newHboxTags.setSpacing(5); + newHboxTags.setPadding(new Insets(5)); + newHboxTags.setStyle("-fx-background-color: transparent"); + return newHboxTags; + } + + private ArrayList<String> getCompletions(ArrayList<Tag> allTags) + { + ArrayList<String> newCompletions = new ArrayList<>(); + for(Tag currentTag : allTags) + { + boolean isAlreadyInList = false; + for(Tag paymentTag : tags) + { + if(currentTag.getName().equals(paymentTag.getName())) + { + isAlreadyInList = true; + } + } + + if(!isAlreadyInList) + { + newCompletions.add(currentTag.getName()); + } + } + + return newCompletions; + } + + public ArrayList<Tag> getTags() + { + return tags; + } + + public void setTags(ArrayList<Tag> tags) + { + this.tags = tags; + refresh(false); + } + + public void setAllTags(ArrayList<Tag> allTags) + { + this.allTags = allTags; + refresh(false); + } + + public void addTag(String tagName) + { + if(tagName.equals("")) + { + return; + } + + for(Tag currentTag : tags) + { + if(currentTag.getName().equals(tagName)) + { + return; + } + } + + if(tagName.length() > 45) + { + AlertGenerator.showAlert(AlertType.WARNING, + Localization.getString(Strings.TITLE_WARNING), + "", + Localization.getString(Strings.WARNING_TAG_CHARACTER_LIMIT_REACHED_45), + parentController.getController().getIcon(), + parentController.getStage(), + null, + false); + return; + } + + tags.add(new Tag(-1, tagName)); + refresh(true); + } + + public void removeTag(Tag tag) + { + tags.remove(tag); + refresh(true); + } + + private void refresh(boolean requstFocus) + { + hboxTags.getChildren().clear(); + + for(Tag currentTag : tags) + { + hboxTags.getChildren().add(generateTag(currentTag)); + } + + if(requstFocus) + { + textField.setText(""); + textField.requestFocus(); + } + } + + private HBox generateTag(Tag tag) + { + HBox hboxTag = new HBox(); + hboxTag.setSpacing(5); + hboxTag.setAlignment(Pos.CENTER_LEFT); + hboxTag.setPadding(new Insets(0, 3, 0, 7)); + hboxTag.setStyle("-fx-background-color: #cccccc; -fx-background-radius: 5px;"); + + Label labelTagName = new Label(tag.getName()); + labelTagName.setStyle("-fx-font-size: 13; -fx-text-fill: " + ConvertTo.toRGBHexWithoutOpacity(Colors.TEXT)); + hboxTag.getChildren().add(labelTagName); + + Button buttonDelete = new Button(); + buttonDelete.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 13, Colors.TEXT)); + buttonDelete.setStyle("-fx-background-color: transparent;"); + buttonDelete.getStyleClass().add("button-hoverable"); + buttonDelete.setOnAction((event)->{ + removeTag(tag); + }); + hboxTag.getChildren().add(buttonDelete); + + return hboxTag; + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/utils/UIHelpers.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/utils/UIHelpers.java new file mode 100644 index 0000000000000000000000000000000000000000..88035fcb1da69d55f23adf6570343466f034dc26 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/utils/UIHelpers.java @@ -0,0 +1,44 @@ +package de.deadlocker8.budgetmasterclient.utils; + +import java.io.IOException; + +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import de.deadlocker8.budgetmasterclient.ui.controller.ModalController; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.image.Image; +import javafx.stage.Modality; +import javafx.stage.Stage; +import logger.Logger; +import tools.Localization; + +public class UIHelpers +{ + public static Stage showModal(String title, String message, Stage owner, Image icon) + { + try + { + FXMLLoader fxmlLoader = new FXMLLoader(Helpers.class.getResource("/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml")); + Parent root = (Parent)fxmlLoader.load(); + fxmlLoader.setResources(Localization.getBundle()); + Stage newStage = new Stage(); + newStage.initOwner(owner); + newStage.initModality(Modality.APPLICATION_MODAL); + newStage.setTitle(title); + newStage.setScene(new Scene(root)); + newStage.getIcons().add(icon); + newStage.setResizable(false); + ModalController newController = fxmlLoader.getController(); + newController.init(newStage, message); + newStage.show(); + + return newStage; + } + catch(IOException e) + { + Logger.error(e); + return null; + } + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/resources/changelog.json b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/changelog.json similarity index 64% rename from src/de/deadlocker8/budgetmaster/resources/changelog.json rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/changelog.json index db0fc9d8ed814b8c3efe3200fb3549a93dd5b070..3c430ae2ffb9994aa954c50b16878759c27d074d 100644 --- a/src/de/deadlocker8/budgetmaster/resources/changelog.json +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/changelog.json @@ -7,5 +7,6 @@ "6":"Fixed critical bug that prevents repeating payments from being correctly updated for future months.\n", "7":"-localized all strings into external file\n-added english localization\n-added language chooser to settings\n-remove javafx.Color from server --> server should no run on linux with normal jdk\n-bugfixes:\n -[FIXED] - report budget is calculated incorrectly\n -[FIXED] - refresh after database imprt/delete missing\n -[FIXED] - critical bug concerning repeating payments\n", "8":"bugfixes:\n -broken month chart if january is selected\n -wrong footer in month report\n -wrong initial file name for month report\n -server start failure\n", - "9":"-remember report table column order and selection\n-added Updater for easier client update procedure\n-bugfixes\n" + "9":"-remember report table column order and selection\n-added Updater for easier client update procedure\n-bugfixes\n", + "10":"-added tag system (tag payments, suggestion of already used payments, ...)\n-added search for payments (search by name, description, category, tags and amount)\n-added better month/year picker (click on date to open)\n-payment description is now shown in payment tab\n-added hover effect for buttons in main stage to make more clear that they are clickable\n-replaced font in reports\n-settings are now scrollable\n-categories are now sorted alphabetically\n-bugfixes:\n -various bugs concerning the prefilled values of input fields\n-database import\n-compatibility issues with old ReportPreferences\n-available version label was not updated on manual update search\n-non running server leads to alert that states that the server version is not compatible\n" } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/resources/flags/english.png b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/flags/english.png similarity index 100% rename from src/de/deadlocker8/budgetmaster/resources/flags/english.png rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/flags/english.png diff --git a/src/de/deadlocker8/budgetmaster/resources/flags/german.png b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/flags/german.png similarity index 100% rename from src/de/deadlocker8/budgetmaster/resources/flags/german.png rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/flags/german.png diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/fonts/OpenSans-Regular.ttf b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2e31d02424ed50b9e05c19b5d82500699a6edbb0 Binary files /dev/null and b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/fonts/OpenSans-Regular.ttf differ diff --git a/src/de/deadlocker8/budgetmaster/resources/icon.png b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/icon.png similarity index 100% rename from src/de/deadlocker8/budgetmaster/resources/icon.png rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/icon.png diff --git a/src/de/deadlocker8/budgetmaster/resources/languages/_de.properties b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties similarity index 90% rename from src/de/deadlocker8/budgetmaster/resources/languages/_de.properties rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties index 562ebe1ed71f353b6c9cfe5b584392960d123fcb..5a19c4b0a6dccc44aa584547dba8e3691020d332 100644 --- a/src/de/deadlocker8/budgetmaster/resources/languages/_de.properties +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties @@ -1,10 +1,10 @@ # DEFAULT app.name=BudgetMaster -version.code=9 -version.name=1.5.0 -version.date=31.08.17 +version.code=10 +version.name=1.6.0 +version.date=03.10.17 author=Robert Goldmann -credits=L�nderflaggen von Freepik auf https://www.flaticon.com +credits=L�nderflaggen von Freepik auf https://www.flaticon.com\nVerwendete Schriftarten: OpenSans folder=Deadlocker/BudgetMaster @@ -28,18 +28,23 @@ title.modal=Vorgang l title.payment.edit={0} bearbeiten title.payment.new=Neue {0} title.filter=Filter +title.search=Suchen title.report.save=Bericht speichern title.database.export=Datenbank exportieren title.database.import=Datenbank importieren +title.datepicker=Datum w�hlen +title.tags=Das Tag-Eingabefeld # LOAD load.charts=Lade Diagramme... load.data=Lade Daten... +load.report.tab=Lade Monatsbericht... load.report=Der Monatsbericht wird erstellt, bitte warten... load.database.export=Die Datenbank wird exportiert, bitte warten... load.database.import=Die Datenbank wird importiert, bitte warten... load.database.delete=Die Datenbank wird gel�scht, bitte warten... load.update=Update wird heruntergeladen, bitte warten... +load.search=Buchungen werden gesucht, bitte warten... # MISC category.none=Keine Kategorie @@ -58,6 +63,7 @@ url.placeholder=z.B. https://yourdomain.de currency.placeholder=z.B. \u20AC, CHF, $ trusted.hosts.placeholder=z.B. localhost undefined=unbekannt +tagfield.placeholder=Neuen Tag hier eingeben # REPORT report.position=Nr. @@ -66,6 +72,7 @@ report.repeating=Wiederholend report.category=Kategorie report.name=Name report.description=Notiz +report.tags=Tags report.rating=+/- report.amount=Betrag report.headline=Monatsbericht - {0} @@ -140,6 +147,7 @@ info.text.update.available.now=Jetzt updaten info.title.start.after.update=Update erfolgreich info.header.text.start.after.update=BudgetMaster wurde erfolgreich auf Version {0} aktualisiert info.text.start.after.update=Hinweis: Der BudgetMasterServer muss manuell von dir geupdated werden! +info.tags=Es erscheinen Vorschl�ge basierend auf bereits verwendeten Tags sobald du zu tippen beginnst.\n\nEnter - F�gt den Inhalt des Eingabefelds als neuen Tag hinzu.\nPfeil nach unten - �ffnet die Vorschl�ge, wenn das Eingabefeld leer ist. # WARNING warning.enddate.before.startdate=Das Enddatum darf zeitlich nicht vor dem Startdatum liegen. @@ -153,6 +161,7 @@ warning.empty.payment.name=Das Feld f warning.name.character.limit.reached.45=Der Name darf maximal 45 Zeichen lang sein. warning.name.character.limit.reached.150=Der Name darf maximal 150 Zeichen lang sein. warning.description.character.limit.reached.150=Die Notiz darf maximal 150 Zeichen lang sein. +warning.tag.character.limit.reached.45=Der Name eines Tags darf maximal 45 Zeichen lang sein. warning.payment.amount=Gib eine g�ltige Zahl f�r den Betrag ein. warning.empty.payment.date=Bitte w�hle ein Datum aus. warning.payment.repeating=Wenn Wiederholung aktiviert ist d�rfen nicht beide Eingabefelder 0 sein.\n(Zur Deaktivierung der Wiederholung einfach die Checkbox abw�hlen) @@ -164,6 +173,8 @@ warning.wrong.verificationcode=Die Eingabe stimmt nicht mit dem Best warning.empty.password=Bitte gib dein Passwort ein. warning.wrong.password=Das Passwort ist nicht korrekt. warning.server.version=Die installierte Serverversion (Version: {0}) ist nicht kompatibel mit deinem Client (Version: {1}).\n\nBitte aktualisiere deinen Server:\nSchritt 1: Server stoppen\nSchritt 2: BudgetMasterServer.jar mit aktuellester Version ersetzen\nSchritt 3: Server starten +warning.empty.year=Bitte gib ein Jahr ein. +warning.wrong.year=Bitte gib eine g�ltige Jahreszahl ein (4 Ziffern). # ERROR error.unknown.host=Es konnte keine Verbindung mit dem Internet hergestellt werden. @@ -209,16 +220,28 @@ filter.type=Art filter.type.income=Einnahme filter.type.payment=Ausgabe filter.repeating=Wiederholung -filter.repeating.none=keine Wiederholung +filter.repeating.none=keine filter.repeating.monthday=monatlich filter.repeating.interval=alle X Tage filter.categories=Kategorien filter.categories.button.all=Alle filter.categories.button.none=Keine filter.name=Name +filter.tags=Tags +filter.tags.button.all=Alle +filter.tags.button.none=Keine filter.button.reset=Zur�cksetzen filter.button.filter=Filtern +search.headline=Nach Buchungen suchen +search.by=Suchen in: +search.by.name=Name +search.by.description=Notiz +search.by.category.name=Kategoriename +search.by.tags=Tags +search.by.amount=Betrag eingrenzen +search.button.search=Suchen + gui.tab.home=Startseite gui.tab.payments=Buchungen gui.tab.categories=Kategorien @@ -239,6 +262,7 @@ payment.new.label.amount=Betrag: payment.new.label.category=Kategorie: payment.new.label.date=Datum: payment.new.label.description=Notiz: +payment.new.label.tags=Tags: payment.new.label.repeating=Wiederholung: payment.new.label.repeating.all=Alle payment.new.label.repeating.days=Tage @@ -252,6 +276,7 @@ paymenttab.button.filter=Filter paymenttab.label.filter.active=Filter aktiv paymenttab.label.incomes=Einnahmen: paymenttab.label.payments=Ausgaben: +paymenttab.button.search=Suchen reporttab.checkbox.include.budget=Budgetkalkulation hinzuf�gen reporttab.checkbox.split.tables=Einnahmen und Ausgaben als getrennte Tabellen @@ -280,3 +305,7 @@ settingstab.label.updates.latest.version=Verf settings.tab.button.save=Speichern splashscreen.label.password=Passwort: + +datepicker.label.month=Monat: +datepicker.label.year=Jahr: +datepicker.button.confirm=�bernehmen diff --git a/src/de/deadlocker8/budgetmaster/resources/languages/_en.properties b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties similarity index 90% rename from src/de/deadlocker8/budgetmaster/resources/languages/_en.properties rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties index 71b5e6e9f1667104774b1495733bed88912c97e0..0214f27fde602c718e1bec53b1d896c7d19c875c 100644 --- a/src/de/deadlocker8/budgetmaster/resources/languages/_en.properties +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties @@ -1,10 +1,10 @@ # DEFAULT app.name=BudgetMaster -version.code=9 -version.name=1.5.0 -version.date=31.08.17 +version.code=10 +version.name=1.6.0 +version.date=03.10.17 author=Robert Goldmann -credits=Flags by Freepik on https://www.flaticon.com +credits=Flags by Freepik on https://www.flaticon.com\nFonts used: OpenSans folder=Deadlocker/BudgetMaster @@ -28,18 +28,23 @@ title.modal=Process is running title.payment.edit=Edit {0} title.payment.new=New {0} title.filter=Filter +title.search=Search title.report.save=Save Report title.database.export=Export Database title.database.import=Import Database +title.datepicker=Choose date +title.tags=The Tag-Inputfield # LOAD load.charts=Loading Charts... load.data=Loading Data... +load.report.tab=Loading Month Report... load.report=Please wait while the report is being generated... load.database.export=Please wait while the database is being exported... load.database.import=Please wait while the database is being imported... load.database.delete=Please wait while the database is being deleted... load.update=Please wait while the update is being downloaded... +load.search=Please wait while payments are being searched... # MISC category.none=No Category @@ -58,6 +63,7 @@ url.placeholder=e.g. https://yourdomain.de currency.placeholder=e.g. \u20AC, CHF, $ trusted.hosts.placeholder=e.g. localhost undefined=undefined +tagfield.placeholder=Enter new Tag here # REPORT report.position=No. @@ -66,6 +72,7 @@ report.repeating=Repeating report.category=Category report.name=Name report.description=Description +report.tags=Tags report.rating=+/- report.amount=Amount report.headline=Month Report - {0} @@ -113,7 +120,7 @@ info.text.chart.export.open.folder=Open Folder info.text.chart.export.open.chart=Open Chart info.title.report.save=Successfully Created info.text.report.save=The month report has been successfully created. -info.text.report.save.open.folder=Open Folde +info.text.report.save.open.folder=Open Folder info.text.report.save.open.report=Open Report info.title.database.export=Successfully Exported info.text.database.export=The database has been successfully exported. @@ -140,6 +147,7 @@ info.text.update.available.now=Update Now info.title.start.after.update=Update successfull info.header.text.start.after.update=Successfully updated BudgetMaster to version {0} info.text.start.after.update=Note: You have to update the BudgetMasterServer manually! +info.tags=Suggestions based on already used tags will show up once you start typing.\n\nEnter - Appends the current input field content as a new tag.\nArrow Down - Opens the suggestions if the input field is empty. # WARNING warning.enddate.before.startdate=The end date can not be earlier than the start date. @@ -153,6 +161,7 @@ warning.empty.payment.name=The field for the name can not be empty. warning.name.character.limit.reached.45=The name must not exceed 45 characters in length. warning.name.character.limit.reached.150=The name must not exceed 150 characters in length. warning.description.character.limit.reached.150=The description must not exceed 150 characters in length. +warning.tag.character.limit.reached.45=A tag name must not exceed 45 characters in length. warning.payment.amount=Please enter a valid number in the amount field. warning.empty.payment.date=Please select a date. warning.payment.repeating=If repeating is activated, both input fields may not be 0.\n(To deactivate the repeat, simply deselect the checkbox). @@ -164,6 +173,8 @@ warning.wrong.verificationcode=The input does not match the verification code. warning.empty.password=Please enter your password. warning.wrong.password=The password is not correct. warning.server.version=The installed server version (version: {0}) is not compatible with your client (version: {1}).\n\nPlease update your server:\nStep 1: stop server\nStep 2: replace BudgetMasterServer.jar with latest version\nStep 3: start server +warning.empty.year=Please enter a year. +warning.wrong.year=Please enter a valid year (4 digits). # ERROR error.unknown.host=Could not connect to the Internet. @@ -209,16 +220,28 @@ filter.type=Type filter.type.income=Income filter.type.payment=Payment filter.repeating=Repeating -filter.repeating.none=no repeating +filter.repeating.none=none filter.repeating.monthday=monthly filter.repeating.interval=every X days filter.categories=Categories filter.categories.button.all=All filter.categories.button.none=None filter.name=Name +filter.tags=Tags +filter.tags.button.all=All +filter.tags.button.none=None filter.button.reset=Reset filter.button.filter=Filter +search.headline=Search for payments +search.by=Search in: +search.by.name=Name +search.by.description=Description +search.by.tags=Tags +search.by.category.name=Category Name +search.by.amount=Limit Amount +search.button.search=Search + gui.tab.home=Home gui.tab.payments=Payments gui.tab.categories=Categories @@ -239,6 +262,7 @@ payment.new.label.amount=Amount: payment.new.label.category=Category: payment.new.label.date=Date: payment.new.label.description=Description: +payment.new.label.tags=Tags: payment.new.label.repeating=Repeating: payment.new.label.repeating.all=every payment.new.label.repeating.days=days @@ -252,6 +276,7 @@ paymenttab.button.filter=Filter paymenttab.label.filter.active=Filter active paymenttab.label.incomes=Incomes: paymenttab.label.payments=Payments: +paymenttab.button.search=Search reporttab.checkbox.include.budget=Include budget calculation reporttab.checkbox.split.tables=Split incomes and payments into separate tables @@ -280,3 +305,7 @@ settingstab.label.updates.latest.version=Latest Version: settings.tab.button.save=Save splashscreen.label.password=Password: + +datepicker.label.month=Month: +datepicker.label.year=Year: +datepicker.button.confirm=Apply \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml similarity index 91% rename from src/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml index 0d2c84f888c5893648f1d0a230beb25108d3676e..25b905501a1283262070d6c5942b814dd4911123 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml @@ -7,7 +7,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.CategoryController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.CategoryController"> <children> <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0"> <children> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml similarity index 98% rename from src/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml index ce7cfe0c10e962b08ffae02ea90cc83efce82e02..a387c946ed7d6510e40e3d1630f61220b53fd1b5 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml @@ -13,7 +13,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ChartController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.ChartController"> <children> <Accordion fx:id="accordion" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0"> <panes> diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/DatePickerGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/DatePickerGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..76cfb1fd918945eaf673d37de9f704194dc72ed5 --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/DatePickerGUI.fxml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.Spinner?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> + +<AnchorPane prefHeight="180.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <VBox prefHeight="273.0" prefWidth="465.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <children> + <HBox alignment="CENTER" prefHeight="30.0" spacing="25.0" VBox.vgrow="ALWAYS"> + <children> + <VBox alignment="CENTER" maxWidth="1.7976931348623157E308" spacing="10.0" HBox.hgrow="ALWAYS"> + <children> + <Label alignment="CENTER" maxWidth="1.7976931348623157E308" prefHeight="29.0" text="%datepicker.label.month"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <ComboBox fx:id="comboBoxMonth" maxWidth="1.7976931348623157E308" minHeight="29.0" prefHeight="29.0" prefWidth="163.0" /> + </children> + </VBox> + <VBox alignment="CENTER" spacing="10.0" HBox.hgrow="ALWAYS"> + <children> + <Label alignment="CENTER" maxWidth="1.7976931348623157E308" prefHeight="29.0" text="%datepicker.label.year"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <Spinner fx:id="spinnerYear" editable="true" maxWidth="1.7976931348623157E308" minHeight="29.0" minWidth="163.0" prefHeight="29.0" prefWidth="163.0" /> + </children> + </VBox> + </children> + </HBox> + <HBox alignment="CENTER" prefHeight="30.0" prefWidth="465.0"> + <children> + <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="%cancel"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + <Button fx:id="buttonConfirm" mnemonicParsing="false" onAction="#confirm" text="%datepicker.button.confirm"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <HBox.margin> + <Insets left="25.0" /> + </HBox.margin> + </Button> + </children> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </HBox> + </children> + <padding> + <Insets bottom="10.0" left="10.0" right="10.0" /> + </padding> + </VBox> + </children> +</AnchorPane> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml similarity index 96% rename from src/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml index eb2edfe7b7c14c5afb8afa964dda58d653a0c0c6..7a4b32843831ccf867f1472955015d11ef11b553 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml @@ -9,7 +9,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="200.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ExportChartController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="200.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> <children> <VBox AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> <children> diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..8e1cf6c9545e5a2762a081ef2df94a83450d3e1a --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.CheckBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.control.TextField?> +<?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="650.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <ScrollPane fx:id="scrollPane" hbarPolicy="NEVER" layoutX="14.0" layoutY="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <content> + <VBox fx:id="vboxMain" prefHeight="567.0" prefWidth="619.0" spacing="15.0"> + <children> + <Label text="%filter.headline"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + <VBox.margin> + <Insets bottom="-5.0" /> + </VBox.margin> + </Label> + <HBox alignment="TOP_CENTER" VBox.vgrow="ALWAYS"> + <children> + <VBox prefHeight="200.0" prefWidth="100.0" spacing="20.0" HBox.hgrow="ALWAYS"> + <children> + <VBox prefHeight="15.0" prefWidth="422.0" spacing="5.0"> + <children> + <Label text="%filter.type"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <HBox prefHeight="10.0" prefWidth="422.0" spacing="25.0"> + <children> + <CheckBox fx:id="checkBoxIncome" mnemonicParsing="false" text="%filter.type.income"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <CheckBox fx:id="checkBoxPayment" mnemonicParsing="false" text="%filter.type.payment"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + </children> + </HBox> + </children> + <padding> + <Insets right="10.0" /> + </padding> + </VBox> + <Label fx:id="labelSeparatorHorizontalLeft" maxWidth="1.7976931348623157E308" prefHeight="5.0" prefWidth="287.0"> + <font> + <Font size="1.0" /> + </font> + </Label> + <VBox prefHeight="150.0" prefWidth="422.0" spacing="5.0" VBox.vgrow="ALWAYS"> + <children> + <HBox spacing="10.0"> + <children> + <Label maxWidth="1.7976931348623157E308" text="%filter.categories" HBox.hgrow="ALWAYS"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <Button fx:id="buttonCategoryAll" mnemonicParsing="false" onAction="#enableAllCategories" text="%filter.categories.button.all"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + <Button fx:id="buttonCategoryNone" mnemonicParsing="false" onAction="#disableAllCategories" text="%filter.categories.button.none"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + </children> + </HBox> + <ScrollPane prefHeight="183.0" prefWidth="297.0" VBox.vgrow="ALWAYS"> + <content> + <VBox fx:id="vboxCategories" spacing="5.0"> + <padding> + <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> + </padding></VBox> + </content> + </ScrollPane> + </children> + <padding> + <Insets right="10.0" /> + </padding> + </VBox> + </children> + </VBox> + <Label fx:id="labelSeparator" maxHeight="1.7976931348623157E308" /> + <VBox prefHeight="200.0" prefWidth="100.0" spacing="20.0" HBox.hgrow="ALWAYS"> + <children> + <VBox prefHeight="33.0" prefWidth="422.0" spacing="5.0"> + <children> + <Label text="%filter.repeating"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <HBox spacing="10.0"> + <children> + <CheckBox fx:id="checkBoxNoRepeating" mnemonicParsing="false" text="%filter.repeating.none"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <CheckBox fx:id="checkBoxMonthlyRepeating" mnemonicParsing="false" text="%filter.repeating.monthday"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <CheckBox fx:id="checkBoxRepeatEveryXDays" mnemonicParsing="false" text="%filter.repeating.interval"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + </children> + </HBox> + </children> + <padding> + <Insets left="10.0" /> + </padding> + </VBox> + <Label fx:id="labelSeparatorHorizontalRight" maxWidth="1.7976931348623157E308"> + <font> + <Font size="1.0" /> + </font> + </Label> + <VBox prefHeight="150.0" prefWidth="422.0" spacing="5.0" VBox.vgrow="ALWAYS"> + <children> + <HBox spacing="10.0"> + <children> + <Label maxWidth="1.7976931348623157E308" text="%filter.tags" HBox.hgrow="ALWAYS"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <Button fx:id="buttonTagsAll" mnemonicParsing="false" onAction="#enableAllTags" text="%filter.categories.button.all"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + <Button fx:id="buttonTagsNone" mnemonicParsing="false" onAction="#disableAllTags" text="%filter.categories.button.none"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Button> + </children> + </HBox> + <ScrollPane prefHeight="85.0" prefWidth="409.0" VBox.vgrow="ALWAYS"> + <content> + <VBox fx:id="vboxTags" spacing="5.0"> + <padding> + <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> + </padding></VBox> + </content> + </ScrollPane> + </children> + <padding> + <Insets left="10.0" /> + </padding> + </VBox> + </children> + </VBox> + </children> + </HBox> + <VBox prefHeight="33.0" prefWidth="422.0" spacing="5.0"> + <children> + <Label text="%filter.name"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <TextField fx:id="textFieldSearch" /> + </children> + </VBox> + <HBox alignment="CENTER" prefHeight="30.0" prefWidth="465.0" spacing="10.0"> + <children> + <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="%cancel"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + <Button fx:id="buttonReset" mnemonicParsing="false" onAction="#reset" text="%filter.button.reset"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <HBox.margin> + <Insets left="25.0" /> + </HBox.margin> + </Button> + <Button fx:id="buttonFilter" mnemonicParsing="false" onAction="#filter" text="%filter.button.filter"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <HBox.margin> + <Insets left="25.0" /> + </HBox.margin> + </Button> + </children> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </HBox> + </children> + <padding> + <Insets bottom="15.0" /> + </padding> + </VBox> + </content> + </ScrollPane> + </children> +</AnchorPane> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml similarity index 87% rename from src/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml index 61f0dd7e053fefc11112b9d13aa484192f427d2e..6cde2cc3f6d2d49ee946df5f489dfeae410523cd 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml @@ -10,9 +10,8 @@ <?import javafx.scene.layout.Region?> <?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.Controller"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> <children> <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="15.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="14.0"> <children> @@ -24,11 +23,7 @@ </HBox.margin> </Region> <Button fx:id="buttonLeft" mnemonicParsing="false" onAction="#previousMonth" /> - <Label fx:id="labelMonth" alignment="CENTER" prefHeight="36.0" prefWidth="280.0" HBox.hgrow="ALWAYS"> - <font> - <Font name="System Bold" size="24.0" /> - </font> - </Label> + <Button fx:id="buttonDate" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#openDatePicker" prefHeight="25.0" prefWidth="280.0" textAlignment="CENTER" HBox.hgrow="ALWAYS" /> <Button fx:id="buttonRight" mnemonicParsing="false" onAction="#nextMonth" /> <Button fx:id="buttonToday" mnemonicParsing="false" onAction="#today" /> <Region prefHeight="0.0" prefWidth="200.0" HBox.hgrow="ALWAYS" /> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml similarity index 94% rename from src/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml index 98d51c305f73724459c7901ab6016e62749a643f..ba134717f273ee86ec353ca80bf17a49be77950d 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml @@ -8,7 +8,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.HomeController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.HomeController"> <children> <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="15.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> <children> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml similarity index 83% rename from src/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml index 846a76e2b3ba52076c54a92a9d95eab81bf105fb..77b86bc0a1dc9b58c5bec77965f3fbcbdb01f77e 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml @@ -6,7 +6,7 @@ <?import javafx.scene.layout.HBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="100.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ModalController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="100.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.ModalController"> <children> <HBox alignment="CENTER_LEFT" spacing="10.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> <children> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml similarity index 95% rename from src/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml index 79d254ac6e5a082d329604da194b13e0959853a0..3661f5a437f9d7fc09e08424fecd8ae7c2bac317 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml @@ -9,7 +9,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane prefHeight="180.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.NewCategoryController"> +<AnchorPane prefHeight="180.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> <children> <VBox prefHeight="273.0" prefWidth="465.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> <children> diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..caffbf8e6bc624e604153a6bbe9a71f18a02541c --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml @@ -0,0 +1,226 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.CheckBox?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.DatePicker?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.RadioButton?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.control.Separator?> +<?import javafx.scene.control.Spinner?> +<?import javafx.scene.control.TextArea?> +<?import javafx.scene.control.TextField?> +<?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="450.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <ScrollPane fx:id="scrollPane" hbarPolicy="NEVER" layoutX="14.0" layoutY="14.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <content> + <VBox fx:id="vboxContent" prefHeight="565.0" prefWidth="414.0" spacing="14.0"> + <children> + <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> + <children> + <VBox> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.name"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.max.characters"> + <font> + <Font size="11.0" /> + </font> + </Label> + </children> + </VBox> + <TextField fx:id="textFieldName" prefHeight="29.0" HBox.hgrow="ALWAYS"> + <font> + <Font size="13.0" /> + </font> + <HBox.margin> + <Insets /> + </HBox.margin> + </TextField> + </children> + </HBox> + <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.amount"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <TextField fx:id="textFieldAmount" prefHeight="29.0" HBox.hgrow="ALWAYS"> + <font> + <Font size="13.0" /> + </font> + <HBox.margin> + <Insets /> + </HBox.margin> + </TextField> + </children> + </HBox> + <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.category"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <ComboBox fx:id="comboBoxCategory" maxWidth="1.7976931348623157E308" prefHeight="30.0" HBox.hgrow="ALWAYS" /> + </children> + </HBox> + <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.date"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <DatePicker fx:id="datePicker" maxWidth="1.7976931348623157E308" prefHeight="29.0" HBox.hgrow="ALWAYS" /> + </children> + </HBox> + <HBox alignment="CENTER_LEFT" maxHeight="1.7976931348623157E308" prefWidth="422.0" VBox.vgrow="ALWAYS"> + <children> + <VBox alignment="CENTER_LEFT"> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.description"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.max.characters"> + <font> + <Font size="11.0" /> + </font> + </Label> + </children> + </VBox> + <TextArea fx:id="textArea" maxWidth="1.7976931348623157E308" prefHeight="37.0" prefWidth="240.0" HBox.hgrow="ALWAYS" /> + </children> + </HBox> + <HBox prefHeight="30.0" prefWidth="465.0"> + <children> + <VBox> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.tags"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <Button fx:id="buttonTagsHelp" mnemonicParsing="false" onAction="#showTagsHelp" /> + </children> + </VBox> + <HBox fx:id="hboxTags" alignment="CENTER_LEFT" HBox.hgrow="ALWAYS" /> + </children> + </HBox> + <VBox prefHeight="214.0" prefWidth="422.0" spacing="20.0"> + <children> + <HBox alignment="CENTER"> + <children> + <CheckBox fx:id="checkBoxRepeat" mnemonicParsing="false" /> + <Label alignment="CENTER" maxWidth="1.7976931348623157E308" prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.repeating"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + </children> + </HBox> + <HBox alignment="TOP_CENTER" prefWidth="422.0"> + <children> + <VBox alignment="TOP_CENTER" spacing="5.0" HBox.hgrow="ALWAYS"> + <children> + <RadioButton fx:id="radioButtonPeriod" mnemonicParsing="false"> + <VBox.margin> + <Insets bottom="10.0" /> + </VBox.margin> + </RadioButton> + <Label fx:id="labelText1" prefHeight="25.0" prefWidth="40.0" text="%payment.new.label.repeating.all"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <Spinner fx:id="spinnerRepeatingPeriod" prefHeight="25.0" prefWidth="90.0" /> + <Label fx:id="labelText2" prefHeight="25.0" prefWidth="36.0" text="%payment.new.label.repeating.days"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + </children> + <padding> + <Insets left="15.0" right="15.0" /> + </padding> + </VBox> + <Separator orientation="VERTICAL" prefHeight="200.0" /> + <VBox alignment="TOP_CENTER" spacing="5.0" HBox.hgrow="ALWAYS"> + <children> + <RadioButton fx:id="radioButtonDay" mnemonicParsing="false"> + <VBox.margin> + <Insets bottom="10.0" /> + </VBox.margin> + </RadioButton> + <Label fx:id="labelText3" prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.repeating.monthday"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <ComboBox fx:id="comboBoxRepeatingDay" prefHeight="25.0" prefWidth="90.0" /> + <Label prefHeight="25.0" prefWidth="36.0"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + </children> + <padding> + <Insets left="15.0" right="15.0" /> + </padding> + </VBox> + </children> + </HBox> + <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> + <children> + <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.enddate"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <DatePicker fx:id="datePickerEnddate" maxWidth="1.7976931348623157E308" prefHeight="29.0" HBox.hgrow="ALWAYS" /> + </children> + </HBox> + </children> + </VBox> + <HBox alignment="CENTER" prefHeight="30.0" prefWidth="465.0"> + <children> + <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="%cancel"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="%payment.new.button.save"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <HBox.margin> + <Insets left="25.0" /> + </HBox.margin> + </Button> + </children> + <VBox.margin> + <Insets top="5.0" /> + </VBox.margin> + </HBox> + </children> + <padding> + <Insets bottom="5.0" /> + </padding> + </VBox> + </content> + </ScrollPane> + </children> +</AnchorPane> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml similarity index 88% rename from src/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml index 24a4beca78889dd6dd5e8111c74f5c231b1a4a82..43cbe9ae740d3b45e5dd9eb9bbbf98173f709882 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml @@ -10,7 +10,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.PaymentController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.PaymentController"> <children> <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0"> <children> @@ -37,6 +37,15 @@ </children> </VBox> <Region HBox.hgrow="ALWAYS" /> + <Button fx:id="buttonSearch" mnemonicParsing="false" onAction="#search" text="%paymenttab.button.search"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <HBox.margin> + <Insets /> + </HBox.margin> + </Button> + <Region HBox.hgrow="ALWAYS" /> <Button fx:id="buttonNewPayment" mnemonicParsing="false" onAction="#newPayment" text="%paymenttab.button.new.payment"> <font> <Font name="System Bold" size="14.0" /> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml similarity index 97% rename from src/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml index 45f4fa37912f585517a53dc93994f6d9a7436bb4..2e84bb4592c196d3cd7c04a2c370babd7512f680 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml @@ -10,7 +10,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ReportController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.ReportController"> <children> <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="20.0" AnchorPane.bottomAnchor="35.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0"> <children> diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SearchGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SearchGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..bc66cd164a7f00c769b60bc2ae91846c4371e183 --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SearchGUI.fxml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.CheckBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ListView?> +<?import javafx.scene.control.TextField?> +<?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="500.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> + <children> + <VBox prefHeight="273.0" prefWidth="465.0" spacing="20.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <children> + <Label text="%search.headline"> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <VBox spacing="15.0"> + <children> + <HBox spacing="25.0"> + <children> + <VBox spacing="20.0" HBox.hgrow="ALWAYS"> + <children> + <TextField fx:id="textFieldSearch" /> + <HBox spacing="15.0"> + <children> + <Label text="%search.by"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <CheckBox fx:id="checkBoxName" mnemonicParsing="false" text="%search.by.name"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <CheckBox fx:id="checkBoxDescription" mnemonicParsing="false" text="%search.by.description"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <CheckBox fx:id="checkBoxCategoryName" mnemonicParsing="false" text="%search.by.category.name"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <CheckBox fx:id="checkBoxTags" mnemonicParsing="false" text="%search.by.tags"> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + </children> + </HBox> + </children> + </VBox> + </children> + </HBox> + <Label fx:id="labelSeparator" maxWidth="1.7976931348623157E308"> + <font> + <Font size="1.0" /> + </font> + </Label> + <HBox alignment="CENTER_LEFT" prefHeight="32.0" prefWidth="377.0" spacing="10.0"> + <children> + <CheckBox fx:id="checkBoxSearchByAmount" mnemonicParsing="false" text="%search.by.amount"> + <HBox.margin> + <Insets right="25.0" /> + </HBox.margin> + <font> + <Font size="14.0" /> + </font> + </CheckBox> + <HBox fx:id="hboxSearchByAmount" alignment="CENTER" spacing="10.0" HBox.hgrow="ALWAYS"> + <children> + <TextField fx:id="textFieldAmountMin" prefHeight="25.0" prefWidth="55.0" /> + <HBox fx:id="hboxRangeSlider" prefHeight="32.0" prefWidth="123.0" HBox.hgrow="ALWAYS" /> + <TextField fx:id="textFieldAmountMax" prefHeight="25.0" prefWidth="55.0" /> + </children> + </HBox> + </children> + </HBox> + </children> + </VBox> + <ListView fx:id="listView" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS" /> + <HBox alignment="CENTER" prefHeight="30.0" prefWidth="465.0" spacing="10.0"> + <children> + <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="%cancel"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + <Button fx:id="buttonSearch" mnemonicParsing="false" onAction="#search" text="%search.button.search"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <HBox.margin> + <Insets left="25.0" /> + </HBox.margin> + </Button> + </children> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </HBox> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml new file mode 100644 index 0000000000000000000000000000000000000000..c853b86e2034c064b80f6435fc5bd2381fd02d5d --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml @@ -0,0 +1,224 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.CheckBox?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.RadioButton?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.control.TextArea?> +<?import javafx.scene.control.TextField?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.Region?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> + +<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.controller.SettingsController"> + <children> + <VBox alignment="TOP_CENTER" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> + <children> + <ScrollPane fx:id="scrollPane" hbarPolicy="NEVER" VBox.vgrow="ALWAYS"> + <content> + <HBox fx:id="hboxSettings" prefHeight="359.0" prefWidth="722.0"> + <children> + <VBox alignment="CENTER_RIGHT" prefHeight="25.0" prefWidth="158.0" spacing="15.0"> + <children> + <Label fx:id="labelClientSecret" prefHeight="25.0" text="%settingstab.label.secret.client"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <Label fx:id="labelURL" prefHeight="25.0" text="%settingstab.label.url"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + <VBox.margin> + <Insets /> + </VBox.margin> + </Label> + <Label fx:id="labelSecret" prefHeight="25.0" text="%settingstab.label.secret.server"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <Label fx:id="labelCurrency" prefHeight="25.0" text="%settingstab.label.currency"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <Label fx:id="labelSecret11" prefHeight="25.0" text="%settingstab.label.rest"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + </Label> + <Label fx:id="labelSecret111" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" minHeight="60.0" prefWidth="158.0" text="%settingstab.label.trusted.hosts" textAlignment="RIGHT" wrapText="true"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + <VBox.margin> + <Insets top="-7.0" /> + </VBox.margin> + </Label> + <Label fx:id="labelSecret1111" alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" text="%settingstab.label.trusted.hosts.info" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS"> + <font> + <Font size="14.0" /> + </font> + <VBox.margin> + <Insets top="-20.0" /> + </VBox.margin> + </Label> + <Label fx:id="labelSecret1112" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="%settingstab.label.language" textAlignment="RIGHT" wrapText="true"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + <VBox.margin> + <Insets top="50.0" /> + </VBox.margin> + </Label> + <Label fx:id="labelSecret11122" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="%settingstab.label.database" textAlignment="RIGHT" wrapText="true"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + <VBox.margin> + <Insets top="5.0" /> + </VBox.margin> + </Label> + <Label fx:id="labelSecret111221" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="%settingstab.label.updates" textAlignment="RIGHT" wrapText="true"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + <VBox.margin> + <Insets top="5.0" /> + </VBox.margin> + </Label> + <Label fx:id="labelSecret11121" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" textAlignment="RIGHT" wrapText="true"> + <font> + <Font name="System Bold" size="16.0" /> + </font> + <VBox.margin> + <Insets top="15.0" /> + </VBox.margin> + </Label> + <Region prefHeight="19.0" prefWidth="158.0" VBox.vgrow="ALWAYS" /> + </children> + <HBox.margin> + <Insets right="25.0" /> + </HBox.margin> + </VBox> + <VBox alignment="CENTER_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="15.0" HBox.hgrow="ALWAYS"> + <children> + <TextField fx:id="textFieldClientSecret" /> + <TextField fx:id="textFieldURL" /> + <TextField fx:id="textFieldSecret" /> + <TextField fx:id="textFieldCurrency" /> + <HBox alignment="CENTER" prefHeight="11.0" prefWidth="539.0" spacing="30.0"> + <children> + <RadioButton fx:id="radioButtonRestActivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="%settingstab.label.rest.activated"> + <font> + <Font size="14.0" /> + </font> + <HBox.margin> + <Insets /> + </HBox.margin> + </RadioButton> + <RadioButton fx:id="radioButtonRestDeactivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="%settingstab.label.rest.deactivated" HBox.hgrow="ALWAYS"> + <font> + <Font size="14.0" /> + </font> + </RadioButton> + </children> + </HBox> + <TextArea fx:id="textAreaTrustedHosts" maxHeight="122.0" minHeight="122.0" prefHeight="122.0" prefWidth="539.0"> + <VBox.margin> + <Insets /> + </VBox.margin> + </TextArea> + <ComboBox fx:id="comboBoxLanguage" maxWidth="1.7976931348623157E308" /> + <HBox alignment="CENTER_LEFT" prefHeight="11.0" prefWidth="539.0" spacing="30.0"> + <children> + <Button fx:id="buttonExportDB" minWidth="100.0" mnemonicParsing="false" onAction="#exportDB" text="%settingstab.button.database.export"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + <Button fx:id="buttonImportDB" minWidth="100.0" mnemonicParsing="false" onAction="#importDB" text="%settingstab.button.database.import"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + <Button fx:id="buttonDeleteDB" minWidth="100.0" mnemonicParsing="false" onAction="#deleteDB" text="%settingstab.button.database.delete"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Button> + </children> + <VBox.margin> + <Insets /> + </VBox.margin> + </HBox> + <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="20.0"> + <children> + <VBox minWidth="210.0" spacing="10.0" HBox.hgrow="ALWAYS"> + <children> + <Button fx:id="buttonSearchUpdates" minWidth="100.0" mnemonicParsing="false" onAction="#checkForUpdates" text="%settingstab.button.updates.search" /> + <CheckBox fx:id="checkboxEnableAutoUpdate" mnemonicParsing="false" text="%settingstab.button.updates.automatic"> + <font> + <Font size="13.0" /> + </font> + </CheckBox> + </children> + </VBox> + <VBox prefHeight="200.0" prefWidth="100.0" spacing="10.0" HBox.hgrow="ALWAYS"> + <children> + <Label fx:id="labelSecret11111" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" minHeight="25.0" text="%settingstab.label.updates.current.version" textAlignment="CENTER" wrapText="true"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + </Label> + <Label fx:id="labelSecret111111" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" minHeight="25.0" text="%settingstab.label.updates.latest.version" textAlignment="CENTER" wrapText="true"> + <font> + <Font name="System Bold" size="13.0" /> + </font> + <VBox.margin> + <Insets /> + </VBox.margin> + </Label> + </children> + </VBox> + <VBox prefHeight="200.0" prefWidth="100.0" spacing="10.0" HBox.hgrow="ALWAYS"> + <children> + <Label fx:id="labelCurrentVersion" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" minHeight="25.0" textAlignment="CENTER" wrapText="true"> + <font> + <Font size="13.0" /> + </font> + </Label> + <Label fx:id="labelLatestVersion" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" minHeight="25.0" textAlignment="CENTER" wrapText="true"> + <font> + <Font size="13.0" /> + </font> + </Label> + </children> + </VBox> + </children> + </HBox> + <Button fx:id="buttonSave" minWidth="100.0" mnemonicParsing="false" onAction="#save" text="%settings.tab.button.save"> + <font> + <Font name="System Bold" size="14.0" /> + </font> + <VBox.margin> + <Insets top="15.0" /> + </VBox.margin> + </Button> + <Region prefWidth="158.0" VBox.vgrow="ALWAYS" /> + </children> + </VBox> + </children> + </HBox> + </content> + </ScrollPane> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml similarity index 96% rename from src/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml index 33be9b46c1128aff1c773bccfcf44d8f26b93c15..398b068412d665c004587a04f5c72a0c112841eb 100644 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml @@ -10,7 +10,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane fx:id="anchorPaneMain" prefHeight="230.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.SplashScreenController"> +<AnchorPane fx:id="anchorPaneMain" prefHeight="230.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> <children> <VBox layoutX="14.0" layoutY="14.0" spacing="10.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> <children> diff --git a/src/de/deadlocker8/budgetmaster/ui/style.css b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/style.css similarity index 92% rename from src/de/deadlocker8/budgetmaster/ui/style.css rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/style.css index ca4b1ca1182b0cf4037e04e0ac6610684c07d33c..f0c0c1e000e2dddc7be6e0501d2e5eabf270af02 100644 --- a/src/de/deadlocker8/budgetmaster/ui/style.css +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/style.css @@ -86,4 +86,13 @@ .color-picker .arrow-button{ -fx-opacity: 0; - } \ No newline at end of file + } + + .button-hoverable:hover{ + -fx-opacity: 0.6; + -fx-cursor: hand; +} + +.scroll-pane > .viewport { + -fx-background-color: transparent; +} \ No newline at end of file diff --git a/BudgetMasterCore/.classpath b/BudgetMasterCore/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..8e795b1c7e0c65a33e55e6a4fe23c4a11dd9e703 --- /dev/null +++ b/BudgetMasterCore/.classpath @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/BudgetMasterCore/.project b/BudgetMasterCore/.project new file mode 100644 index 0000000000000000000000000000000000000000..5cb225e94a1907fffaac671cb11c963eebaad177 --- /dev/null +++ b/BudgetMasterCore/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>BudgetMasterCore</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + </natures> +</projectDescription> diff --git a/BudgetMasterCore/.settings/org.eclipse.jdt.core.prefs b/BudgetMasterCore/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..714351aec195a9a572640e6844dcafd51565a2a5 --- /dev/null +++ b/BudgetMasterCore/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/BudgetMasterCore/.settings/org.eclipse.m2e.core.prefs b/BudgetMasterCore/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/BudgetMasterCore/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/BudgetMasterCore/pom.xml b/BudgetMasterCore/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..378e55ce7636d2d06a38be2dacd30be6a3d3dae1 --- /dev/null +++ b/BudgetMasterCore/pom.xml @@ -0,0 +1,45 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>de.deadlocker8</groupId> + <artifactId>BudgetMasterCore</artifactId> + <version>0.0.1-SNAPSHOT</version> + <name>BudgetMasterCore</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>2.9.7</version> + </dependency> + <dependency> + <groupId>com.itextpdf</groupId> + <artifactId>itextpdf</artifactId> + <version>5.0.6</version> + </dependency> + <dependency> + <groupId>de.deadlocker8</groupId> + <artifactId>tools</artifactId> + <version>1.0</version> + <scope>system</scope> + <systemPath>${basedir}/../lib/Tools.jar</systemPath> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/Budget.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/Budget.java similarity index 92% rename from src/de/deadlocker8/budgetmaster/logic/Budget.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/Budget.java index a7aef0079cc7ee5dae1229dd5ef62b7fb6efea5d..22dc0a7a50369e2141bb3e5779a510cf5ea1e342 100644 --- a/src/de/deadlocker8/budgetmaster/logic/Budget.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/Budget.java @@ -2,6 +2,8 @@ package de.deadlocker8.budgetmaster.logic; import java.util.List; +import de.deadlocker8.budgetmaster.logic.payment.Payment; + public class Budget { private double incomeSum; diff --git a/src/de/deadlocker8/budgetmaster/logic/FilterSettings.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/FilterSettings.java similarity index 79% rename from src/de/deadlocker8/budgetmaster/logic/FilterSettings.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/FilterSettings.java index 7a72815d0674d66ea5925873bbe18ece78606aee..82818e4c97dc74d42d00f862e135f3079e76c1f2 100644 --- a/src/de/deadlocker8/budgetmaster/logic/FilterSettings.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/FilterSettings.java @@ -10,9 +10,10 @@ public class FilterSettings private boolean isMonthlyRepeatingAllowed; private boolean isRepeatingEveryXDaysAllowed; private ArrayList<Integer> allowedCategoryIDs; + private ArrayList<Integer> allowedTagIDs; private String name; - public FilterSettings(boolean isIncomeAllowed, boolean isPaymentAllowed, boolean isNoRepeatingAllowed, boolean isMonthlyRepeatingAllowed, boolean isRepeatingEveryXDaysAllowed, ArrayList<Integer> allowedCategoryIDs, String name) + public FilterSettings(boolean isIncomeAllowed, boolean isPaymentAllowed, boolean isNoRepeatingAllowed, boolean isMonthlyRepeatingAllowed, boolean isRepeatingEveryXDaysAllowed, ArrayList<Integer> allowedCategoryIDs, ArrayList<Integer> allowedTagIDs, String name) { this.isIncomeAllowed = isIncomeAllowed; this.isPaymentAllowed = isPaymentAllowed; @@ -20,6 +21,7 @@ public class FilterSettings this.isMonthlyRepeatingAllowed = isMonthlyRepeatingAllowed; this.isRepeatingEveryXDaysAllowed = isRepeatingEveryXDaysAllowed; this.allowedCategoryIDs = allowedCategoryIDs; + this.allowedTagIDs = allowedTagIDs; this.name = name; } @@ -31,6 +33,7 @@ public class FilterSettings this.isMonthlyRepeatingAllowed = true; this.isRepeatingEveryXDaysAllowed = true; this.allowedCategoryIDs = null; + this.allowedTagIDs = null; this.name = null; } @@ -93,6 +96,16 @@ public class FilterSettings { this.allowedCategoryIDs = allowedCategoryIDs; } + + public ArrayList<Integer> getAllowedTagIDs() + { + return allowedTagIDs; + } + + public void setAllowedTagIDs(ArrayList<Integer> allowedTagIDs) + { + this.allowedTagIDs = allowedTagIDs; + } public String getName() { @@ -102,12 +115,13 @@ public class FilterSettings public void setName(String name) { this.name = name; - } + } + @Override public String toString() { return "FilterSettings [isIncomeAllowed=" + isIncomeAllowed + ", isPaymentAllowed=" + isPaymentAllowed + ", isNoRepeatingAllowed=" + isNoRepeatingAllowed + ", isMonthlyRepeatingAllowed=" + isMonthlyRepeatingAllowed + ", isRepeatingEveryXDaysAllowed=" + isRepeatingEveryXDaysAllowed - + ", allowedCategoryIDs=" + allowedCategoryIDs + ", name=" + name + "]"; + + ", allowedCategoryIDs=" + allowedCategoryIDs + ", allowedTagIDs=" + allowedTagIDs + ", name=" + name + "]"; } public boolean equals(Object other) @@ -150,7 +164,7 @@ public class FilterSettings } else { - return true; + return isEqualTagIDs(otherSettings); } } else @@ -163,12 +177,43 @@ public class FilterSettings { if(allowedCategoryIDs.equals(otherSettings.getAllowedCategoryIDs())) { - return true; + return isEqualTagIDs(otherSettings); } } - } + } } return false; } + + private boolean isEqualTagIDs(FilterSettings otherSettings) + { + if(allowedTagIDs == null) + { + if(otherSettings.getAllowedTagIDs() != null) + { + return false; + } + else + { + return true; + } + } + else + { + if(otherSettings.getAllowedTagIDs() == null) + { + return false; + } + else + { + if(allowedTagIDs.equals(otherSettings.getAllowedTagIDs())) + { + return true; + } + } + } + + return false; + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/Settings.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/Settings.java similarity index 74% rename from src/de/deadlocker8/budgetmaster/logic/Settings.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/Settings.java index 2d8612467f033bf9e64bd9972599a121509d5912..aede2c726d25b69783474169bc49176f810fa418 100644 --- a/src/de/deadlocker8/budgetmaster/logic/Settings.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/Settings.java @@ -3,9 +3,21 @@ package de.deadlocker8.budgetmaster.logic; import java.util.ArrayList; import de.deadlocker8.budgetmaster.logic.utils.LanguageType; +import de.deadlocker8.budgetmaster.logic.utils.SaveFileType; public class Settings { + /* + * VERSIONS + * + * --> 1 + * initial + * + */ + + @SuppressWarnings("unused") + private final String TYPE = SaveFileType.BUDGETMASTER_SETTINGS.toString(); + private final int VERSION = 1; private String clientSecret; private String url; private String secret; @@ -112,9 +124,15 @@ public class Settings return true; } + public int getVERSION() + { + return VERSION; + } + @Override public String toString() { - return "Settings [clientSecret=" + clientSecret + ", url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + ", trustedHosts=" + trustedHosts + ", language=" + language + ", autoUpdateCheckEnabled=" + autoUpdateCheckEnabled + "]"; + return "Settings [TYPE=" + TYPE + ", VERSION=" + VERSION + ", clientSecret=" + clientSecret + ", url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + ", trustedHosts=" + trustedHosts + ", language=" + language + ", autoUpdateCheckEnabled=" + + autoUpdateCheckEnabled + "]"; } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/Category.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/Category.java similarity index 95% rename from src/de/deadlocker8/budgetmaster/logic/Category.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/Category.java index 8c958bd05423425d659b10231613d6b0d6155922..b9daf6e12bda7ca7462e8a6997f14bd72190fca3 100644 --- a/src/de/deadlocker8/budgetmaster/logic/Category.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/Category.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.category; import de.deadlocker8.budgetmaster.logic.utils.Strings; import tools.Localization; diff --git a/src/de/deadlocker8/budgetmaster/logic/CategoryBudget.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/CategoryBudget.java similarity index 91% rename from src/de/deadlocker8/budgetmaster/logic/CategoryBudget.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/CategoryBudget.java index d4ddeb3b996b6f36a8649615c9096d33ab35b048..25ad57c5cdb8bc08dd84900464c4275d2f8ec3e2 100644 --- a/src/de/deadlocker8/budgetmaster/logic/CategoryBudget.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/CategoryBudget.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.category; public class CategoryBudget { diff --git a/src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/CategoryHandler.java similarity index 70% rename from src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/CategoryHandler.java index 974d26d0d440ca897004d346431a698f22af9a85..06fd51b8aac2958a453fb7f947b05c34760d7517 100644 --- a/src/de/deadlocker8/budgetmaster/logic/CategoryHandler.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/category/CategoryHandler.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.category; import java.util.ArrayList; @@ -32,6 +32,20 @@ public class CategoryHandler return categories; } + public ArrayList<Category> getCategoriesWithoutNone() + { + ArrayList<Category> categoriesWithoutNone = new ArrayList<>(); + for(Category currentCategory : categories) + { + if(currentCategory.getID() != 1) + { + categoriesWithoutNone.add(currentCategory); + } + } + + return categoriesWithoutNone; + } + public Category getCategory(int ID) { for(Category currentCategory : categories) diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java similarity index 86% rename from src/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java index 6668f410c097cd11eb64d7764bbf306f87be0057..5921ab8cd892b66e60b3935b92117e72c1631b3a 100644 --- a/src/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java @@ -2,7 +2,6 @@ package de.deadlocker8.budgetmaster.logic.charts; import java.util.ArrayList; -import de.deadlocker8.budgetmaster.logic.CategoryInOutSum; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; @@ -19,6 +18,7 @@ import javafx.scene.layout.Priority; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.scene.text.Font; import javafx.scene.transform.Transform; import javafx.stage.Modality; import javafx.stage.Stage; @@ -36,6 +36,7 @@ public class CategoriesChart extends VBox implements ChartExportable private LegendType legendType; private final double CHART_HEIGHT = 200; private final double FULL_LEGEND_ITEM_HEIGHT = 40; + private final double DELIMITER_HEIGHT = 21; public CategoriesChart(String titleIncomes, String titlePayments, ArrayList<CategoryInOutSum> categoryInOutSums, String currency, LegendType legendType) { @@ -177,10 +178,10 @@ public class CategoriesChart extends VBox implements ChartExportable double totalOut = getTotal(categoryInOutSums, false); HBox hboxLegend = new HBox(); - hboxLegend.setSpacing(10); + hboxLegend.setSpacing(0); VBox vboxCircles = new VBox(); - vboxCircles.setSpacing(10); + vboxCircles.setSpacing(10); VBox vboxNames = new VBox(); vboxNames.setSpacing(10); VBox vboxIn = new VBox(); @@ -196,7 +197,8 @@ public class CategoriesChart extends VBox implements ChartExportable Label labelHeaderName = new Label(Localization.getString(Strings.TITLE_CATEGORIES)); labelHeaderName.setStyle("-fx-font-weight: bold; -fx-underline: true;"); labelHeaderName.setMinHeight(20); - vboxNames.getChildren().add(labelHeaderName); + labelHeaderName.setPadding(new Insets(0, 0, 0, 10)); + vboxNames.getChildren().add(labelHeaderName); Label labelHeaderIn = new Label(Localization.getString(Strings.TITLE_INCOMES)); labelHeaderIn.setStyle("-fx-font-weight: bold; -fx-underline: true;"); @@ -208,33 +210,45 @@ public class CategoriesChart extends VBox implements ChartExportable labelHeaderOut.setMinHeight(20); vboxOut.getChildren().add(labelHeaderOut); - for(CategoryInOutSum currentItem : categoryInOutSums) - { + for(int i = 0; i < categoryInOutSums.size(); i++) + { + CategoryInOutSum currentItem = categoryInOutSums.get(i); + Label labelCircle = new Label(); labelCircle.setMinWidth(20); labelCircle.setMinHeight(20); labelCircle.setStyle("-fx-background-color: " + currentItem.getColor() + "; -fx-background-radius: 50%; -fx-border-width: 1; -fx-border-color: black - fx-border-radius: 50%"); - vboxCircles.getChildren().add(labelCircle); + vboxCircles.getChildren().add(labelCircle); Label labelName = new Label(currentItem.getName()); labelName.setStyle("-fx-font-weight: bold;"); labelName.setMinHeight(20); + labelName.setPadding(new Insets(0, 0, 0, 10)); vboxNames.getChildren().add(labelName); - String percentageIn = Helpers.NUMBER_FORMAT.format((currentItem.getBudgetIN() / totalIn)); + String percentageIn = totalIn != 0 ? Helpers.NUMBER_FORMAT.format(Math.abs((currentItem.getBudgetIN() / totalIn))) : "0,00"; Label labelInSum = new Label("+" + Helpers.getCurrencyString(currentItem.getBudgetIN(), currency) + " (" + percentageIn + "%)"); labelInSum.setStyle("-fx-font-weight: bold;"); labelInSum.setMinHeight(20); vboxIn.getChildren().add(labelInSum); - String percentageOut = Helpers.NUMBER_FORMAT.format((currentItem.getBudgetOUT() / totalOut)); + String percentageOut = totalOut != 0 ? Helpers.NUMBER_FORMAT.format(Math.abs((currentItem.getBudgetOUT() / totalOut))) : "0,00"; Label labelOutSum = new Label(Helpers.getCurrencyString(currentItem.getBudgetOUT(), currency) + " (" + percentageOut + "%)"); labelOutSum.setStyle("-fx-font-weight: bold;"); labelOutSum.setMinHeight(20); vboxOut.getChildren().add(labelOutSum); + + if(i < categoryInOutSums.size()-1) + { + //add delimiters + vboxCircles.getChildren().add(generateNewSeparator()); + vboxNames.getChildren().add(generateNewSeparator()); + vboxIn.getChildren().add(generateNewSeparator()); + vboxOut.getChildren().add(generateNewSeparator()); + } } - hboxLegend.getChildren().add(vboxCircles); + hboxLegend.getChildren().add(vboxCircles); hboxLegend.getChildren().add(vboxNames); HBox.setHgrow(vboxNames, Priority.ALWAYS); hboxLegend.getChildren().add(vboxIn); @@ -263,6 +277,17 @@ public class CategoriesChart extends VBox implements ChartExportable return legendItem; } + + private Label generateNewSeparator() + { + Label separator = new Label(); + separator.setStyle("-fx-background-color: #212121; -fx-padding: 0;"); + separator.setFont(new Font(1)); + separator.setMinHeight(1); + separator.setMaxHeight(1); + separator.setMaxWidth(Double.MAX_VALUE); + return separator; + } private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useIncomes) { @@ -322,6 +347,6 @@ public class CategoriesChart extends VBox implements ChartExportable @Override public double getSuggestedHeight() { - return CHART_HEIGHT + categoryInOutSums.size() * FULL_LEGEND_ITEM_HEIGHT + 50; + return CHART_HEIGHT + categoryInOutSums.size() * (FULL_LEGEND_ITEM_HEIGHT + DELIMITER_HEIGHT) + 50; } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/CategoryInOutSum.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/CategoryInOutSum.java similarity index 88% rename from src/de/deadlocker8/budgetmaster/logic/CategoryInOutSum.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/CategoryInOutSum.java index 5c9d569eee2847d48417a9cc0caee7a5ad5d0e4d..2d921f896e0c51f7c262772847f4c0c3761b6c34 100644 --- a/src/de/deadlocker8/budgetmaster/logic/CategoryInOutSum.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/CategoryInOutSum.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.charts; import de.deadlocker8.budgetmaster.logic.utils.Strings; import tools.Localization; @@ -19,6 +19,11 @@ public class CategoryInOutSum this.budgetIN = budgetIN; this.budgetOUT = budgetOUT; } + + public int getID() + { + return ID; + } public String getName() { @@ -27,6 +32,11 @@ public class CategoryInOutSum return Localization.getString(Strings.CATEGORY_NONE); } + if(ID == 2) + { + return Localization.getString(Strings.CATEGORY_REST); + } + return name; } diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/LegendType.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/LegendType.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/charts/LegendType.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/LegendType.java diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java similarity index 98% rename from src/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java index 4a0cef86ecea45aafbf1395feee06142dfb01dec..d579605e536fff2528cb3e6bdf5a8dfa56cc7618 100644 --- a/src/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java @@ -2,8 +2,6 @@ package de.deadlocker8.budgetmaster.logic.charts; import java.util.ArrayList; -import de.deadlocker8.budgetmaster.logic.CategoryInOutSum; -import de.deadlocker8.budgetmaster.logic.MonthInOutSum; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; diff --git a/src/de/deadlocker8/budgetmaster/logic/MonthInOutSum.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthInOutSum.java similarity index 95% rename from src/de/deadlocker8/budgetmaster/logic/MonthInOutSum.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthInOutSum.java index edc3d0f572bd1d87283f6d5dbcb0d56581e53fca..9d008662dc016bf1a33851a624fed5e44ab5f270 100644 --- a/src/de/deadlocker8/budgetmaster/logic/MonthInOutSum.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthInOutSum.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.charts; import java.util.ArrayList; diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java similarity index 99% rename from src/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java index b4e02909204f200a21c787cd48745ba009a1b023..015d9da3c1f45951cbc50c2a17f6382b9885d1b8 100644 --- a/src/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Set; -import de.deadlocker8.budgetmaster.logic.MonthInOutSum; import de.deadlocker8.budgetmaster.logic.utils.Colors; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; diff --git a/src/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java diff --git a/src/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/Database.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/Database.java new file mode 100644 index 0000000000000000000000000000000000000000..67b7ca2aae86844d829f7667a71d7b85f99702b2 --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/Database.java @@ -0,0 +1,82 @@ +package de.deadlocker8.budgetmaster.logic.database; + +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmaster.logic.tag.TagMatch; +import de.deadlocker8.budgetmaster.logic.utils.SaveFileType; + +public class Database +{ + /* + * VERSIONS + * + * --> 1 + * initial + * + * --> 2 + * added tags and tag matches (additional tables) + */ + + @SuppressWarnings("unused") + private final String TYPE = SaveFileType.BUDGETMASTER_DATABASE.toString(); + private final int VERSION = 2; + private ArrayList<Category> categories; + private ArrayList<NormalPayment> normalPayments; + private ArrayList<RepeatingPayment> repeatingPayments; + private ArrayList<Tag> tags; + private ArrayList<TagMatch> tagMatches; + + public Database() + { + + } + + public Database(ArrayList<Category> categories, ArrayList<NormalPayment> normalPayments, ArrayList<RepeatingPayment> repeatingPayments, ArrayList<Tag> tags, ArrayList<TagMatch> tagMatches) + { + this.categories = categories; + this.normalPayments = normalPayments; + this.repeatingPayments = repeatingPayments; + this.tags = tags; + this.tagMatches = tagMatches; + } + + public ArrayList<Category> getCategories() + { + return categories; + } + + public ArrayList<NormalPayment> getNormalPayments() + { + return normalPayments; + } + + public ArrayList<RepeatingPayment> getRepeatingPayments() + { + return repeatingPayments; + } + + public int getVERSION() + { + return VERSION; + } + + public ArrayList<Tag> getTags() + { + return tags; + } + + public ArrayList<TagMatch> getTagMatches() + { + return tagMatches; + } + + @Override + public String toString() + { + return "Database [VERSION=" + VERSION + ", categories=" + categories + ", normalPayments=" + normalPayments + ", repeatingPayments=" + repeatingPayments + ", tags=" + tags + ", tagMatches=" + tagMatches + "]"; + } +} \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/DatabaseImportExport.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/DatabaseImportExport.java new file mode 100644 index 0000000000000000000000000000000000000000..9fb4dae18f94e49901b45b2f437d1ac8b506756e --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/DatabaseImportExport.java @@ -0,0 +1,14 @@ +package de.deadlocker8.budgetmaster.logic.database; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to mark model classes that only exists in order to allow gson to import and export the database + * + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.SOURCE) +public @interface DatabaseImportExport {} \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/OldDatabase.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/OldDatabase.java new file mode 100644 index 0000000000000000000000000000000000000000..51b0448a043cd8767d5625239d059dde97ca07d6 --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/database/OldDatabase.java @@ -0,0 +1,45 @@ +package de.deadlocker8.budgetmaster.logic.database; + +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; + +/** + * this class is only used for backwards compatibility while importing database jsons files + */ +@Deprecated +public class OldDatabase +{ + private ArrayList<Category> categories; + private ArrayList<NormalPayment> normalPayments; + private ArrayList<RepeatingPayment> repeatingPayments; + + public OldDatabase() + { + + } + + public OldDatabase(ArrayList<Category> categories, ArrayList<NormalPayment> normalPayments, ArrayList<RepeatingPayment> repeatingPayments) + { + this.categories = categories; + this.normalPayments = normalPayments; + this.repeatingPayments = repeatingPayments; + } + + public ArrayList<Category> getCategories() + { + return categories; + } + + public ArrayList<NormalPayment> getNormalPayments() + { + return normalPayments; + } + + public ArrayList<RepeatingPayment> getRepeatingPayments() + { + return repeatingPayments; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/LatestRepeatingPayment.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/LatestRepeatingPayment.java similarity index 92% rename from src/de/deadlocker8/budgetmaster/logic/LatestRepeatingPayment.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/LatestRepeatingPayment.java index 4ac70eef388f1d35e06cf0e4509c26231af1ca66..ada7d739c10d23a9c10763097fab8082aec39f4c 100644 --- a/src/de/deadlocker8/budgetmaster/logic/LatestRepeatingPayment.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/LatestRepeatingPayment.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.payment; public class LatestRepeatingPayment { diff --git a/src/de/deadlocker8/budgetmaster/logic/NormalPayment.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/NormalPayment.java similarity index 84% rename from src/de/deadlocker8/budgetmaster/logic/NormalPayment.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/NormalPayment.java index f06a91e6ea961f4796f234a47d4d0a1327ba4690..2b168c2f7f8a6a3db9f86d54286eb72d9e216cfe 100644 --- a/src/de/deadlocker8/budgetmaster/logic/NormalPayment.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/NormalPayment.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.payment; public class NormalPayment extends Payment { @@ -7,6 +7,11 @@ public class NormalPayment extends Payment super(ID, amount, date, categoryID, name, description); } + public NormalPayment() + { + super(); + } + @Override public String toString() { diff --git a/src/de/deadlocker8/budgetmaster/logic/Payment.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/Payment.java similarity index 93% rename from src/de/deadlocker8/budgetmaster/logic/Payment.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/Payment.java index 8097353c2780fda914849ee9031330f372e379e3..4e6525e3f4d3ae77cea0c361c476be28ef679a21 100644 --- a/src/de/deadlocker8/budgetmaster/logic/Payment.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/Payment.java @@ -1,7 +1,7 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.payment; public abstract class Payment -{ +{ private int ID; private int amount; private String date; @@ -18,6 +18,11 @@ public abstract class Payment this.name = name; this.description = description; } + + public Payment() + { + + } public int getID() { diff --git a/src/de/deadlocker8/budgetmaster/logic/PaymentHandler.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentHandler.java similarity index 75% rename from src/de/deadlocker8/budgetmaster/logic/PaymentHandler.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentHandler.java index ecb61a71ccee4b7ca9cabcd9e3f5c7bdb26d39ce..a4732006121adbb03432f11cd7c0ae1d64d25595 100644 --- a/src/de/deadlocker8/budgetmaster/logic/PaymentHandler.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentHandler.java @@ -1,10 +1,13 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.payment; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.stream.Collectors; +import de.deadlocker8.budgetmaster.logic.FilterSettings; +import de.deadlocker8.budgetmaster.logic.tag.TagHandler; + public class PaymentHandler { private ArrayList<Payment> payments; @@ -24,6 +27,22 @@ public class PaymentHandler this.payments = payments; } + public int getPosition(Payment payment) + { + if(payment == null) + return -1; + + for(int i = 0; i < payments.size(); i++) + { + if(payment.getID() == payments.get(i).getID()) + { + return i; + } + } + + return -1; + } + public void sort() { Collections.sort(payments, new Comparator<Payment>() { @@ -134,13 +153,44 @@ public class PaymentHandler return new ArrayList<>(); } - public void filter(FilterSettings filterSettings) + private ArrayList<Payment> filterByTag(FilterSettings filterSettings, ArrayList<Payment> paymentsList, TagHandler tagHandler) throws Exception + { + if(filterSettings.getAllowedTagIDs() == null) + { + return paymentsList; + } + + if(filterSettings.getAllowedTagIDs().size() == 0) + { + return new ArrayList<>(); + } + + ArrayList<Payment> filteredPayments = new ArrayList<>(); + for(Payment currentPayment : paymentsList) + { + ArrayList<Integer> paymentTagIDs = tagHandler.getTagIDs(currentPayment); + + for(Integer tagID : filterSettings.getAllowedTagIDs()) + { + if(paymentTagIDs.contains(tagID)) + { + filteredPayments.add(currentPayment); + break; + } + } + } + + return filteredPayments; + } + + public void filter(FilterSettings filterSettings, TagHandler tagHandler) throws Exception { ArrayList<Payment> filteredPayments = filterByType(filterSettings, payments); filteredPayments = filterByType(filterSettings, filteredPayments); filteredPayments = filterByRepeating(filterSettings, filteredPayments); filteredPayments = filterByCategory(filterSettings, filteredPayments); filteredPayments = filterByName(filterSettings, filteredPayments); + filteredPayments = filterByTag(filterSettings, filteredPayments, tagHandler); payments = filteredPayments; } diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentJSONDeserializer.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentJSONDeserializer.java new file mode 100644 index 0000000000000000000000000000000000000000..84bb9fd2143399ab9fb5cf83c7fc093558bbc36c --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentJSONDeserializer.java @@ -0,0 +1,59 @@ +package de.deadlocker8.budgetmaster.logic.payment; + +import java.util.ArrayList; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; + +public class PaymentJSONDeserializer +{ + public static Payment deserializePayment(JsonObject paymentObject) + { + if(paymentObject.get("classType").getAsString().equals("NormalPayment")) + { + Payment payment = new NormalPayment(); + payment.setID(paymentObject.get("ID").getAsInt()); + payment.setAmount(paymentObject.get("amount").getAsInt()); + payment.setDate(paymentObject.get("date").getAsString()); + payment.setCategoryID(paymentObject.get("categoryID").getAsInt()); + payment.setName(paymentObject.get("name").getAsString()); + payment.setDescription(paymentObject.get("description").getAsString()); + return payment; + } + + if(paymentObject.get("classType").getAsString().equals("RepeatingPayment")) + { + RepeatingPayment payment = new RepeatingPayment(); + payment.setID(paymentObject.get("ID").getAsInt()); + payment.setAmount(paymentObject.get("amount").getAsInt()); + payment.setDate(paymentObject.get("date").getAsString()); + payment.setCategoryID(paymentObject.get("categoryID").getAsInt()); + payment.setName(paymentObject.get("name").getAsString()); + payment.setDescription(paymentObject.get("description").getAsString()); + + payment.setRepeatInterval(paymentObject.get("repeatInterval").getAsInt()); + payment.setRepeatMonthDay(paymentObject.get("repeatMonthDay").getAsInt()); + + JsonElement repeatEndDate = paymentObject.get("repeatEndDate"); + payment.setRepeatEndDate(repeatEndDate != JsonNull.INSTANCE ? repeatEndDate.getAsString() : null); + + return payment; + } + + return null; + } + + public static ArrayList<Payment> deserializePaymentList(JsonArray paymentArray) + { + ArrayList<Payment> payments = new ArrayList<>(); + + for(JsonElement currentElement : paymentArray) + { + payments.add(deserializePayment(currentElement.getAsJsonObject())); + } + + return payments; + } +} diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentJSONSerializer.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentJSONSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..0727bebe753c19ee0ea60394a41676e69ece999a --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/PaymentJSONSerializer.java @@ -0,0 +1,53 @@ +package de.deadlocker8.budgetmaster.logic.payment; + +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +public class PaymentJSONSerializer +{ + public static JsonObject serializePayment(Payment payment) + { + JsonObject paymentObject = new JsonObject(); + paymentObject.addProperty("ID", payment.getID()); + paymentObject.addProperty("amount", payment.getAmount()); + paymentObject.addProperty("date", payment.getDate()); + paymentObject.addProperty("categoryID", payment.getCategoryID()); + paymentObject.addProperty("name", payment.getName()); + paymentObject.addProperty("description", payment.getDescription()); + + if(payment instanceof NormalPayment) + { + paymentObject.addProperty("classType", "NormalPayment"); + } + + if(payment instanceof RepeatingPayment) + { + RepeatingPayment repeatingPayment = (RepeatingPayment)payment; + + paymentObject.addProperty("repeatInterval", repeatingPayment.getRepeatInterval()); + paymentObject.addProperty("repeatMonthDay", repeatingPayment.getRepeatMonthDay()); + paymentObject.addProperty("repeatEndDate", repeatingPayment.getRepeatEndDate()); + + paymentObject.addProperty("classType", "RepeatingPayment"); + } + + return paymentObject; + } + + public static JsonObject serializePaymentList(List<Payment> payments) + { + JsonArray paymentArray = new JsonArray(); + + for(Payment currentPayment : payments) + { + paymentArray.add(serializePayment(currentPayment)); + } + + JsonObject result = new JsonObject(); + result.add("payments", paymentArray); + + return result; + } +} diff --git a/src/de/deadlocker8/budgetmaster/logic/RepeatingPayment.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/RepeatingPayment.java similarity index 89% rename from src/de/deadlocker8/budgetmaster/logic/RepeatingPayment.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/RepeatingPayment.java index c3d2cee8b79e5cd61b539be0a43073a4841fcf28..6e2e0d8d1b64fde5b52d45edd8d2c183f16fe5df 100644 --- a/src/de/deadlocker8/budgetmaster/logic/RepeatingPayment.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/RepeatingPayment.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.payment; public class RepeatingPayment extends Payment { @@ -8,11 +8,16 @@ public class RepeatingPayment extends Payment public RepeatingPayment(int ID, int amount, String date, int categoryID, String name, String description, int repeatInterval, String repeatEndDate, int repeatMonthDay) { - super(ID, amount, date, categoryID, name, description); + super(ID, amount, date, categoryID, name, description); this.repeatInterval = repeatInterval; - this.repeatEndDate = repeatEndDate; + this.repeatEndDate = repeatEndDate; this.repeatMonthDay = repeatMonthDay; } + + public RepeatingPayment() + { + + } public int getRepeatInterval() { diff --git a/src/de/deadlocker8/budgetmaster/logic/RepeatingPaymentEntry.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/RepeatingPaymentEntry.java similarity index 96% rename from src/de/deadlocker8/budgetmaster/logic/RepeatingPaymentEntry.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/RepeatingPaymentEntry.java index 001f213c6cf9cc57eea73b5f8cab8c5c9997c671..9b97a7a91908920bc8deedfd1f834196258eaa41 100644 --- a/src/de/deadlocker8/budgetmaster/logic/RepeatingPaymentEntry.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/payment/RepeatingPaymentEntry.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.logic; +package de.deadlocker8.budgetmaster.logic.payment; public class RepeatingPaymentEntry extends Payment { diff --git a/src/de/deadlocker8/budgetmaster/logic/report/AmountType.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/AmountType.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/report/AmountType.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/AmountType.java diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ColumnType.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnType.java similarity index 96% rename from src/de/deadlocker8/budgetmaster/logic/report/ColumnType.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnType.java index 313f400cee9784d5483e9fd0d8f11fca3be23902..5401e1ffbd82e4c39ba02803e3f3944c7646ae3f 100644 --- a/src/de/deadlocker8/budgetmaster/logic/report/ColumnType.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ColumnType.java @@ -11,6 +11,7 @@ public enum ColumnType CATEGORY(Strings.REPORT_CATEGORY, 3), NAME(Strings.REPORT_NAME, 3), DESCRIPTION(Strings.REPORT_DESCRIPTION, 3), + TAGS(Strings.REPORT_TAGS, 3), RATING(Strings.REPORT_RATING, 1), AMOUNT(Strings.REPORT_AMOUNT, 2); diff --git a/src/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java similarity index 79% rename from src/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java index 3ff99a548ff30a38227ab3cf7ed4ed917ce21022..6ed310d207ddbdc2293fa9a6e87cf49386e63119 100644 --- a/src/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java @@ -2,16 +2,18 @@ package de.deadlocker8.budgetmaster.logic.report; import org.joda.time.DateTime; +import com.itextpdf.text.BaseColor; import com.itextpdf.text.Document; import com.itextpdf.text.Element; import com.itextpdf.text.Font; +import com.itextpdf.text.FontFactory; import com.itextpdf.text.Phrase; -import com.itextpdf.text.Font.FontFamily; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.ColumnText; -import com.itextpdf.text.pdf.GrayColor; import com.itextpdf.text.pdf.PdfPageEventHelper; import com.itextpdf.text.pdf.PdfWriter; +import de.deadlocker8.budgetmaster.logic.utils.Fonts; import de.deadlocker8.budgetmaster.logic.utils.Strings; import tools.Localization; @@ -24,7 +26,7 @@ public class HeaderFooterPageEvent extends PdfPageEventHelper public void onEndPage(PdfWriter writer, Document document) { - Font font = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, GrayColor.BLACK); + Font font = FontFactory.getFont(Fonts.OPEN_SANS, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 8, Font.NORMAL, BaseColor.BLACK); ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(Localization.getString(Strings.REPORT_FOOTER_LEFT), font), 100, 25, 0); ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(Localization.getString(Strings.REPORT_FOOTER_CENTER, document.getPageNumber()), font), 300, 25, 0); diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java similarity index 86% rename from src/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java index 60380bd2d412d3c67fb3bd1376e04d880cf190bc..38f7d53bd7e60d29ec468b769f46e3d5e5e685ad 100644 --- a/src/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java @@ -16,16 +16,18 @@ import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Font; -import com.itextpdf.text.Font.FontFamily; +import com.itextpdf.text.FontFactory; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Phrase; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.GrayColor; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import de.deadlocker8.budgetmaster.logic.Budget; -import de.deadlocker8.budgetmaster.logic.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.category.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.utils.Fonts; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmaster.logic.utils.Strings; import tools.Localization; @@ -39,7 +41,8 @@ public class ReportGenerator private String currency; private DateTime date; private Budget budget; - + private final String FONT = Fonts.OPEN_SANS; + public ReportGenerator(ArrayList<ReportItem> reportItems, ArrayList<CategoryBudget> categoryBudgets, ReportPreferences reportPreferences, File savePath, String currency, DateTime date, Budget budget) { this.reportItems = reportItems; @@ -52,9 +55,9 @@ public class ReportGenerator } private Chapter generateHeader() - { - Font chapterFont = new Font(FontFamily.HELVETICA, 16, Font.BOLDITALIC); - Chunk chunk = new Chunk(Localization.getString(Strings.REPORT_HEADLINE, date.toString("MMMM yyyy")), chapterFont); + { + Font font = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 16, Font.BOLDITALIC, BaseColor.BLACK); + Chunk chunk = new Chunk(Localization.getString(Strings.REPORT_HEADLINE, date.toString("MMMM yyyy")), font); Chapter chapter = new Chapter(new Paragraph(chunk), 1); chapter.setNumberDepth(0); chapter.add(Chunk.NEWLINE); @@ -77,7 +80,7 @@ public class ReportGenerator PdfPTable table = new PdfPTable(proportions); table.setWidthPercentage(tableWidth); - Font font = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, GrayColor.BLACK); + Font font = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 8, Font.NORMAL, GrayColor.BLACK); for(ColumnType column : reportPreferences.getColumnOrder().getColumns()) { @@ -151,18 +154,19 @@ public class ReportGenerator PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(savePath)); writer.setPageEvent(new HeaderFooterPageEvent()); document.open(); - document.setMargins(50, 45, 50, 70); - Font headerFont = new Font(FontFamily.HELVETICA, 14, Font.BOLD); - Font smallHeaderFont = new Font(FontFamily.HELVETICA, 12, Font.BOLD); + document.setMargins(50, 45, 50, 70); + Font headerFont = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 14, Font.BOLD, BaseColor.BLACK); + Font smallHeaderFont = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12, Font.BOLD, BaseColor.BLACK); document.add(generateHeader()); document.add(Chunk.NEWLINE); if(reportPreferences.isIncludeBudget()) - { - Font fontGreen = new Font(FontFamily.HELVETICA, 12, Font.NORMAL, new BaseColor(36, 122, 45)); - Font fontRed = new Font(FontFamily.HELVETICA, 12, Font.NORMAL, BaseColor.RED); - Font fontBlack = new Font(FontFamily.HELVETICA, 12, Font.BOLD); + { + Font fontGreen = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12, Font.NORMAL, new BaseColor(36, 122, 45)); + Font fontRed = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12, Font.NORMAL, BaseColor.RED); + Font fontBlack = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12, Font.BOLD, BaseColor.BLACK); + document.add(new Paragraph("Budget", headerFont)); document.add(Chunk.NEWLINE); document.add(new Paragraph("Einnahmen: " + Helpers.getCurrencyString(budget.getIncomeSum(), currency), fontGreen)); @@ -207,7 +211,7 @@ public class ReportGenerator if(reportPreferences.isIncludeCategoryBudgets()) { document.add(Chunk.NEWLINE); - document.add(new Paragraph(Localization.getString(Strings.TITLE_CATEGORY_BUDGETS), headerFont)); + document.add(new Paragraph(Localization.getString(Strings.TITLE_CATEGORY_BUDGETS), smallHeaderFont)); document.add(Chunk.NEWLINE); PdfPTable table = generateCategoryBudgets(); @@ -224,7 +228,7 @@ public class ReportGenerator { PdfPTable table = new PdfPTable(2); table.setWidthPercentage(100); - Font font = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, GrayColor.BLACK); + Font font = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 8, Font.NORMAL, BaseColor.BLACK); //header cells PdfPCell cellHeaderCategory = new PdfPCell(new Phrase(Localization.getString(Strings.TITLE_CATEGORY), font)); @@ -264,6 +268,8 @@ public class ReportGenerator return DateTime.parse(reportItem.getDate(), DateTimeFormat.forPattern("YYYY-MM-dd")).toString("dd.MM.YYYY"); case DESCRIPTION: return reportItem.getDescription(); + case TAGS: + return reportItem.getTags(); case NAME: return reportItem.getName(); case POSITION: diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ReportItem.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportItem.java similarity index 82% rename from src/de/deadlocker8/budgetmaster/logic/report/ReportItem.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportItem.java index d155a69481267a722b24355ae233374f3acc8ea1..c26a6e4f6a0c93ccdb0bf935b59ecaa56fe24871 100644 --- a/src/de/deadlocker8/budgetmaster/logic/report/ReportItem.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportItem.java @@ -1,6 +1,6 @@ package de.deadlocker8.budgetmaster.logic.report; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; public class ReportItem { @@ -10,6 +10,7 @@ public class ReportItem private Category category; private String name; private String description; + private String tags; private boolean repeating; public ReportItem() @@ -75,6 +76,16 @@ public class ReportItem public void setDescription(String description) { this.description = description; + } + + public String getTags() + { + return tags; + } + + public void setTags(String tags) + { + this.tags = tags; } public boolean getRepeating() @@ -90,6 +101,6 @@ public class ReportItem @Override public String toString() { - return "ReportItem [position=" + position + ", amount=" + amount + ", date=" + date + ", category=" + category + ", name=" + name + ", description=" + description + ", isRepeating=" + repeating + "]"; + return "ReportItem [position=" + position + ", amount=" + amount + ", date=" + date + ", category=" + category + ", name=" + name + ", description=" + description + ", tags=" + tags + ", repeating=" + repeating + "]"; } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ReportPreferences.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportPreferences.java similarity index 60% rename from src/de/deadlocker8/budgetmaster/logic/report/ReportPreferences.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportPreferences.java index 9f1b89a7b926a360406c5856a25eb72cdfb04362..e358e1817d682a66006cc7c42033b9eace929272 100644 --- a/src/de/deadlocker8/budgetmaster/logic/report/ReportPreferences.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportPreferences.java @@ -1,25 +1,47 @@ package de.deadlocker8.budgetmaster.logic.report; +import de.deadlocker8.budgetmaster.logic.utils.SaveFileType; + public class ReportPreferences { + /* + * VERSIONS + * + * --> 1 + * initial + * + * --> 2 + * added last export folder as reportFolderPath + */ + + @SuppressWarnings("unused") + private final String TYPE = SaveFileType.BUDGETMASTER_REPORT_PREFERENCES.toString(); + private final int VERSION = 2; private ColumnOrder columnOrder; private boolean includeBudget; private boolean splitTable; private boolean includeCategoryBudgets; private ReportSorting reportSorting; + private String reportFolderPath; public ReportPreferences() { } - public ReportPreferences(ColumnOrder columnOrder, boolean includeBudget, boolean splitTable, boolean includeCategoryBudgets, ReportSorting reportSorting) - { + public ReportPreferences(ColumnOrder columnOrder, boolean includeBudget, boolean splitTable, boolean includeCategoryBudgets, ReportSorting reportSorting, String reportFolderPath) + { this.columnOrder = columnOrder; this.includeBudget = includeBudget; this.splitTable = splitTable; this.includeCategoryBudgets = includeCategoryBudgets; this.reportSorting = reportSorting; + this.reportFolderPath = reportFolderPath; + } + + public int getVERSION() + { + return VERSION; } public ColumnOrder getColumnOrder() @@ -71,10 +93,20 @@ public class ReportPreferences { this.reportSorting = reportSorting; } + + public String getReportFolderPath() + { + return reportFolderPath; + } + + public void setReportFolderPath(String reportFolderPath) + { + this.reportFolderPath = reportFolderPath; + } @Override public String toString() { - return "ReportPreferences [columnOrder=" + columnOrder + ", includeBudget=" + includeBudget + ", splitTable=" + splitTable + ", includeCategoryBudgets=" + includeCategoryBudgets + ", reportSorting=" + reportSorting + "]"; + return "ReportPreferences [VERSION=" + VERSION + ", columnOrder=" + columnOrder + ", includeBudget=" + includeBudget + ", splitTable=" + splitTable + ", includeCategoryBudgets=" + includeCategoryBudgets + ", reportSorting=" + reportSorting + ", reportFolderPath=" + reportFolderPath + "]"; } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ReportSorting.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportSorting.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/report/ReportSorting.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportSorting.java diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/search/SearchPreferences.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/search/SearchPreferences.java new file mode 100644 index 0000000000000000000000000000000000000000..3c327559e63a93289df9c0da74d6d9dcf513641f --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/search/SearchPreferences.java @@ -0,0 +1,122 @@ +package de.deadlocker8.budgetmaster.logic.search; + +public class SearchPreferences +{ + private String lastQuery; + private boolean searchName; + private boolean searchDescription; + private boolean searchCategorNames; + private boolean searchTags; + private boolean searchAmount; + private int minAmount; + private int maxAmount; + + public SearchPreferences() + { + + } + + public SearchPreferences(String lastQuery, boolean searchName, boolean searchDescription, boolean searchCategorNames, boolean searchTags, boolean searchAmount, int minAmount, int maxAmount) + { + this.lastQuery = lastQuery; + this.searchName = searchName; + this.searchDescription = searchDescription; + this.searchCategorNames = searchCategorNames; + this.searchTags = searchTags; + this.searchAmount = searchAmount; + this.minAmount = minAmount; + this.maxAmount = maxAmount; + } + + public String getLastQuery() + { + return lastQuery; + } + + public void setLastQuery(String lastQuery) + { + this.lastQuery = lastQuery; + } + + public boolean isSearchName() + { + return searchName; + } + + public void setSearchName(boolean searchName) + { + this.searchName = searchName; + } + + public boolean isSearchDescription() + { + return searchDescription; + } + + public void setSearchDescription(boolean searchDescription) + { + this.searchDescription = searchDescription; + } + + public boolean isSearchCategorNames() + { + return searchCategorNames; + } + + public void setSearchCategorNames(boolean searchCategorNames) + { + this.searchCategorNames = searchCategorNames; + } + + public boolean isSearchTags() + { + return searchTags; + } + + public void setSearchTags(boolean searchTags) + { + this.searchTags = searchTags; + } + + public boolean isSearchAmount() + { + return searchAmount; + } + + public void setSearchAmount(boolean searchAmount) + { + this.searchAmount = searchAmount; + } + + public int getMinAmount() + { + return minAmount; + } + + public void setMinAmount(int minAmount) + { + this.minAmount = minAmount; + } + + public int getMaxAmount() + { + return maxAmount; + } + + public void setMaxAmount(int maxAmount) + { + this.maxAmount = maxAmount; + } + + public void searchPreferences(int maxAmount) + { + this.maxAmount = maxAmount; + } + + @Override + public String toString() + { + return "SearchPreferences [lastQuery=" + lastQuery + ", searchName=" + searchName + ", searchDescription=" + searchDescription + ", searchCategorNames=" + searchCategorNames + ", searchTags=" + searchTags + ", searchAmount=" + searchAmount + ", minAmount=" + minAmount + ", maxAmount=" + + maxAmount + "]"; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java diff --git a/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java similarity index 84% rename from src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java index bfd251cfe0bbb528fbaa15f7335eefce01eb3a25..86191f4c14ed4a065a880a7bc5f38934abd8f4df 100644 --- a/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java @@ -17,19 +17,23 @@ import javax.net.ssl.X509TrustManager; import org.joda.time.DateTime; import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.CategoryBudget; -import de.deadlocker8.budgetmaster.logic.CategoryInOutSum; -import de.deadlocker8.budgetmaster.logic.MonthInOutSum; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; import de.deadlocker8.budgetmaster.logic.Settings; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.category.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.charts.CategoryInOutSum; +import de.deadlocker8.budgetmaster.logic.charts.MonthInOutSum; +import de.deadlocker8.budgetmaster.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.PaymentJSONDeserializer; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; import de.deadlocker8.budgetmaster.logic.utils.Helpers; -import de.deadlocker8.budgetmasterserver.logic.database.Database; import tools.Read; public class ServerConnection @@ -229,7 +233,7 @@ public class ServerConnection } } - public void addNormalPayment(NormalPayment payment) throws Exception + public Integer addNormalPayment(NormalPayment payment) throws Exception { URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName()) + "&description=" + Helpers.getURLEncodedString(payment.getDescription())); @@ -238,9 +242,8 @@ public class ServerConnection httpsCon.setDoInput(true); if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) { - InputStream stream = httpsCon.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - reader.close(); + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Integer.class); } else { @@ -267,7 +270,7 @@ public class ServerConnection } } - public void addRepeatingPayment(RepeatingPayment payment) throws Exception + public Integer addRepeatingPayment(RepeatingPayment payment) throws Exception { String repeatEndDate = payment.getRepeatEndDate(); if(repeatEndDate == null || repeatEndDate.equals("")) @@ -283,9 +286,8 @@ public class ServerConnection httpsCon.setDoInput(true); if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) { - InputStream stream = httpsCon.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - reader.close(); + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Integer.class); } else { @@ -328,6 +330,72 @@ public class ServerConnection throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); } } + + public ArrayList<Payment> getPaymentsForSearch(String query, boolean searchName, boolean searchDescription, boolean searchCategoryName, boolean searchTags, boolean searchAmount, int minAmount, int maxAmount) throws Exception + { + String urlString = settings.getUrl() + "/payment/search?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&query=" + Helpers.getURLEncodedString(query); + if(searchName) + { + urlString += "&name=" + 1; + } + + if(searchDescription) + { + urlString += "&description=" + 1; + } + + if(searchCategoryName) + { + urlString += "&categoryName=" + 1; + } + + if(searchTags) + { + urlString += "&tags=" + 1; + } + + if(searchAmount) + { + urlString += "&minAmount=" + minAmount; + urlString += "&maxAmount=" + maxAmount; + } + + URL url = new URL(urlString); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + JsonParser parser = new JsonParser(); + JsonElement resultJSON = parser.parse(result); + + return PaymentJSONDeserializer.deserializePaymentList(resultJSON.getAsJsonObject().get("payments").getAsJsonArray()); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public int getMaxAmount() throws Exception + { + URL url = new URL(settings.getUrl() + "/payment/search/maxAmount?secret=" + Helpers.getURLEncodedString(settings.getSecret())); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Integer.class); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } /* * CATEGORYBUDGET diff --git a/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerTagConnection.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerTagConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..858de8646b233295b714d2117a919c65caf4088d --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerTagConnection.java @@ -0,0 +1,309 @@ +package de.deadlocker8.budgetmaster.logic.serverconnection; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; +import java.net.URL; +import java.security.cert.X509Certificate; +import java.util.ArrayList; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import de.deadlocker8.budgetmaster.logic.Settings; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmaster.logic.utils.Helpers; +import tools.Read; + +public class ServerTagConnection +{ + private Settings settings; + private Gson gson; + + public ServerTagConnection(Settings settings) throws Exception + { + this.settings = settings; + this.gson = new Gson(); + + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() + { + public java.security.cert.X509Certificate[] getAcceptedIssuers() + { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) + { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) + { + } + } }; + + // Install the all-trusting trust manager + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + + // check whitelist + HttpsURLConnection.setDefaultHostnameVerifier((hostname, sslSession) -> settings.getTrustedHosts().contains(hostname)); + } + + public ArrayList<Tag> getTags() throws Exception + { + URL url = new URL(settings.getUrl() + "/tag?secret=" + Helpers.getURLEncodedString(settings.getSecret())); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + // required by GSON + Type listType = new TypeToken<ArrayList<Tag>>() + { + }.getType(); + return gson.fromJson(result, listType); + } + else + { + return new ArrayList<>(); + } + } + + public Tag getTag(int ID) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/single?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + ID); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Tag.class); + } + else + { + return null; + } + } + + public Tag getTag(String name) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/single/byName?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&name=" + Helpers.getURLEncodedString(name)); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Tag.class); + } + else + { + return null; + } + } + + public void addTag(Tag tag) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&name=" + Helpers.getURLEncodedString(tag.getName())); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setRequestMethod("POST"); + httpsCon.setDoInput(true); + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + InputStream stream = httpsCon.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + reader.close(); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public void deleteTag(int ID) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + ID); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setRequestMethod("DELETE"); + httpsCon.setDoInput(true); + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + InputStream stream = httpsCon.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + reader.close(); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + /* + * tag match + */ + public boolean isMatchExistingForPayment(int tagID, NormalPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/normal?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&tagID=" + tagID + "&paymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Boolean.class); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public boolean isMatchExistingForRepeatingPayment(int tagID, RepeatingPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/repeating?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&tagID=" + tagID + "&repeatingPaymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + return gson.fromJson(result, Boolean.class); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public void addTagMatchForPayment(int tagID, NormalPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/normal?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&tagID=" + tagID + "&paymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setRequestMethod("POST"); + httpsCon.setDoInput(true); + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + InputStream stream = httpsCon.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + reader.close(); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public void addTagMatchForRepeatingPayment(int tagID, RepeatingPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/repeating?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&tagID=" + tagID + "&repeatingPaymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setRequestMethod("POST"); + httpsCon.setDoInput(true); + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + InputStream stream = httpsCon.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + reader.close(); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public void deleteTagMatchForPayment(int tagID, NormalPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/normal?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&tagID=" + tagID + "&paymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setRequestMethod("DELETE"); + httpsCon.setDoInput(true); + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + InputStream stream = httpsCon.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + reader.close(); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public void deleteTagMatchForRepeatingPayment(int tagID, RepeatingPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/repeating?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&tagID=" + tagID + "&repeatingPaymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setRequestMethod("DELETE"); + httpsCon.setDoInput(true); + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + InputStream stream = httpsCon.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + reader.close(); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + + public ArrayList<Tag> getAllTagsForPayment(NormalPayment payment) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/all/normal?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&paymentID=" + payment.getID()); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + // required by GSON + Type listType = new TypeToken<ArrayList<Tag>>() + { + }.getType(); + return gson.fromJson(result, listType); + } + else + { + return new ArrayList<>(); + } + } + + public ArrayList<Tag> getAllTagsForRepeatingPayment(int repeatingPaymentID) throws Exception + { + URL url = new URL(settings.getUrl() + "/tag/match/all/repeating?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&repeatingPaymentID=" + repeatingPaymentID); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + String result = Read.getStringFromInputStream(httpsCon.getInputStream()); + // required by GSON + Type listType = new TypeToken<ArrayList<Tag>>() + { + }.getType(); + return gson.fromJson(result, listType); + } + else + { + return new ArrayList<>(); + } + } +} \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/Tag.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/Tag.java new file mode 100644 index 0000000000000000000000000000000000000000..a9a23fc0fe4e2ad97054a1ba6a420b5a1f1f961f --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/Tag.java @@ -0,0 +1,39 @@ +package de.deadlocker8.budgetmaster.logic.tag; + +public class Tag +{ + private int ID; + private String name; + + public Tag(int ID, String name) + { + this.ID = ID; + this.name = name; + } + + public int getID() + { + return ID; + } + + public void setID(int ID) + { + this.ID = ID; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + @Override + public String toString() + { + return "Tag [ID=" + ID + ", Name=" + name + "]"; + } +} \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/TagHandler.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/TagHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..d4f0f17311eadfa9020c542847211701d7fcb40b --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/TagHandler.java @@ -0,0 +1,65 @@ +package de.deadlocker8.budgetmaster.logic.tag; + +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.Settings; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerTagConnection; + +public class TagHandler +{ + private Settings settings; + + public TagHandler(Settings settings) + { + this.settings = settings; + } + + public ArrayList<Tag> getTags(Payment payment) throws Exception + { + ArrayList<Tag> tags = new ArrayList<>(); + + ServerTagConnection connection = new ServerTagConnection(settings); + + if(payment instanceof NormalPayment) + { + tags.addAll(connection.getAllTagsForPayment((NormalPayment)payment)); + } + else + { + tags.addAll(connection.getAllTagsForRepeatingPayment(((RepeatingPaymentEntry)payment).getRepeatingPaymentID())); + } + + return tags; + } + + public String getTagsAsString(Payment payment) throws Exception + { + ArrayList<Tag> tags = getTags(payment); + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < tags.size(); i++) + { + sb.append(tags.get(i).getName()); + if(i != tags.size()-1) + { + sb.append(", "); + } + } + + return sb.toString(); + } + + public ArrayList<Integer> getTagIDs(Payment payment) throws Exception + { + ArrayList<Tag> tags = getTags(payment); + ArrayList<Integer> ids = new ArrayList<>(); + for(Tag currentTag : tags) + { + ids.add(currentTag.getID()); + } + + return ids; + } +} \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/TagMatch.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/TagMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..7177bee480e0335e410f6ce00065781bdddf9b8c --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/tag/TagMatch.java @@ -0,0 +1,59 @@ +package de.deadlocker8.budgetmaster.logic.tag; + +import de.deadlocker8.budgetmaster.logic.database.DatabaseImportExport; + +@DatabaseImportExport +public class TagMatch +{ + private int tagID; + private int paymentID; + private int repeatingPaymentID; + + public TagMatch(int tagID, int paymentID, int repeatingPaymentID) + { + this.tagID = tagID; + this.paymentID = paymentID; + this.repeatingPaymentID = repeatingPaymentID; + } + + public TagMatch() + { + + } + + public int getTagID() + { + return tagID; + } + + public void setTagID(int tagID) + { + this.tagID = tagID; + } + + public int getPaymentID() + { + return paymentID; + } + + public void setPaymentID(int paymentID) + { + this.paymentID = paymentID; + } + + public int getRepeatingPaymentID() + { + return repeatingPaymentID; + } + + public void setRepeatingPaymentID(int repeatingPaymentID) + { + this.repeatingPaymentID = repeatingPaymentID; + } + + @Override + public String toString() + { + return "TagMatch [tagID=" + tagID + ", paymentID=" + paymentID + ", repeatingPaymentID=" + repeatingPaymentID + "]"; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/updater/Updater.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java similarity index 85% rename from src/de/deadlocker8/budgetmaster/logic/updater/Updater.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java index 72f5835fec13c5b4c674b3e5b4d7dbd68b789702..9b6fc104146616f9425f090353dd0ca9f8ba9389 100644 --- a/src/de/deadlocker8/budgetmaster/logic/updater/Updater.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java @@ -11,7 +11,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; +import java.util.Properties; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -41,35 +41,14 @@ public class Updater URL webseite = new URL(LATEST_VERSION_INFO_URL); URLConnection connection = webseite.openConnection(); - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String line; - - ArrayList<String> lines = new ArrayList<String>(); - - while ((line = br.readLine()) != null) - { - lines.add(line); - } - + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + VersionInformation versionInfo = new VersionInformation(); - - for(String currentLine : lines) - { - if(currentLine.contains("version.code")) - { - versionInfo.setVersionCode(Integer.parseInt(currentLine.substring(currentLine.indexOf("=") + 1, currentLine.length()))); - } - - if(currentLine.contains("version.name")) - { - versionInfo.setVersionName(currentLine.substring(currentLine.indexOf("=") + 1, currentLine.length())); - } - - if(currentLine.contains("version.date")) - { - versionInfo.setDate(currentLine.substring(currentLine.indexOf("=") + 1, currentLine.length())); - } - } + Properties properties = new Properties(); + properties.load(bufferedReader); + versionInfo.setVersionCode(Integer.parseInt(properties.getProperty("version.code", "-1"))); + versionInfo.setVersionName(properties.getProperty("version.name")); + versionInfo.setDate(properties.getProperty("version.date")); if(!versionInfo.isComplete()) throw new IllegalArgumentException("VersionInformation not complete"); diff --git a/src/de/deadlocker8/budgetmaster/logic/updater/VersionInformation.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/VersionInformation.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/updater/VersionInformation.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/VersionInformation.java diff --git a/src/de/deadlocker8/budgetmaster/logic/utils/Colors.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Colors.java similarity index 99% rename from src/de/deadlocker8/budgetmaster/logic/utils/Colors.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Colors.java index 6f7d97513e1df3ece7d608315729be6945227181..7d394d24822956a1d04fd86912a643e6419d25c0 100644 --- a/src/de/deadlocker8/budgetmaster/logic/utils/Colors.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Colors.java @@ -14,7 +14,7 @@ public class Colors public static final Color BACKGROUND_BUTTON_RED = Color.web("#FF5047"); public static final Color BACKGROUND_NOTIFICATION = Color.web("#323232"); public static final Color BACKGROUND_REPORT_TABLE_HEADER_DISABLED = Color.SALMON; - public static final Color BACKGROUND_CHART_LEGEND = Color.web("#EEEEEE"); + public static final Color BACKGROUND_CHART_LEGEND = Color.web("#DDDDDD"); // CATEGORIES public static final Color CATEGORIES_LIGHT_GREY = Color.web("#EEEEEE"); @@ -32,5 +32,4 @@ public class Colors public static final Color CATEGORIES_LIGHT_BLUE = Color.rgb(90,200,250); public static final Color CATEGORIES_LIGHT_GREEN = Color.rgb(76,217,100); public static final Color CATEGORIES_DARK_GREEN = Color.rgb(46,124,43); - } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java similarity index 59% rename from src/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java index 3b0c4da6d85cf27f17078403097d5649d4110f26..1f4353564f28e2e27f1c16258354effeff16df5e 100644 --- a/src/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java @@ -1,5 +1,6 @@ package de.deadlocker8.budgetmaster.logic.utils; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.Reader; @@ -7,24 +8,29 @@ import java.io.Writer; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.ArrayList; import com.google.gson.Gson; import de.deadlocker8.budgetmaster.logic.Settings; -import de.deadlocker8.budgetmasterserver.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.database.OldDatabase; +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmaster.logic.tag.TagMatch; import tools.Localization; import tools.PathUtils; +@SuppressWarnings("deprecation") public class FileHelper -{ +{ public static Settings loadSettings() { Settings settings; try { - Gson gson = new Gson(); + Gson gson = new Gson(); Reader reader = Files.newBufferedReader(Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER) + "/settings.json"), Charset.forName("UTF-8")); - settings = gson.fromJson(reader, Settings.class); + settings = gson.fromJson(reader, Settings.class); reader.close(); return settings; } @@ -33,9 +39,9 @@ public class FileHelper return null; } } - + public static void saveSettings(Settings settings) throws IOException - { + { Gson gson = new Gson(); String jsonString = gson.toJson(settings); PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER))); @@ -43,28 +49,66 @@ public class FileHelper writer.write(jsonString); writer.close(); } - + public static Database loadDatabaseJSON(File file) throws IOException - { + { Gson gson = new Gson(); - Reader reader = Files.newBufferedReader(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8")); - Database database = gson.fromJson(reader, Database.class); + BufferedReader reader = Files.newBufferedReader(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8")); + + StringBuilder sb = new StringBuilder(); + String line; + while((line = reader.readLine()) != null) + { + sb.append(line); + } + reader.close(); - return database; + String jsonString = sb.toString(); + if(jsonString.contains("BUDGETMASTER_DATABASE")) + { + if(jsonString.contains("VERSION")) + { + int start = jsonString.indexOf("\"VERSION\": "); + start = start + 11; + int version = Integer.parseInt(jsonString.substring(start, start + 1)); + Database database; + + switch(version) + { + case 2: database = gson.fromJson(jsonString, Database.class); + break; + default: return loadOldDatabase(gson, jsonString); + } + return database; + } + } + + return loadOldDatabase(gson, jsonString); } + private static Database loadOldDatabase(Gson gson, String jsonString) throws IOException + { + // database version = 1 (prior to BudgetMaster 1.6.0) + OldDatabase olDatabase = gson.fromJson(jsonString, OldDatabase.class); + return new Database(olDatabase.getCategories(), + olDatabase.getNormalPayments(), + olDatabase.getRepeatingPayments(), + new ArrayList<Tag>(), + new ArrayList<TagMatch>()); + } + public static void saveDatabaseJSON(File file, String databaseJSON) throws IOException - { + { Writer writer = Files.newBufferedWriter(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8")); writer.write(databaseJSON); writer.close(); } - + public static Object loadObjectFromJSON(String fileName, Object objectype) - { + { try { - Gson gson = new Gson(); + Gson gson = new Gson(); Reader reader = Files.newBufferedReader(Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER) + "/" + fileName + ".json"), Charset.forName("UTF-8")); Object preferences = gson.fromJson(reader, objectype.getClass()); reader.close(); @@ -75,9 +119,9 @@ public class FileHelper return null; } } - + public static void saveObjectToJSON(String fileName, Object objectToSave) throws IOException - { + { Gson gson = new Gson(); String jsonString = gson.toJson(objectToSave); PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER))); diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Fonts.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Fonts.java new file mode 100644 index 0000000000000000000000000000000000000000..d69997c9f1de948ce2c6ea35c83402ac17e94d1f --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Fonts.java @@ -0,0 +1,6 @@ +package de.deadlocker8.budgetmaster.logic.utils; + +public class Fonts +{ + public static final String OPEN_SANS = "/de/deadlocker8/budgetmaster/resources/fonts/OpenSans-Regular.ttf"; +} diff --git a/src/de/deadlocker8/budgetmaster/logic/utils/Helpers.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java similarity index 76% rename from src/de/deadlocker8/budgetmaster/logic/utils/Helpers.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java index 9c105dcde51c46379359920072cddbdfd90fac09..53539a1a10de04426648db4730dc03188c29d650 100644 --- a/src/de/deadlocker8/budgetmaster/logic/utils/Helpers.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java @@ -1,6 +1,5 @@ package de.deadlocker8.budgetmaster.logic.utils; -import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.DecimalFormat; @@ -8,17 +7,9 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import de.deadlocker8.budgetmaster.ui.controller.ModalController; import fontAwesome.FontIcon; import fontAwesome.FontIconType; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.image.Image; import javafx.scene.paint.Color; -import javafx.stage.Modality; -import javafx.stage.Stage; -import logger.Logger; import tools.Localization; public class Helpers @@ -117,30 +108,15 @@ public class Helpers return icon; } - public static Stage showModal(String title, String message, Stage owner, Image icon) + /** + * Replaces line breaks and tabs with spaces + * @param text + * @return String + */ + public static String getFlatText(String text) { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(Helpers.class.getResource("/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml")); - Parent root = (Parent)fxmlLoader.load(); - fxmlLoader.setResources(Localization.getBundle()); - Stage newStage = new Stage(); - newStage.initOwner(owner); - newStage.initModality(Modality.APPLICATION_MODAL); - newStage.setTitle(title); - newStage.setScene(new Scene(root)); - newStage.getIcons().add(icon); - newStage.setResizable(false); - ModalController newController = fxmlLoader.getController(); - newController.init(newStage, message); - newStage.show(); - - return newStage; - } - catch(IOException e) - { - Logger.error(e); - return null; - } + text = text.replace("\n", " "); + text = text.replace("\t", " "); + return text; } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/utils/LanguageType.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/LanguageType.java similarity index 100% rename from src/de/deadlocker8/budgetmaster/logic/utils/LanguageType.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/LanguageType.java diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/SaveFileType.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/SaveFileType.java new file mode 100644 index 0000000000000000000000000000000000000000..a5cf884f072415e071f093dc90e155b3363c5dbd --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/SaveFileType.java @@ -0,0 +1,8 @@ +package de.deadlocker8.budgetmaster.logic.utils; + +public enum SaveFileType +{ + BUDGETMASTER_DATABASE, + BUDGETMASTER_REPORT_PREFERENCES, + BUDGETMASTER_SETTINGS +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/utils/Strings.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java similarity index 94% rename from src/de/deadlocker8/budgetmaster/logic/utils/Strings.java rename to BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java index 1da9cedd55456ff0d8c5b5ba15ec10449f09ba1b..9ab0bee5897f92c683e6615f4775343b82e6ed58 100644 --- a/src/de/deadlocker8/budgetmaster/logic/utils/Strings.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java @@ -30,18 +30,23 @@ public class Strings public static final String TITLE_PAYMENT_EDIT = "title.payment.edit"; public static final String TITLE_PAYMENT_NEW = "title.payment.new"; public static final String TITLE_FILTER = "title.filter"; + public static final String TITLE_SEARCH = "title.search"; public static final String TITLE_REPORT_SAVE = "title.report.save"; public static final String TITLE_DATABASE_EXPORT = "title.database.export"; public static final String TITLE_DATABASE_IMPORT = "title.database.import"; + public static final String TITLE_DATEPICKER = "title.datepicker"; + public static final String TITLE_TAGS = "title.tags"; //LOAD public static final String LOAD_CHARTS = "load.charts"; public static final String LOAD_DATA = "load.data"; + public static final String LOAD_REPORT_TAB = "load.report.tab"; public static final String LOAD_REPORT = "load.report"; public static final String LOAD_DATABASE_EXPORT = "load.database.export"; public static final String LOAD_DATABASE_IMPORT = "load.database.import"; public static final String LOAD_DATABASE_DELETE = "load.database.delete"; public static final String LOAD_UPDATE = "load.update"; + public static final String LOAD_SEARCH = "load.search"; //MISC public static final String CATEGORY_NONE = "category.none"; @@ -61,6 +66,7 @@ public class Strings public static final String TRUSTED_HOSTS_PLACEHOLDER = "trusted.hosts.placeholder"; public static final String VERSION = "version"; public static final String UNDEFINED = "undefined"; + public static final String TAGFIELD_PLACEHOLDER = "tagfield.placeholder"; //REPORT public static final String REPORT_POSITION = "report.position"; @@ -69,6 +75,7 @@ public class Strings public static final String REPORT_CATEGORY = "report.category"; public static final String REPORT_NAME = "report.name"; public static final String REPORT_DESCRIPTION = "report.description"; + public static final String REPORT_TAGS = "report.tags"; public static final String REPORT_RATING = "report.rating"; public static final String REPORT_AMOUNT = "report.amount"; public static final String REPORT_HEADLINE = "report.headline"; @@ -143,6 +150,7 @@ public class Strings public static final String INFO_TITLE_START_AFTER_UPDATE = "info.title.start.after.update"; public static final String INFO_HEADER_TEXT_START_AFTER_UPDATE = "info.header.text.start.after.update"; public static final String INFO_TEXT_START_AFTER_UPDATE = "info.text.start.after.update"; + public static final String INFO_TAGS = "info.tags"; //WARNING public static final String WARNING_ENDDATE_BEFORE_STARTDATE = "warning.enddate.before.startdate"; @@ -156,6 +164,7 @@ public class Strings public static final String WARNING_NAME_CHARACTER_LIMIT_REACHED_45 = "warning.name.character.limit.reached.45"; public static final String WARNING_NAME_CHARACTER_LIMIT_REACHED_150 = "warning.name.character.limit.reached.150"; public static final String WARNING_DESCRIPTION_CHARACTER_LIMIT_REACHED_150 = "warning.description.character.limit.reached.150"; + public static final String WARNING_TAG_CHARACTER_LIMIT_REACHED_45 = "warning.tag.character.limit.reached.45"; public static final String WARNING_PAYMENT_AMOUNT = "warning.payment.amount"; public static final String WARNING_EMPTY_PAYMENT_DATE = "warning.empty.payment.date"; public static final String WARNING_PAYMENT_REPEATING = "warning.payment.repeating"; @@ -167,6 +176,8 @@ public class Strings public static final String WARNING_EMPTY_PASSWORD = "warning.empty.password"; public static final String WARNING_WRONG_PASSWORD = "warning.wrong.password"; public static final String WARNING_SERVER_VERSION = "warning.server.version"; + public static final String WARNING_EMPTY_YEAR = "warning.empty.year"; + public static final String WARNING_WRONG_YEAR = "warning.wrong.year"; //ERROR public static final String ERROR_UNKNOWN_HOST = "error.unknown.host"; diff --git a/BudgetMasterServer/.classpath b/BudgetMasterServer/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..fae1a2b37d5e3386c9651caedb78b9bd107715bd --- /dev/null +++ b/BudgetMasterServer/.classpath @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/BudgetMasterServer/.project b/BudgetMasterServer/.project new file mode 100644 index 0000000000000000000000000000000000000000..3af6b4d3f9ec19391adbd671158bdb0a3019a56e --- /dev/null +++ b/BudgetMasterServer/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>BudgetMasterServer</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + </natures> +</projectDescription> diff --git a/BudgetMasterServer/.settings/org.eclipse.jdt.core.prefs b/BudgetMasterServer/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..714351aec195a9a572640e6844dcafd51565a2a5 --- /dev/null +++ b/BudgetMasterServer/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/BudgetMasterServer/.settings/org.eclipse.m2e.core.prefs b/BudgetMasterServer/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/BudgetMasterServer/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/BudgetMasterServer/pom.xml b/BudgetMasterServer/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..f0aff38da07c472479abd04afc342b0dc32962e4 --- /dev/null +++ b/BudgetMasterServer/pom.xml @@ -0,0 +1,90 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>de.deadlocker8</groupId> + <artifactId>BudgetMasterServer</artifactId> + <version>1.6.0</version> + <name>BudgetMasterServer</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.7.0</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <outputDirectory>../build/${project.version}</outputDirectory> + <finalName>BudgetMasterServer-v${project.version}</finalName> + <appendAssemblyId>false</appendAssemblyId> + <archive> + <manifest> + <mainClass>de.deadlocker8.budgetmasterserver.main.Main</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <id>make-assembly</id> <!-- this is used for inheritance merges --> + <phase>package</phase> <!-- bind to the packaging phase --> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>com.sparkjava</groupId> + <artifactId>spark-core</artifactId> + <version>2.5.4</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <version>1.7.21</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>6.0.5</version> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>2.9.7</version> + </dependency> + <dependency> + <groupId>de.deadlocker8</groupId> + <artifactId>tools</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>de.deadlocker8</groupId> + <artifactId>BudgetMasterCore</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/logic/Settings.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/Settings.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/logic/Settings.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/Settings.java diff --git a/src/de/deadlocker8/budgetmasterserver/logic/Utils.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/Utils.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/logic/Utils.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/Utils.java diff --git a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseCreator.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseCreator.java similarity index 77% rename from src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseCreator.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseCreator.java index 18d81340e14f17c0fbbee56c8b37a4b93813f347..81350a988fbacb3bf8bd2742fc3f5b77cb6889c9 100644 --- a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseCreator.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseCreator.java @@ -64,6 +64,16 @@ public class DatabaseCreator { createTableRepeatingEntry(); } + + if(!existingTables.contains("tag")) + { + createTableTag(); + } + + if(!existingTables.contains("tag_match")) + { + createTableTagMatch(); + } } private void createTableCategory() @@ -115,9 +125,9 @@ public class DatabaseCreator "`Amount` int(11) DEFAULT NULL COMMENT 'amount in cents'," + "`Date` date DEFAULT NULL COMMENT 'payment date'," + "`Description` varchar(150) DEFAULT NULL COMMENT 'optional description'" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; - String query2 = "ALTER TABLE `payment` ADD PRIMARY KEY (`ID`);"; - String query3 = "ALTER TABLE `payment` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID';"; + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; + String query2 = "ALTER TABLE `payment` ADD PRIMARY KEY (`ID`);"; + String query3 = "ALTER TABLE `payment` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID';"; try { @@ -229,4 +239,75 @@ public class DatabaseCreator } } } + + private void createTableTag() + { + Statement stmt = null; + String query = "CREATE TABLE `tag` (`ID` int(11) NOT NULL COMMENT 'ID'," + + " `Name` varchar(45) COLLATE utf8_unicode_ci NOT NULL COMMENT 'Name'" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; + String query2 = "ALTER TABLE `tag` ADD PRIMARY KEY (`ID`);"; + String query3 = "ALTER TABLE `tag` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID';"; + + try + { + stmt = connection.createStatement(); + stmt.execute(query); + stmt.execute(query2); + stmt.execute(query3); + Logger.info("Successfully created table tag"); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + if(stmt != null) + { + try + { + stmt.close(); + } + catch(SQLException e) + { + } + } + } + } + + private void createTableTagMatch() + { + Statement stmt = null; + String query = "CREATE TABLE `tag_match` (`Tag_ID` int(11) NOT NULL," + + "`Payment_ID` int(11) NOT NULL," + + "`RepeatingPayment_ID` int(11) NOT NULL" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"; + String query2 = "ALTER TABLE `tag_match` ADD KEY `Tag_ID` (`Tag_ID`), ADD KEY `Payment_ID` (`Payment_ID`), ADD KEY `RepeatingPayment_ID` (`RepeatingPayment_ID`);"; + + try + { + stmt = connection.createStatement(); + stmt.execute(query); + stmt.execute(query2); + Logger.info("Successfully created table tag_match"); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + if(stmt != null) + { + try + { + stmt.close(); + } + catch(SQLException e) + { + } + } + } + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseExporter.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseExporter.java similarity index 68% rename from src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseExporter.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseExporter.java index 4dbf4022e81e6d143155002d89293718c0fcaf67..2213d91003b903824193d41803d4afa0f96daf6e 100644 --- a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseExporter.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseExporter.java @@ -8,9 +8,12 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmaster.logic.tag.TagMatch; import de.deadlocker8.budgetmasterserver.logic.Settings; import logger.Logger; @@ -36,8 +39,10 @@ public class DatabaseExporter ArrayList<Category> categories = getAllCategories(); ArrayList<NormalPayment> normalPayments = getAllNormalPayments(); ArrayList<RepeatingPayment> repeatingPayments = getAllRepeatingPayments(); + ArrayList<Tag> tags = getAllTags(); + ArrayList<TagMatch> tagMatches = getAllTagMatches(); - return new Database(categories, normalPayments, repeatingPayments); + return new Database(categories, normalPayments, repeatingPayments, tags, tagMatches); } private void closeConnection(Statement statement) @@ -150,5 +155,64 @@ public class DatabaseExporter } return results; - } + } + + private ArrayList<Tag> getAllTags() + { + PreparedStatement stmt = null; + ArrayList<Tag> results = new ArrayList<>(); + try + { + stmt = connection.prepareStatement("SELECT * FROM tag;"); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int resultID = rs.getInt("ID"); + String name = rs.getString("Name"); + + results.add(new Tag(resultID, name)); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return results; + } + + private ArrayList<TagMatch> getAllTagMatches() + { + PreparedStatement stmt = null; + ArrayList<TagMatch> results = new ArrayList<>(); + try + { + stmt = connection.prepareStatement("SELECT * FROM tag_match;"); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int tagID = rs.getInt("Tag_ID"); + int paymentID = rs.getInt("Payment_ID"); + int repeatingPaymentID = rs.getInt("RepeatingPayment_ID"); + + results.add(new TagMatch(tagID, paymentID, repeatingPaymentID)); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return results; + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseHandler.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseHandler.java similarity index 87% rename from src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseHandler.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseHandler.java index c02d8a08c4e1210f5d476bd340fb05961d58d163..b9f91615a2ae2d9364fcb28da120e20a8047371a 100644 --- a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseHandler.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseHandler.java @@ -12,12 +12,12 @@ import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.Payment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.LatestRepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; import de.deadlocker8.budgetmasterserver.logic.Settings; import logger.Logger; @@ -365,6 +365,41 @@ public class DatabaseHandler return null; } + + public ArrayList<NormalPayment> getAllNormalPayments() + { + PreparedStatement stmt = null; + + ArrayList<NormalPayment> results = new ArrayList<>(); + try + { + stmt = connection.prepareStatement("SELECT * FROM payment;"); + + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int resultID = rs.getInt("ID"); + String name = rs.getString("Name"); + int amount = rs.getInt("amount"); + String date = rs.getString("Date"); + int categoryID = rs.getInt("CategoryID"); + String description = rs.getString("Description"); + + results.add(new NormalPayment(resultID, amount, date, categoryID, name, description)); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return results; + } public ArrayList<NormalPayment> getPayments(int year, int month) { @@ -621,6 +656,54 @@ public class DatabaseHandler return result; } + + public int getNormalPaymentMaxAmount() + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("SELECT MAX(ABS(Amount)) as'max' FROM payment;"); ; + ResultSet rs = stmt.executeQuery(); + while(rs.next()) + { + return rs.getInt("max"); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return -1; + } + + public int getRepeatingPaymentMaxAmount() + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("SELECT MAX(ABS(Amount)) as'max' FROM repeating_payment;"); ; + ResultSet rs = stmt.executeQuery(); + while(rs.next()) + { + return rs.getInt("max"); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return -1; + } /* * DELETE @@ -689,6 +772,8 @@ public class DatabaseHandler String tablePayment = "DROP TABLE IF EXISTS payment;"; String tableRepeatingPayment = "DROP TABLE IF EXISTS repeating_payment;"; String tableRepeatingEntry = "DROP TABLE IF EXISTS repeating_entry;"; + String tableTag = "DROP TABLE IF EXISTS tag;"; + String tableTagMatch = "DROP TABLE IF EXISTS tag_match;"; try { stmt = connection.createStatement(); @@ -701,6 +786,10 @@ public class DatabaseHandler Logger.info("Deleted table: repeating_payment"); stmt.execute(tableRepeatingEntry); Logger.info("Deleted table: repeating_entry"); + stmt.execute(tableTag); + Logger.info("Deleted table: tag"); + stmt.execute(tableTagMatch); + Logger.info("Deleted table: tag_match"); stmt.execute("SET FOREIGN_KEY_CHECKS = 1;"); } catch(SQLException e) @@ -757,18 +846,25 @@ public class DatabaseHandler } } - public void addNormalPayment(int amount, String date, int categoryID, String name, String description) + public Integer addNormalPayment(int amount, String date, int categoryID, String name, String description) { PreparedStatement stmt = null; try { - stmt = connection.prepareStatement("INSERT INTO payment (Amount, Date, CategoryID, Name, Description) VALUES(?, ?, ?, ?, ?);"); + stmt = connection.prepareStatement("INSERT INTO payment (Amount, Date, CategoryID, Name, Description) VALUES(?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS); stmt.setInt(1, amount); stmt.setString(2, date); stmt.setInt(3, categoryID); stmt.setString(4, name); stmt.setString(5, description); stmt.execute(); + + ResultSet rs = stmt.getGeneratedKeys(); + if(rs.next()) + { + return rs.getInt(1); + } } catch(SQLException e) { @@ -778,9 +874,11 @@ public class DatabaseHandler { closeConnection(stmt); } + + return -1; } - public void addRepeatingPayment(int amount, String date, int categoryID, String name, String description, int repeatInterval, String repeatEndDate, int repeatMonthDay) + public Integer addRepeatingPayment(int amount, String date, int categoryID, String name, String description, int repeatInterval, String repeatEndDate, int repeatMonthDay) { PreparedStatement stmt = null; String correctRepeatEndDate = repeatEndDate; @@ -791,7 +889,8 @@ public class DatabaseHandler try { - stmt = connection.prepareStatement("INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES(?, ?, ?, ?, ?, ?, ?, ?);"); + stmt = connection.prepareStatement("INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES(?, ?, ?, ?, ?, ?, ?, ?);", + Statement.RETURN_GENERATED_KEYS); stmt.setInt(1, amount); stmt.setString(2, date); stmt.setInt(3, categoryID); @@ -801,16 +900,23 @@ public class DatabaseHandler stmt.setInt(7, repeatMonthDay); stmt.setString(8, description); stmt.execute(); + + ResultSet rs = stmt.getGeneratedKeys(); + if(rs.next()) + { + return rs.getInt(1); + } } catch(SQLException e) - { - e.printStackTrace(); + { Logger.error(e); } finally { closeConnection(stmt); } + + return -1; } public void addRepeatingPaymentEntry(int repeatingPaymentID, String date) diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseImporter.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseImporter.java new file mode 100644 index 0000000000000000000000000000000000000000..3070bf67b655552cb6d552d0c3824ce12808b2c0 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseImporter.java @@ -0,0 +1,234 @@ +package de.deadlocker8.budgetmasterserver.logic.database; + +import java.util.ArrayList; +import java.util.Iterator; + +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmaster.logic.tag.TagMatch; + +public class DatabaseImporter +{ + private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; + private ArrayList<Category> categories; + private ArrayList<NormalPayment> normalPayments; + private ArrayList<RepeatingPayment> repeatingPayments; + private ArrayList<NormalPayment> changedNormalPayments; + private ArrayList<RepeatingPayment> changedRepeatingPayments; + private ArrayList<Tag> tags; + private ArrayList<TagMatch> tagMatches; + private ArrayList<TagMatch> changedTagMatches; + + public DatabaseImporter(DatabaseHandler handler, DatabaseTagHandler tagHandler) throws IllegalStateException + { + this.handler = handler; + this.tagHandler = tagHandler; + } + + public void importDatabase(Database database) + { + this.categories = database.getCategories(); + this.normalPayments = database.getNormalPayments(); + this.repeatingPayments = database.getRepeatingPayments(); + this.changedNormalPayments = new ArrayList<>(); + this.changedRepeatingPayments = new ArrayList<>(); + this.tags = database.getTags(); + this.tagMatches = database.getTagMatches(); + this.changedTagMatches = new ArrayList<>(); + + importAll(); + } + + private void importAll() + { + for(Category currentCategory : categories) + { + if(currentCategory.getID() == 1 || currentCategory.getID() == 2) + { + continue; + } + + Category existingCategory = handler.getCategory(currentCategory.getName(), currentCategory.getColor()); + if(existingCategory == null) + { + handler.addCategory(currentCategory.getName(), currentCategory.getColor()); + int newID = handler.getLastInsertID(); + + updatePayments(currentCategory.getID(), newID); + } + else + { + updatePayments(currentCategory.getID(), existingCategory.getID()); + } + } + + //merge changed and remaining payments + normalPayments.addAll(changedNormalPayments); + repeatingPayments.addAll(changedRepeatingPayments); + + importNormalPayments(normalPayments); + tagMatches.addAll(changedTagMatches); + changedTagMatches = new ArrayList<>(); + + importRepeatingPayments(repeatingPayments); + tagMatches.addAll(changedTagMatches); + changedTagMatches = new ArrayList<>(); + + // import tags + for(Tag currentTag : tags) + { + int tagID = currentTag.getID(); + + Tag existingTag = tagHandler.getTagByName(currentTag.getName()); + if(existingTag == null) + { + tagHandler.addTag(currentTag.getName()); + int newID = tagHandler.getLastInsertID(); + + updateTagMatchesByTagID(tagID, newID); + } + else + { + updateTagMatchesByTagID(tagID, existingTag.getID()); + } + } + + tagMatches.addAll(changedTagMatches); + importTagMatches(tagMatches); + } + + private void updatePayments(int oldID, int newID) + { + //check normal payments for old category ID + Iterator<NormalPayment> iterator = normalPayments.iterator(); + while(iterator.hasNext()) + { + NormalPayment currentPayment = iterator.next(); + if(currentPayment.getCategoryID() == oldID) + { + currentPayment.setCategoryID(newID); + /* + * remove payment from payments list to avoid overriding category ID again on future calls of this method + * e.g.: call 1 = replace ID 2 with 3 + * call 2 = replace ID 3 with 4 + * --> would replace category IDs in payments where category ID has already been replaced + * --> would lead to wrong import + * --> remove payment from list but add to "changedPayments" in order not to loose the payment completly + * --> remaining payments in list and all payments from "changedPayments" will be merged after all categories are imported + */ + changedNormalPayments.add(currentPayment); + iterator.remove(); + } + } + + //check repeating payments for old category ID + Iterator<RepeatingPayment> iterator2 = repeatingPayments.iterator(); + while(iterator2.hasNext()) + { + RepeatingPayment currentPayment = iterator2.next(); + if(currentPayment.getCategoryID() == oldID) + { + currentPayment.setCategoryID(newID); + /* + * see explanation in NormalPayments loop + */ + changedRepeatingPayments.add(currentPayment); + iterator2.remove(); + } + } + } + + private void importNormalPayments(ArrayList<NormalPayment> normalPayments) + { + for(NormalPayment currentPayment : normalPayments) + { + int newID = handler.addNormalPayment(currentPayment.getAmount(), currentPayment.getDate(), currentPayment.getCategoryID(), currentPayment.getName(), currentPayment.getDescription()); + updateTagMatchesByPaymentID(currentPayment.getID(), newID); + } + } + + private void importRepeatingPayments(ArrayList<RepeatingPayment> repeatingPayments) + { + for(RepeatingPayment currentPayment : repeatingPayments) + { + int newID = handler.addRepeatingPayment(currentPayment.getAmount(), currentPayment.getDate(), currentPayment.getCategoryID(), currentPayment.getName(), currentPayment.getDescription(), currentPayment.getRepeatInterval(), currentPayment.getRepeatEndDate(), currentPayment.getRepeatMonthDay()); + updateTagMatchesByRepeatingPaymentID(currentPayment.getID(), newID); + } + } + + private void updateTagMatchesByTagID(int oldID, int newID) + { + //check tag matches for old tag ID + Iterator<TagMatch> iterator = tagMatches.iterator(); + while(iterator.hasNext()) + { + TagMatch currentTagMatch = iterator.next(); + if(currentTagMatch.getTagID() == oldID) + { + currentTagMatch.setTagID(newID); + /* + * see explanation in updatePayments() + */ + changedTagMatches.add(currentTagMatch); + iterator.remove(); + } + } + } + + private void updateTagMatchesByPaymentID(int oldID, int newID) + { + //check tag matches for old payment ID + Iterator<TagMatch> iterator = tagMatches.iterator(); + while(iterator.hasNext()) + { + TagMatch currentTagMatch = iterator.next(); + if(currentTagMatch.getPaymentID() == oldID) + { + currentTagMatch.setPaymentID(newID); + /* + * see explanation in updatePayments() + */ + changedTagMatches.add(currentTagMatch); + iterator.remove(); + } + } + } + + private void updateTagMatchesByRepeatingPaymentID(int oldID, int newID) + { + //check tag matches for old payment ID + Iterator<TagMatch> iterator = tagMatches.iterator(); + while(iterator.hasNext()) + { + TagMatch currentTagMatch = iterator.next(); + if(currentTagMatch.getRepeatingPaymentID() == oldID) + { + currentTagMatch.setRepeatingPaymentID(newID); + /* + * see explanation in updatePayments() + */ + changedTagMatches.add(currentTagMatch); + iterator.remove(); + } + } + } + + private void importTagMatches(ArrayList<TagMatch> tagMatches) + { + for(TagMatch currentTagMatch : tagMatches) + { + if(currentTagMatch.getRepeatingPaymentID() == -1) + { + tagHandler.addTagMatchForPayment(currentTagMatch.getTagID(), currentTagMatch.getPaymentID()); + } + else + { + tagHandler.addTagMatchForRepeatingPayment(currentTagMatch.getTagID(), currentTagMatch.getRepeatingPaymentID()); + } + } + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseTagHandler.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseTagHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..562e2b20fe13dd7e71fc4f734e65d498e587b0a9 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/logic/database/DatabaseTagHandler.java @@ -0,0 +1,415 @@ +package de.deadlocker8.budgetmasterserver.logic.database; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.Settings; +import logger.Logger; + +public class DatabaseTagHandler +{ + private Connection connection; + + public DatabaseTagHandler(Settings settings) throws IllegalStateException + { + try + { + this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin", settings.getDatabaseUsername(), settings.getDatabasePassword()); + } + catch(Exception e) + { + Logger.error(e); + throw new IllegalStateException("Cannot connect the database!", e); + } + } + + private void closeConnection(Statement statement) + { + if(statement != null) + { + try + { + statement.close(); + } + catch(SQLException e) + { + } + } + } + + public int getLastInsertID() + { + PreparedStatement stmt = null; + int lastInsertID = 0; + try + { + stmt = connection.prepareStatement("SELECT LAST_INSERT_ID();"); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + lastInsertID = rs.getInt("LAST_INSERT_ID()"); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return lastInsertID; + } + + public ArrayList<Tag> getAllTags() + { + PreparedStatement stmt = null; + ArrayList<Tag> results = new ArrayList<>(); + try + { + stmt = connection.prepareStatement("SELECT * FROM tag ORDER BY tag.Name"); + ResultSet rs = stmt.executeQuery(); + while(rs.next()) + { + int id = rs.getInt("ID"); + String name = rs.getString("Name"); + + results.add(new Tag(id, name)); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return results; + } + + public Tag getTagByID(int ID) + { + PreparedStatement stmt = null; + Tag tag = null; + try + { + stmt = connection.prepareStatement("SELECT * FROM tag WHERE tag.ID= ?;"); + stmt.setInt(1, ID); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int id = rs.getInt("ID"); + String name = rs.getString("Name"); + + tag = new Tag(id, name); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return tag; + } + + public Tag getTagByName(String name) + { + PreparedStatement stmt = null; + Tag tag = null; + try + { + stmt = connection.prepareStatement("SELECT * FROM tag WHERE tag.Name= ?;"); + stmt.setString(1, name); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int id = rs.getInt("ID"); + String newName = rs.getString("Name"); + + tag = new Tag(id, newName); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return tag; + } + + public void addTag(String name) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("INSERT INTO tag (Name) VALUES(?);"); + stmt.setString(1, name); + stmt.execute(); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + } + + public void deleteTag(int ID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("DELETE FROM tag WHERE tag.ID = ?;"); + stmt.setInt(1, ID); + stmt.execute(); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + } + + public boolean isMatchExistingForPaymentID(int tagID, int paymentID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("SELECT * FROM tag_match WHERE tag_match.Tag_ID = ? AND tag_match.Payment_ID = ?;"); + stmt.setInt(1, tagID); + stmt.setInt(2, paymentID); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + return true; + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return false; + } + + public boolean isMatchExistingForRepeatingPaymentID(int tagID, int repeatingPaymentID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("SELECT * FROM tag_match WHERE tag_match.Tag_ID = ? AND tag_match.RepeatingPayment_ID = ?;"); + stmt.setInt(1, tagID); + stmt.setInt(2, repeatingPaymentID); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + return true; + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return false; + } + + public ArrayList<Integer> getAllTagsForPayment(int paymentID) + { + PreparedStatement stmt = null; + ArrayList<Integer> tagIDs = new ArrayList<>(); + try + { + stmt = connection.prepareStatement("SELECT * FROM tag_match WHERE tag_match.Payment_ID = ?;"); + stmt.setInt(1, paymentID); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int tagID = rs.getInt("Tag_ID"); + tagIDs.add(tagID); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return tagIDs; + } + + public ArrayList<Integer> getAllTagsForRepeatingPayment(int repeatingPaymentID) + { + PreparedStatement stmt = null; + ArrayList<Integer> tagIDs = new ArrayList<>(); + try + { + stmt = connection.prepareStatement("SELECT * FROM tag_match WHERE tag_match.RepeatingPayment_ID = ?;"); + stmt.setInt(1, repeatingPaymentID); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + int tagID = rs.getInt("Tag_ID"); + tagIDs.add(tagID); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return tagIDs; + } + + public void addTagMatchForPayment(int tagID, int paymentID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("INSERT INTO tag_match (Tag_ID, Payment_ID, RepeatingPayment_ID) VALUES(?, ?, ?);"); + stmt.setInt(1, tagID); + stmt.setInt(2, paymentID); + stmt.setInt(3, -1); + stmt.execute(); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + } + + public void addTagMatchForRepeatingPayment(int tagID, int repeatingPaymentID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("INSERT INTO tag_match (Tag_ID, Payment_ID, RepeatingPayment_ID) VALUES(?, ?, ?);"); + stmt.setInt(1, tagID); + stmt.setInt(2, -1); + stmt.setInt(3, repeatingPaymentID); + stmt.execute(); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + } + + public void deleteTagMatchForPayment(int tagID, int paymentID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("DELETE FROM tag_match WHERE tag_match.Tag_ID = ? AND tag_match.Payment_ID = ?;"); + stmt.setInt(1, tagID); + stmt.setInt(2, paymentID); + stmt.execute(); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + } + + public void deleteTagMatchForRepeatingPayment(int tagID, int repeatingPaymentID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("DELETE FROM tag_match WHERE tag_match.Tag_ID = ? AND tag_match.repeatingPayment_ID = ?;"); + stmt.setInt(1, tagID); + stmt.setInt(2, repeatingPaymentID); + stmt.execute(); + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + } + + public boolean isTagUsedInMatches(int tagID) + { + PreparedStatement stmt = null; + try + { + stmt = connection.prepareStatement("SELECT * FROM tag_match WHERE tag_match.Tag_ID = ?;"); + stmt.setInt(1, tagID); + ResultSet rs = stmt.executeQuery(); + + while(rs.next()) + { + return true; + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + closeConnection(stmt); + } + + return false; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/main/Main.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/main/Main.java similarity index 71% rename from src/de/deadlocker8/budgetmasterserver/main/Main.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/main/Main.java index 435a3378ed8f85f2416e00c6738cd4fb952c701e..eb3a19f902e893737a2313c3b84d29a3d87e0731 100644 --- a/src/de/deadlocker8/budgetmasterserver/main/Main.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/main/Main.java @@ -7,7 +7,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Locale; -import java.util.ResourceBundle; import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; import de.deadlocker8.budgetmasterserver.logic.Settings; @@ -20,17 +19,17 @@ import tools.Localization; public class Main { - //for server specific version information - private static ResourceBundle bundle = ResourceBundle.getBundle("de/deadlocker8/budgetmasterserver/main/", Locale.GERMAN); - public static void main(String[] args) { //for category.none in class Category - Localization.init("de/deadlocker8/budgetmaster/resources/languages/"); + Localization.init("de/deadlocker8/budgetmasterserver/"); Localization.loadLanguage(Locale.ENGLISH); Logger.setLevel(LogLevel.ALL); - Logger.appInfo(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date")); + Logger.appInfo(Localization.getString("app.name"), + Localization.getString("version.name"), + Localization.getString("version.code"), + Localization.getString("version.date")); try { File logFolder = Paths.get(SparkServer.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().toFile(); @@ -49,7 +48,7 @@ public class Main { try { - Files.copy(SparkServer.class.getClassLoader().getResourceAsStream("de/deadlocker8/budgetmasterserver/resources/settings.json"), settingsPath); + Files.copy(SparkServer.class.getClassLoader().getResourceAsStream("de/deadlocker8/budgetmasterserver/settings.json"), settingsPath); } catch(IOException e) { @@ -62,9 +61,9 @@ public class Main { settings = Utils.loadSettings(); VersionInformation versionInfo = new VersionInformation(); - versionInfo.setVersionCode(Integer.parseInt(bundle.getString("version.code"))); - versionInfo.setVersionName(bundle.getString("version.name")); - versionInfo.setDate(bundle.getString("version.date")); + versionInfo.setVersionCode(Integer.parseInt(Localization.getString("version.code"))); + versionInfo.setVersionName(Localization.getString("version.name")); + versionInfo.setDate(Localization.getString("version.date")); new SparkServer(settings, versionInfo); } diff --git a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java similarity index 64% rename from src/de/deadlocker8/budgetmasterserver/server/SparkServer.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java index 72771a73be50526a7fa3398eb0352a3e9aeb72b3..72558d5dab04ffb6195f48f450b3c5af3602fe3d 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java @@ -21,6 +21,7 @@ import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; import de.deadlocker8.budgetmaster.logic.utils.Helpers; import de.deadlocker8.budgetmasterserver.logic.Settings; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; import de.deadlocker8.budgetmasterserver.server.category.CategoryAdd; import de.deadlocker8.budgetmasterserver.server.category.CategoryDelete; import de.deadlocker8.budgetmasterserver.server.category.CategoryGet; @@ -40,7 +41,22 @@ import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPayme import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentDelete; import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentGet; import de.deadlocker8.budgetmasterserver.server.payment.repeating.RepeatingPaymentGetAll; +import de.deadlocker8.budgetmasterserver.server.payment.search.PaymentMaxAmount; +import de.deadlocker8.budgetmasterserver.server.payment.search.PaymentSearch; import de.deadlocker8.budgetmasterserver.server.rest.RestGet; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchAddForPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchAddForRepeatingPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchDeleteForPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchDeleteForRepeatingPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchExistingForPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchExistingForRepeatingPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchGetAllForPayment; +import de.deadlocker8.budgetmasterserver.server.tag.match.TagMatchGetAllForRepeatingPayment; +import de.deadlocker8.budgetmasterserver.server.tag.tag.TagAdd; +import de.deadlocker8.budgetmasterserver.server.tag.tag.TagDelete; +import de.deadlocker8.budgetmasterserver.server.tag.tag.TagGet; +import de.deadlocker8.budgetmasterserver.server.tag.tag.TagGetAll; +import de.deadlocker8.budgetmasterserver.server.tag.tag.TagGetByName; import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater; import de.deadlocker8.budgetmasterserver.server.version.VersionGet; import logger.Logger; @@ -52,6 +68,7 @@ public class SparkServer { private Gson gson; private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; public SparkServer(Settings settings, VersionInformation versionInfo) { @@ -81,6 +98,7 @@ public class SparkServer RouteOverview.enableRouteOverview(); handler = new DatabaseHandler(settings); + tagHandler = new DatabaseTagHandler(settings); before((request, response) -> { @@ -102,17 +120,19 @@ public class SparkServer delete("/category", new CategoryDelete(handler)); // Payment + get("/payment/search", new PaymentSearch(handler, tagHandler)); + get("/payment/search/maxAmount", new PaymentMaxAmount(handler, gson)); // Normal get("/payment", new PaymentGet(handler, gson)); - post("/payment", new PaymentAdd(handler)); + post("/payment", new PaymentAdd(handler, gson)); put("/payment", new PaymentUpdate(handler)); - delete("/payment", new PaymentDelete(handler)); + delete("/payment", new PaymentDelete(handler, tagHandler)); // Repeating get("/repeatingpayment/single", new RepeatingPaymentGet(handler, gson)); get("/repeatingpayment", new RepeatingPaymentGetAll(handler, gson)); - post("/repeatingpayment", new RepeatingPaymentAdd(handler)); - delete("/repeatingpayment", new RepeatingPaymentDelete(handler)); + post("/repeatingpayment", new RepeatingPaymentAdd(handler, gson)); + delete("/repeatingpayment", new RepeatingPaymentDelete(handler, tagHandler)); // CategoryBudget get("/categorybudget", new CategoryBudgetGet(handler, gson)); @@ -120,13 +140,30 @@ public class SparkServer // Rest get("/rest", new RestGet(handler, gson)); - //charts + // charts get("/charts/categoryInOutSum", new CategoryInOutSumForMonth(handler, gson)); get("/charts/monthInOutSum", new MonthInOutSum(handler, gson)); + + // tag + get("/tag/single", new TagGet(tagHandler, gson)); + get("/tag/single/byName", new TagGetByName(tagHandler, gson)); + get("/tag", new TagGetAll(tagHandler, gson)); + post("/tag", new TagAdd(tagHandler)); + delete("/tag", new TagDelete(tagHandler)); + + // tag match + get("/tag/match/all/normal", new TagMatchGetAllForPayment(tagHandler, gson)); + get("/tag/match/all/repeating", new TagMatchGetAllForRepeatingPayment(tagHandler, gson)); + get("/tag/match/normal", new TagMatchExistingForPayment(tagHandler, gson)); + get("/tag/match/repeating", new TagMatchExistingForRepeatingPayment(tagHandler, gson)); + post("/tag/match/normal", new TagMatchAddForPayment(tagHandler)); + post("/tag/match/repeating", new TagMatchAddForRepeatingPayment(tagHandler)); + delete("/tag/match/normal", new TagMatchDeleteForPayment(tagHandler)); + delete("/tag/match/repeating", new TagMatchDeleteForRepeatingPayment(tagHandler)); // Database get("/database", new DatabaseExport(settings, gson)); - post("/database", new DatabaseImport(handler, gson)); + post("/database", new DatabaseImport(handler, tagHandler, gson)); delete("/database", new DatabaseDelete(handler, settings)); get("/version", new VersionGet(gson, versionInfo)); diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java similarity index 94% rename from src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java index 29cbb37e1adbeeabc77f254331685d197df155ae..bda73e67ae850a08732b72b94c8a556ae53c5bd1 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java @@ -4,7 +4,7 @@ import static spark.Spark.halt; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java similarity index 73% rename from src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java index 6b25afee1303049f749d84fbb6d36c63ef0cc247..2cb97062a8b66480191e522c4e118f9d106f2494 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java @@ -3,10 +3,11 @@ package de.deadlocker8.budgetmasterserver.server.category; import static spark.Spark.halt; import java.util.ArrayList; +import java.util.Collections; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.category.Category; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; @@ -28,7 +29,8 @@ public class CategoryGetAll implements Route { try { - ArrayList<Category> categories = handler.getCategories(); + ArrayList<Category> categories = handler.getCategories(); + Collections.sort(categories, (c1, c2) -> c1.getName().toLowerCase().compareTo(c2.getName().toLowerCase())); return gson.toJson(categories); } diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java diff --git a/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java similarity index 93% rename from src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java index 60b3f37a0a7d18181273fe201bf0c48249452efe..7ae44cb599ef970c44e2a2c5aeb9f33c5cc8d9ba 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java @@ -9,9 +9,9 @@ import java.util.Iterator; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.CategoryBudget; -import de.deadlocker8.budgetmaster.logic.Payment; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.category.CategoryBudget; +import de.deadlocker8.budgetmaster.logic.payment.Payment; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; diff --git a/src/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java similarity index 91% rename from src/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java index 52543c4c60bf41609e0c443b83e0aa7c721f587f..a83a7a50964ad81606f4591aa2b90512a40a9b1e 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java @@ -6,9 +6,9 @@ import java.util.ArrayList; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.CategoryInOutSum; -import de.deadlocker8.budgetmaster.logic.Payment; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.charts.CategoryInOutSum; +import de.deadlocker8.budgetmaster.logic.payment.Payment; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; diff --git a/src/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java similarity index 84% rename from src/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java index 4ae6da848f0fa97507136bdcabb3587edba2c0e1..8a4f43f1883fde9e47fd9c922b393e645f0273ab 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java @@ -8,9 +8,9 @@ import org.joda.time.DateTime; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.CategoryInOutSum; -import de.deadlocker8.budgetmaster.logic.Payment; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.charts.CategoryInOutSum; +import de.deadlocker8.budgetmaster.logic.payment.Payment; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; @@ -40,7 +40,7 @@ public class MonthInOutSum implements Route DateTime startDate = DateTime.parse(req.queryMap("startDate").value()).withDayOfMonth(1); DateTime endDate = DateTime.parse(req.queryMap("endDate").value()).withDayOfMonth(1); - ArrayList<de.deadlocker8.budgetmaster.logic.MonthInOutSum> monthInOutSums = new ArrayList<>(); + ArrayList<de.deadlocker8.budgetmaster.logic.charts.MonthInOutSum> monthInOutSums = new ArrayList<>(); while(startDate.isBefore(endDate) || startDate.isEqual(endDate)) { @@ -71,7 +71,7 @@ public class MonthInOutSum implements Route } } - monthInOutSums.add(new de.deadlocker8.budgetmaster.logic.MonthInOutSum(startDate.getMonthOfYear(), startDate.getYear(), sums)); + monthInOutSums.add(new de.deadlocker8.budgetmaster.logic.charts.MonthInOutSum(startDate.getMonthOfYear(), startDate.getYear(), sums)); startDate = startDate.plusMonths(1); } diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java similarity index 75% rename from src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java index 86dce0c839fd30528cf4cb467c4f5907287a4668..fa3e9b13a2f7012aed495d03f5919ac58efb2e72 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java @@ -4,9 +4,10 @@ import static spark.Spark.halt; import com.google.gson.Gson; -import de.deadlocker8.budgetmasterserver.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.database.Database; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseImporter; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; import logger.Logger; import spark.Request; import spark.Response; @@ -15,11 +16,13 @@ import spark.Route; public class DatabaseImport implements Route { private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; private Gson gson; - public DatabaseImport(DatabaseHandler handler, Gson gson) + public DatabaseImport(DatabaseHandler handler, DatabaseTagHandler tagHandler, Gson gson) { this.handler = handler; + this.tagHandler = tagHandler; this.gson = gson; } @@ -32,7 +35,7 @@ public class DatabaseImport implements Route { Database database = gson.fromJson(databaseJSON, Database.class); - DatabaseImporter importer = new DatabaseImporter(handler); + DatabaseImporter importer = new DatabaseImporter(handler, tagHandler); importer.importDatabase(database); return ""; } diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java similarity index 74% rename from src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java index 53580d8b925d12db336c1a649dff3c51d6975748..86a78819e0481f958bd4eaaef065f52b53519d11 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java @@ -2,6 +2,8 @@ package de.deadlocker8.budgetmasterserver.server.payment.normal; import static spark.Spark.halt; +import com.google.gson.Gson; + import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; @@ -10,10 +12,12 @@ import spark.Route; public class PaymentAdd implements Route { private DatabaseHandler handler; + private Gson gson; - public PaymentAdd(DatabaseHandler handler) + public PaymentAdd(DatabaseHandler handler, Gson gson) { this.handler = handler; + this.gson = gson; } @Override @@ -38,13 +42,13 @@ public class PaymentAdd implements Route try { - handler.addNormalPayment(amount, - req.queryMap("date").value(), - categoryID, - req.queryMap("name").value(), - req.queryMap("description").value()); + Integer id = handler.addNormalPayment(amount, + req.queryMap("date").value(), + categoryID, + req.queryMap("name").value(), + req.queryMap("description").value()); - return ""; + return gson.toJson(id); } catch(IllegalStateException ex) { @@ -52,8 +56,7 @@ public class PaymentAdd implements Route } } catch(Exception e) - { - e.printStackTrace(); + { halt(400, "Bad Request"); } diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java new file mode 100644 index 0000000000000000000000000000000000000000..f0a059d1cb7fb0f628006ca844a2bdbb679ebde2 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java @@ -0,0 +1,66 @@ +package de.deadlocker8.budgetmasterserver.server.payment.normal; + +import static spark.Spark.halt; + +import java.util.ArrayList; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class PaymentDelete implements Route +{ + private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; + + public PaymentDelete(DatabaseHandler handler, DatabaseTagHandler tagHandler) + { + this.handler = handler; + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("id")) + { + halt(400, "Bad Request"); + } + + int id = -1; + + try + { + id = Integer.parseInt(req.queryMap("id").value()); + + if(id < 0) + { + halt(400, "Bad Request"); + } + + try + { + handler.deletePayment(id); + ArrayList<Integer> tagIDs = tagHandler.getAllTagsForPayment(id); + for(Integer currentTagID : tagIDs) + { + tagHandler.deleteTagMatchForPayment(currentTagID, id); + } + + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return ""; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java similarity index 96% rename from src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java index 19a9106e56e26b941925f7cc3ab0229d2a684e4c..da8e0818163a5d99f5174c41543b740f4c2c66cb 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java @@ -8,7 +8,7 @@ import org.joda.time.DateTime; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater; import spark.Request; diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java similarity index 74% rename from src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java index 0c711c30f0f6e1c5ea8baf7c7ff721c61c2a0221..72111cbffa878a2a8a1be9f6db7a03d4c8132cb8 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java @@ -2,6 +2,8 @@ package de.deadlocker8.budgetmasterserver.server.payment.repeating; import static spark.Spark.halt; +import com.google.gson.Gson; + import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; @@ -10,10 +12,12 @@ import spark.Route; public class RepeatingPaymentAdd implements Route { private DatabaseHandler handler; + private Gson gson; - public RepeatingPaymentAdd(DatabaseHandler handler) + public RepeatingPaymentAdd(DatabaseHandler handler, Gson gson) { this.handler = handler; + this.gson = gson; } @Override @@ -45,16 +49,16 @@ public class RepeatingPaymentAdd implements Route try { - handler.addRepeatingPayment(amount, - req.queryMap("date").value(), - categoryID, - req.queryMap("name").value(), - req.queryMap("description").value(), - repeatInterval, - req.queryMap("repeatEndDate").value(), - repeatMonthDay); + Integer id = handler.addRepeatingPayment(amount, + req.queryMap("date").value(), + categoryID, + req.queryMap("name").value(), + req.queryMap("description").value(), + repeatInterval, + req.queryMap("repeatEndDate").value(), + repeatMonthDay); - return ""; + return gson.toJson(id); } catch(IllegalStateException ex) { diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java similarity index 63% rename from src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java index 89d2c121929fd5198eb0fd67e93fb1c54240d101..0df80498598d4b81e4736201d11a44ba34f5481d 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java @@ -2,7 +2,10 @@ package de.deadlocker8.budgetmasterserver.server.payment.repeating; import static spark.Spark.halt; +import java.util.ArrayList; + import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; import spark.Request; import spark.Response; import spark.Route; @@ -10,10 +13,12 @@ import spark.Route; public class RepeatingPaymentDelete implements Route { private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; - public RepeatingPaymentDelete(DatabaseHandler handler) + public RepeatingPaymentDelete(DatabaseHandler handler, DatabaseTagHandler tagHandler) { this.handler = handler; + this.tagHandler = tagHandler; } @Override @@ -37,7 +42,12 @@ public class RepeatingPaymentDelete implements Route try { - handler.deleteRepeatingPayment(id); + handler.deleteRepeatingPayment(id); + ArrayList<Integer> tagIDs = tagHandler.getAllTagsForRepeatingPayment(id); + for(Integer currentTagID : tagIDs) + { + tagHandler.deleteTagMatchForRepeatingPayment(currentTagID, id); + } return ""; } diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java similarity index 94% rename from src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java index 59724e2027676d4eeb1f971f5c44de56948c3bb2..5349848f24246bb03affc36ad554638fab1efbe3 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java @@ -4,7 +4,7 @@ import static spark.Spark.halt; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import spark.Request; import spark.Response; diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java similarity index 96% rename from src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java index 0b49df55505325f3e7ffb2009685d5f2286ac455..ce617830abc32782ed64ca81ce56af1e03472576 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java @@ -8,7 +8,7 @@ import org.joda.time.DateTime; import com.google.gson.Gson; -import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPaymentEntry; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater; import spark.Request; diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/search/PaymentMaxAmount.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/search/PaymentMaxAmount.java new file mode 100644 index 0000000000000000000000000000000000000000..a8f40253bb8fb229128ca313bc0ecb10e29156f2 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/search/PaymentMaxAmount.java @@ -0,0 +1,46 @@ +package de.deadlocker8.budgetmasterserver.server.payment.search; + +import static spark.Spark.halt; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class PaymentMaxAmount implements Route +{ + private DatabaseHandler handler; + private Gson gson; + + public PaymentMaxAmount(DatabaseHandler handler, Gson gson) + { + this.handler = handler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + try + { + int maxNormal = handler.getNormalPaymentMaxAmount(); + int maxRepeating = handler.getRepeatingPaymentMaxAmount(); + + int max = maxNormal; + if(maxRepeating > max) + { + max = maxRepeating; + } + //plus 1 to allow all amounts up to maxNormal.99 € + return gson.toJson((max+1)/100); + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/search/PaymentSearch.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/search/PaymentSearch.java new file mode 100644 index 0000000000000000000000000000000000000000..9c7f3b639ded27953e5531f5d04c5823f125f87a --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/payment/search/PaymentSearch.java @@ -0,0 +1,189 @@ +package de.deadlocker8.budgetmasterserver.server.payment.search; + +import static spark.Spark.halt; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.Payment; +import de.deadlocker8.budgetmaster.logic.payment.PaymentJSONSerializer; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class PaymentSearch implements Route +{ + private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; + + public PaymentSearch(DatabaseHandler handler, DatabaseTagHandler tagHandler) + { + this.handler = handler; + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + try + { + ArrayList<Payment> payments = new ArrayList<>(); + ArrayList<NormalPayment> normalPayments = handler.getAllNormalPayments(); + ArrayList<RepeatingPayment> repeatingPayments = handler.getAllRepeatingPayments(); + for(Payment currentPayment : normalPayments) + { + if(meetsCriteria(req, currentPayment)) + { + payments.add(currentPayment); + } + } + + for(Payment currentPayment : repeatingPayments) + { + if(meetsCriteria(req, currentPayment)) + { + payments.add(currentPayment); + } + } + + Collections.sort(payments, new Comparator<Payment>() + { + @Override + public int compare(Payment o1, Payment o2) + { + return o1.getDate().compareTo(o2.getDate()); + } + }); + + return PaymentJSONSerializer.serializePaymentList(payments); + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + + return null; + } + + private boolean meetsCriteria(Request req, Payment payment) + { + boolean otherChecksThanAmount = false; + + if(req.queryMap("query").value().toLowerCase().equals("")) + return checkAmount(req, payment); + + if(!req.queryParams().contains("name") + && !req.queryParams().contains("description") + && !req.queryParams().contains("categoryName") + && !req.queryParams().contains("tags") + && !req.queryParams().contains("minAmount") + && !req.queryParams().contains("maxAmount")) + return false; + + if(req.queryParams().contains("name")) + { + otherChecksThanAmount = true; + if(payment.getName().toLowerCase().contains(req.queryMap("query").value().toLowerCase())) + { + return checkAmount(req, payment); + } + } + + if(req.queryParams().contains("description")) + { + otherChecksThanAmount = true; + if(payment.getDescription().toLowerCase().contains(req.queryMap("query").value().toLowerCase())) + { + return checkAmount(req, payment); + } + } + + if(req.queryParams().contains("categoryName")) + { + otherChecksThanAmount = true; + int id = payment.getCategoryID(); + //TODO + if(id == -1) + return false; + + Category category = handler.getCategory(payment.getCategoryID()); + if(category.getName().toLowerCase().contains(req.queryMap("query").value().toLowerCase())) + { + return checkAmount(req, payment); + } + } + + if(req.queryParams().contains("tags")) + { + otherChecksThanAmount = true; + ArrayList<Integer> tagIDs = new ArrayList<>(); + if(payment instanceof NormalPayment) + { + tagIDs = tagHandler.getAllTagsForPayment(payment.getID()); + } + else + { + tagIDs = tagHandler.getAllTagsForRepeatingPayment(payment.getID()); + } + + if(tagIDs.size() > 0) + { + for(Integer currentTagID : tagIDs) + { + Tag currentTag = tagHandler.getTagByID(currentTagID); + if(currentTag != null) + { + if(currentTag.getName().toLowerCase().contains(req.queryMap("query").value().toLowerCase())) + { + return checkAmount(req, payment); + } + } + } + } + } + + if(otherChecksThanAmount) + { + return false; + } + else + { + return checkAmount(req, payment); + } + } + + private boolean checkAmount(Request req, Payment payment) + { + if(req.queryParams().contains("minAmount") && req.queryParams().contains("maxAmount")) + { + try + { + int minAmount = Integer.parseInt(req.queryMap("minAmount").value()); + int maxAmount = Integer.parseInt(req.queryMap("maxAmount").value()); + int amount = Math.abs(payment.getAmount()); + + if(amount >= minAmount && amount <= maxAmount) + { + return true; + } + else + { + return false; + } + } + catch(NumberFormatException e) + { + halt(400, "Bad Request"); + } + } + + return true; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchAddForPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchAddForPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..64b71a28e54300a9fd748761310f92bbbf5cdff4 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchAddForPayment.java @@ -0,0 +1,52 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchAddForPayment implements Route +{ + private DatabaseTagHandler tagHandler; + + public TagMatchAddForPayment(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("tagID") || !req.queryParams().contains("paymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int tagID = Integer.parseInt(req.queryMap("tagID").value()); + int paymentID = Integer.parseInt(req.queryMap("paymentID").value()); + + if(tagID < 0 || paymentID < 0) + { + halt(400, "Bad Request"); + } + + tagHandler.addTagMatchForPayment(tagID, paymentID); + + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return ""; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchAddForRepeatingPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchAddForRepeatingPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..3eb1871ca76dde351b40491be4e862d1d6545eea --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchAddForRepeatingPayment.java @@ -0,0 +1,52 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchAddForRepeatingPayment implements Route +{ + private DatabaseTagHandler tagHandler; + + public TagMatchAddForRepeatingPayment(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("tagID") || !req.queryParams().contains("repeatingPaymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int tagID = Integer.parseInt(req.queryMap("tagID").value()); + int repeatingPaymentID = Integer.parseInt(req.queryMap("repeatingPaymentID").value()); + + if(tagID < 0 || repeatingPaymentID < 0) + { + halt(400, "Bad Request"); + } + + tagHandler.addTagMatchForRepeatingPayment(tagID, repeatingPaymentID); + + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return ""; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchDeleteForPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchDeleteForPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..9f676c0e8252312921ce688c2fb8ee95f2625dbb --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchDeleteForPayment.java @@ -0,0 +1,56 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import de.deadlocker8.budgetmasterserver.server.updater.TagUpdater; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchDeleteForPayment implements Route +{ + private DatabaseTagHandler tagHandler; + + public TagMatchDeleteForPayment(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("tagID") || !req.queryParams().contains("paymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int tagID = Integer.parseInt(req.queryMap("tagID").value()); + int paymentID = Integer.parseInt(req.queryMap("paymentID").value()); + + if(tagID < 0 || paymentID < 0) + { + halt(400, "Bad Request"); + } + + tagHandler.deleteTagMatchForPayment(tagID, paymentID); + + TagUpdater tagUpdater = new TagUpdater(tagHandler); + tagUpdater.deleteTagsIfNotReferenced(); + + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return ""; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchDeleteForRepeatingPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchDeleteForRepeatingPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..ab0e5a1c6fbac0c1eb5e2265513f2ee62fd93baf --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchDeleteForRepeatingPayment.java @@ -0,0 +1,56 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import de.deadlocker8.budgetmasterserver.server.updater.TagUpdater; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchDeleteForRepeatingPayment implements Route +{ + private DatabaseTagHandler tagHandler; + + public TagMatchDeleteForRepeatingPayment(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("tagID") || !req.queryParams().contains("repeatingPaymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int tagID = Integer.parseInt(req.queryMap("tagID").value()); + int repeatingPaymentID = Integer.parseInt(req.queryMap("repeatingPaymentID").value()); + + if(tagID < 0 || repeatingPaymentID < 0) + { + halt(400, "Bad Request"); + } + + tagHandler.deleteTagMatchForRepeatingPayment(tagID, repeatingPaymentID); + + TagUpdater tagUpdater = new TagUpdater(tagHandler); + tagUpdater.deleteTagsIfNotReferenced(); + + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return ""; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchExistingForPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchExistingForPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..9d1bb98528bd1324a2b01e8b2ed4f9eadf690432 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchExistingForPayment.java @@ -0,0 +1,54 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchExistingForPayment implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagMatchExistingForPayment(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("tagID") || !req.queryParams().contains("paymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int tagID = Integer.parseInt(req.queryMap("tagID").value()); + int paymentID = Integer.parseInt(req.queryMap("paymentID").value()); + + if(tagID < 0 || paymentID < 0) + { + halt(400, "Bad Request"); + } + + return gson.toJson(tagHandler.isMatchExistingForPaymentID(tagID, paymentID)); + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchExistingForRepeatingPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchExistingForRepeatingPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..5b6fda13a934ea9030b1eb3cffa970db02ab232b --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchExistingForRepeatingPayment.java @@ -0,0 +1,54 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchExistingForRepeatingPayment implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagMatchExistingForRepeatingPayment(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("tagID") || !req.queryParams().contains("repeatingPaymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int tagID = Integer.parseInt(req.queryMap("tagID").value()); + int repeatingPaymentID = Integer.parseInt(req.queryMap("repeatingPaymentID").value()); + + if(tagID < 0 || repeatingPaymentID < 0) + { + halt(400, "Bad Request"); + } + + return gson.toJson(tagHandler.isMatchExistingForRepeatingPaymentID(tagID, repeatingPaymentID)); + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchGetAllForPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchGetAllForPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..08a93ad9b39d992c4fd7d3efce79529266e37c9a --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchGetAllForPayment.java @@ -0,0 +1,67 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import java.util.ArrayList; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchGetAllForPayment implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagMatchGetAllForPayment(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("paymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int paymentID = Integer.parseInt(req.queryMap("paymentID").value()); + + if(paymentID < 0) + { + halt(400, "Bad Request"); + } + + ArrayList<Integer> tagIDs = tagHandler.getAllTagsForPayment(paymentID); + ArrayList<Tag> tags = new ArrayList<>(); + for(Integer currentTagID : tagIDs) + { + Tag currentTag = tagHandler.getTagByID(currentTagID); + if(currentTag != null) + { + tags.add(currentTag); + } + } + + return gson.toJson(tags); + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchGetAllForRepeatingPayment.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchGetAllForRepeatingPayment.java new file mode 100644 index 0000000000000000000000000000000000000000..7f8b4465060aacc42b46a88ce0054d82b1927a0b --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/match/TagMatchGetAllForRepeatingPayment.java @@ -0,0 +1,67 @@ +package de.deadlocker8.budgetmasterserver.server.tag.match; + +import static spark.Spark.halt; + +import java.util.ArrayList; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagMatchGetAllForRepeatingPayment implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagMatchGetAllForRepeatingPayment(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("repeatingPaymentID")) + { + halt(400, "Bad Request"); + } + + try + { + int repeatingPaymentID = Integer.parseInt(req.queryMap("repeatingPaymentID").value()); + + if(repeatingPaymentID < 0) + { + halt(400, "Bad Request"); + } + + ArrayList<Integer> tagIDs = tagHandler.getAllTagsForRepeatingPayment(repeatingPaymentID); + ArrayList<Tag> tags = new ArrayList<>(); + for(Integer currentTagID : tagIDs) + { + Tag currentTag = tagHandler.getTagByID(currentTagID); + if(currentTag != null) + { + tags.add(currentTag); + } + } + + return gson.toJson(tags); + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagAdd.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagAdd.java new file mode 100644 index 0000000000000000000000000000000000000000..edd44ab77f1e03d4d1c19f640910a4e395ab5ab2 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagAdd.java @@ -0,0 +1,44 @@ +package de.deadlocker8.budgetmasterserver.server.tag.tag; + +import static spark.Spark.halt; + +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagAdd implements Route +{ + private DatabaseTagHandler tagHandler; + + public TagAdd(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("name")) + { + halt(400, "Bad Request"); + } + + try + { + tagHandler.addTag(req.queryMap("name").value()); + + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return ""; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagDelete.java similarity index 70% rename from src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagDelete.java index ff7b6a5ae53c0b42c2cd91e04212545cf0a698f9..75d45f927b3601069b422cadd0ff2221d1d57069 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagDelete.java @@ -1,19 +1,19 @@ -package de.deadlocker8.budgetmasterserver.server.payment.normal; +package de.deadlocker8.budgetmasterserver.server.tag.tag; import static spark.Spark.halt; -import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; import spark.Request; import spark.Response; import spark.Route; -public class PaymentDelete implements Route +public class TagDelete implements Route { - private DatabaseHandler handler; + private DatabaseTagHandler tagHandler; - public PaymentDelete(DatabaseHandler handler) - { - this.handler = handler; + public TagDelete(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; } @Override @@ -36,8 +36,8 @@ public class PaymentDelete implements Route } try - { - handler.deletePayment(id); + { + tagHandler.deleteTag(id); return ""; } diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGet.java new file mode 100644 index 0000000000000000000000000000000000000000..782df0b96bd7b4ba78fc064aa3eced912a45cf58 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGet.java @@ -0,0 +1,60 @@ +package de.deadlocker8.budgetmasterserver.server.tag.tag; + +import static spark.Spark.halt; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagGet implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagGet(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("id")) + { + halt(400, "Bad Request"); + } + + int id = -1; + + try + { + id = Integer.parseInt(req.queryMap("id").value()); + + if(id < 0) + { + halt(400, "Bad Request"); + } + + try + { + Tag tag = tagHandler.getTagByID(id); + + return gson.toJson(tag); + } + catch(IllegalStateException e) + { + halt(500, "Internal Server Error"); + } + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGetAll.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGetAll.java new file mode 100644 index 0000000000000000000000000000000000000000..46f52361320184f834fa7d1e9b4d76797378bcf2 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGetAll.java @@ -0,0 +1,42 @@ +package de.deadlocker8.budgetmasterserver.server.tag.tag; + +import static spark.Spark.halt; + +import java.util.ArrayList; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagGetAll implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagGetAll(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + try + { + ArrayList<Tag> tags = tagHandler.getAllTags(); + + return gson.toJson(tags); + } + catch(IllegalStateException e) + { + halt(500, "Internal Server Error"); + } + + return null; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGetByName.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGetByName.java new file mode 100644 index 0000000000000000000000000000000000000000..a4e7a898978ff76953b2d73bb199d7653e3a0059 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/tag/tag/TagGetByName.java @@ -0,0 +1,44 @@ +package de.deadlocker8.budgetmasterserver.server.tag.tag; + +import static spark.Spark.halt; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; +import spark.Request; +import spark.Response; +import spark.Route; + +public class TagGetByName implements Route +{ + private DatabaseTagHandler tagHandler; + private Gson gson; + + public TagGetByName(DatabaseTagHandler tagHandler, Gson gson) + { + this.tagHandler = tagHandler; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("name")) + { + halt(400, "Bad Request"); + } + + try + { + Tag tag = tagHandler.getTagByName(req.queryMap("name").value()); + return gson.toJson(tag); + } + catch(Exception e) + { + halt(500, "Internal Server Error"); + } + + return null; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java similarity index 95% rename from src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java index bf3d5cd037162975976305d787482039b0c7b839..0ad4e5f8836e6cbb69c6cae0cc16164e87351928 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java @@ -6,8 +6,8 @@ import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.Months; -import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.LatestRepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import logger.Logger; diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/updater/TagUpdater.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/updater/TagUpdater.java new file mode 100644 index 0000000000000000000000000000000000000000..1263871aee24650744f3cf742506dbf93505bca9 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/updater/TagUpdater.java @@ -0,0 +1,28 @@ +package de.deadlocker8.budgetmasterserver.server.updater; + +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; + +public class TagUpdater +{ + private DatabaseTagHandler tagHandler; + + public TagUpdater(DatabaseTagHandler tagHandler) + { + this.tagHandler = tagHandler; + } + + public void deleteTagsIfNotReferenced() + { + ArrayList<Tag> tags = tagHandler.getAllTags(); + for(Tag currentTag : tags) + { + if(!tagHandler.isTagUsedInMatches(currentTag.getID())) + { + tagHandler.deleteTag(currentTag.getID()); + } + } + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java diff --git a/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties b/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..8de2a69fbfed7d822d9ebdf32a042ce1c98893ef --- /dev/null +++ b/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties @@ -0,0 +1,8 @@ +app.name=BudgetMasterServer +version.code=10 +version.name=1.6.0 +version.date=03.10.17 +author=Robert Goldmann + +category.none=No Category +category.rest=Rest \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/resources/settings.json b/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/settings.json similarity index 100% rename from src/de/deadlocker8/budgetmasterserver/resources/settings.json rename to BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/settings.json diff --git a/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseHandlerTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseHandlerTest.java similarity index 95% rename from tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseHandlerTest.java rename to BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseHandlerTest.java index 9321e7af500030007363f92e5cd89aaddef34330..80f6b7c660425c26beea47feca4489dc9e2f64a2 100644 --- a/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseHandlerTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseHandlerTest.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.tests.server.database; +package de.deadlocker8.budgetmaster.tests.database; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -13,10 +13,10 @@ import java.util.Locale; import org.junit.BeforeClass; import org.junit.Test; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.payment.LatestRepeatingPayment; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; import de.deadlocker8.budgetmasterserver.logic.Settings; import de.deadlocker8.budgetmasterserver.logic.Utils; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; @@ -39,8 +39,8 @@ public class DatabaseHandlerTest handler = new DatabaseHandler(settings); databaseHandler = handler; - Localization.init("de/deadlocker8/budgetmaster/resources/"); - Localization.loadLanguage(Locale.GERMANY); + Localization.init("de/deadlocker8/budgetmaster/"); + Localization.loadLanguage(Locale.ENGLISH); } catch(IOException | URISyntaxException e) { diff --git a/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseImportExportTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseImportExportTest.java similarity index 76% rename from tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseImportExportTest.java rename to BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseImportExportTest.java index 3e713d563afb5e932e6d9bd132c87737252cdcda..6414890b6acbe6bf4295bfe24ca998c3112e60ab 100644 --- a/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseImportExportTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseImportExportTest.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.tests.server.database; +package de.deadlocker8.budgetmaster.tests.database; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -15,23 +15,26 @@ import org.junit.BeforeClass; import org.junit.Test; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; +import de.deadlocker8.budgetmaster.logic.category.Category; +import de.deadlocker8.budgetmaster.logic.database.Database; +import de.deadlocker8.budgetmaster.logic.payment.NormalPayment; +import de.deadlocker8.budgetmaster.logic.payment.RepeatingPayment; import de.deadlocker8.budgetmaster.logic.utils.FileHelper; import de.deadlocker8.budgetmasterserver.logic.Settings; import de.deadlocker8.budgetmasterserver.logic.Utils; -import de.deadlocker8.budgetmasterserver.logic.database.Database; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseExporter; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; import de.deadlocker8.budgetmasterserver.logic.database.DatabaseImporter; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; import tools.Localization; public class DatabaseImportExportTest { private static Settings settings; private static DatabaseHandler databaseHandler; + private static DatabaseTagHandler tagHandler; @BeforeClass public static void init() @@ -44,9 +47,10 @@ public class DatabaseImportExportTest handler.deleteDatabase(); handler = new DatabaseHandler(settings); databaseHandler = handler; + tagHandler = new DatabaseTagHandler(settings); - Localization.init("de/deadlocker8/budgetmaster/resources/"); - Localization.loadLanguage(Locale.GERMANY); + Localization.init("de/deadlocker8/budgetmaster/"); + Localization.loadLanguage(Locale.ENGLISH); } catch(IOException | URISyntaxException e) { @@ -59,10 +63,10 @@ public class DatabaseImportExportTest { try { - File file = Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/import.json").toFile(); + File file = Paths.get("src/test/resources/de/deadlocker8/budgetmaster/import.json").toFile(); Database database = FileHelper.loadDatabaseJSON(file); - DatabaseImporter importer = new DatabaseImporter(databaseHandler); + DatabaseImporter importer = new DatabaseImporter(databaseHandler, tagHandler); importer.importDatabase(database); //test category @@ -74,7 +78,7 @@ public class DatabaseImportExportTest assertEquals(expectedCategory.getColor(), category.getColor()); //test normal payment - NormalPayment expectedPayment = new NormalPayment(1, 23, "2017-06-02", 0, "Test Normal", "Lorem Ipsum"); + NormalPayment expectedPayment = new NormalPayment(1, 23, "2017-06-02", 3, "Test Normal", "Lorem Ipsum"); NormalPayment payment = databaseHandler.getPayment(1); assertEquals(expectedPayment.getAmount(), payment.getAmount()); assertEquals(expectedPayment.getDate(), payment.getDate()); @@ -83,7 +87,7 @@ public class DatabaseImportExportTest assertEquals(expectedPayment.getDescription(), payment.getDescription()); //test repeating payment - RepeatingPayment expectedRepeatingPayment = new RepeatingPayment(1, -10012, "2017-06-01", 3, "Test Repeating", "Lorem Ipsum", 7, "2017-06-30", 0); + RepeatingPayment expectedRepeatingPayment = new RepeatingPayment(1, -10012, "2017-06-01", 1, "Test Repeating", "Lorem Ipsum", 7, "2017-06-30", 0); RepeatingPayment repeatingPayment = databaseHandler.getRepeatingPayment(1); assertEquals(expectedRepeatingPayment.getAmount(), repeatingPayment.getAmount()); assertEquals(expectedRepeatingPayment.getDate(), repeatingPayment.getDate()); @@ -92,7 +96,7 @@ public class DatabaseImportExportTest assertEquals(expectedRepeatingPayment.getDescription(), repeatingPayment.getDescription()); assertEquals(expectedRepeatingPayment.getRepeatInterval(), repeatingPayment.getRepeatInterval()); assertEquals(expectedRepeatingPayment.getRepeatEndDate(), repeatingPayment.getRepeatEndDate()); - assertEquals(expectedRepeatingPayment.getRepeatMonthDay(), repeatingPayment.getRepeatMonthDay()); + assertEquals(expectedRepeatingPayment.getRepeatMonthDay(), repeatingPayment.getRepeatMonthDay()); } catch(Exception e) { @@ -109,21 +113,21 @@ public class DatabaseImportExportTest databaseHandler.deleteDatabase(); databaseHandler = new DatabaseHandler(settings); - File file = Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/import.json").toFile(); + File file = Paths.get("src/test/resources/de/deadlocker8/budgetmaster/import.json").toFile(); Database database = FileHelper.loadDatabaseJSON(file); - DatabaseImporter importer = new DatabaseImporter(databaseHandler); + DatabaseImporter importer = new DatabaseImporter(databaseHandler, tagHandler); importer.importDatabase(database); - file = Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/export.json").toFile(); + file = Paths.get("src/test/resources/de/deadlocker8/budgetmaster/export.json").toFile(); DatabaseExporter exporter = new DatabaseExporter(settings); - Gson gson = new Gson(); - String databaseJSON = gson.toJson(exporter.exportDatabase()); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + String databaseJSON = gson.toJson(exporter.exportDatabase()).replaceAll("\n", ""); FileHelper.saveDatabaseJSON(file, databaseJSON); FileHelper.saveDatabaseJSON(new File("C:/Users/ROGO2/Desktop/123.json"), databaseJSON); - String expectedJSON = new String(Files.readAllBytes(Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/import.json"))); - String exportedJSON = new String(Files.readAllBytes(Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/export.json"))); + String expectedJSON = new String(Files.readAllBytes(Paths.get("src/test/resources/de/deadlocker8/budgetmaster/import.json"))); + String exportedJSON = new String(Files.readAllBytes(Paths.get("src/test/resources/de/deadlocker8/budgetmaster/export.json"))); assertEquals(expectedJSON, exportedJSON); } diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseTagHandlerTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseTagHandlerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..475c0f7f4bd1c9076dcfdccdc335ebaec7b38c88 --- /dev/null +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/database/DatabaseTagHandlerTest.java @@ -0,0 +1,118 @@ +package de.deadlocker8.budgetmaster.tests.database; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.junit.BeforeClass; +import org.junit.Test; + +import de.deadlocker8.budgetmaster.logic.tag.Tag; +import de.deadlocker8.budgetmasterserver.logic.Settings; +import de.deadlocker8.budgetmasterserver.logic.Utils; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.logic.database.DatabaseTagHandler; + +public class DatabaseTagHandlerTest +{ + private static DatabaseTagHandler tagHandler; + + @BeforeClass + public static void init() + { + try + { + //init + Settings settings = Utils.loadSettings(); + System.out.println(settings); + DatabaseHandler handler = new DatabaseHandler(settings); + handler.deleteDatabase(); + handler = new DatabaseHandler(settings); + tagHandler = new DatabaseTagHandler(settings); + } + catch(IOException | URISyntaxException e) + { + fail(e.getMessage()); + } + } + + @Test + public void testTag() + { + //add + Tag expected = new Tag(1, "sd836f4ds86f4sd86"); + tagHandler.addTag(expected.getName()); + ArrayList<Tag> tags = tagHandler.getAllTags(); + assertEquals(1, tags.size()); + + //get + Tag tag = tagHandler.getTagByID(1); + assertEquals(expected.getName(), tag.getName()); + + tag = tagHandler.getTagByName(expected.getName()); + assertEquals(1, tag.getID()); + } + + @Test + public void testDeleteCategory() + { + //add + Tag expected = new Tag(1, "115"); + tagHandler.addTag(expected.getName()); + + int id = tagHandler.getLastInsertID(); + + tagHandler.deleteTag(id); + Tag tag = tagHandler.getTagByID(id); + + assertNull(tag); + } + + @Test + public void testMatchForNormalPayment() + { + //add + Tag expected = new Tag(1, "wqeolugjf"); + tagHandler.addTag(expected.getName()); + int id = tagHandler.getLastInsertID(); + + tagHandler.addTagMatchForPayment(id, 1); + ArrayList<Integer> tags = tagHandler.getAllTagsForPayment(1); + assertEquals(1, tags.size()); + + assertTrue(tagHandler.isMatchExistingForPaymentID(id, 1)); + assertFalse(tagHandler.isMatchExistingForPaymentID(id, -3)); + + assertTrue(tagHandler.isTagUsedInMatches(id)); + + tagHandler.deleteTagMatchForPayment(id, 1); + assertFalse(tagHandler.isMatchExistingForPaymentID(id, 1)); + } + + @Test + public void testMatchRepeatingPayment() + { + //add + Tag expected = new Tag(1, "as5d4s5a4d"); + tagHandler.addTag(expected.getName()); + int id = tagHandler.getLastInsertID(); + + tagHandler.addTagMatchForRepeatingPayment(id, 1); + ArrayList<Integer> tags = tagHandler.getAllTagsForRepeatingPayment(1); + assertEquals(1, tags.size()); + + assertTrue(tagHandler.isMatchExistingForRepeatingPaymentID(id, 1)); + assertFalse(tagHandler.isMatchExistingForRepeatingPaymentID(id, -3)); + + assertTrue(tagHandler.isTagUsedInMatches(id)); + + tagHandler.deleteTagMatchForRepeatingPayment(id, 1); + assertFalse(tagHandler.isMatchExistingForRepeatingPaymentID(id, 1)); + } +} \ No newline at end of file diff --git a/tests/de/deadlocker8/budgetmaster/tests/server/settings/SettingsTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/settings/SettingsTest.java similarity index 94% rename from tests/de/deadlocker8/budgetmaster/tests/server/settings/SettingsTest.java rename to BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/settings/SettingsTest.java index 6136a4ca9d728627d118e7ca9a2c84dce306c7ea..cd660fadeff8ab2b817352d3015b707c77277490 100644 --- a/tests/de/deadlocker8/budgetmaster/tests/server/settings/SettingsTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/tests/settings/SettingsTest.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmaster.tests.server.settings; +package de.deadlocker8.budgetmaster.tests.settings; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; diff --git a/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/_en.properties b/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..9a6167b39161f92cc7325cd55bdf1c46419296a3 --- /dev/null +++ b/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/_en.properties @@ -0,0 +1,8 @@ +app.name=BudgetMasterServer +version.code=10 +version.name=1.6.0_alpha +version.date=31.08.17 +author=Robert Goldmann + +category.none=No Category +category.rest=Rest \ No newline at end of file diff --git a/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/export.json b/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/export.json new file mode 100644 index 0000000000000000000000000000000000000000..2ec45ae722fd88352583b6f633d6ef837f799103 --- /dev/null +++ b/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/export.json @@ -0,0 +1 @@ +{ "TYPE": "BUDGETMASTER_DATABASE", "VERSION": 2, "categories": [ { "ID": 1, "name": "NONE", "color": "#FFFFFF" }, { "ID": 2, "name": "Übertrag", "color": "#FFFF00" }, { "ID": 3, "name": "123 Tü+?est Category", "color": "#FF9500" } ], "normalPayments": [ { "ID": 1, "amount": 23, "date": "2017-06-02", "categoryID": 3, "name": "Test Normal", "description": "Lorem Ipsum" } ], "repeatingPayments": [ { "repeatInterval": 7, "repeatEndDate": "2017-06-30", "repeatMonthDay": 0, "ID": 1, "amount": -10012, "date": "2017-06-01", "categoryID": 1, "name": "Test Repeating", "description": "Lorem Ipsum" } ], "tags": [ { "ID": 1, "name": "Lorem Ipsum" }, { "ID": 2, "name": "123" } ], "tagMatches": [ { "tagID": 1, "paymentID": -1, "repeatingPaymentID": 1 }, { "tagID": 2, "paymentID": 1, "repeatingPaymentID": -1 } ]} \ No newline at end of file diff --git a/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/import.json b/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/import.json new file mode 100644 index 0000000000000000000000000000000000000000..2ec45ae722fd88352583b6f633d6ef837f799103 --- /dev/null +++ b/BudgetMasterServer/src/test/resources/de/deadlocker8/budgetmaster/import.json @@ -0,0 +1 @@ +{ "TYPE": "BUDGETMASTER_DATABASE", "VERSION": 2, "categories": [ { "ID": 1, "name": "NONE", "color": "#FFFFFF" }, { "ID": 2, "name": "Übertrag", "color": "#FFFF00" }, { "ID": 3, "name": "123 Tü+?est Category", "color": "#FF9500" } ], "normalPayments": [ { "ID": 1, "amount": 23, "date": "2017-06-02", "categoryID": 3, "name": "Test Normal", "description": "Lorem Ipsum" } ], "repeatingPayments": [ { "repeatInterval": 7, "repeatEndDate": "2017-06-30", "repeatMonthDay": 0, "ID": 1, "amount": -10012, "date": "2017-06-01", "categoryID": 1, "name": "Test Repeating", "description": "Lorem Ipsum" } ], "tags": [ { "ID": 1, "name": "Lorem Ipsum" }, { "ID": 2, "name": "123" } ], "tagMatches": [ { "tagID": 1, "paymentID": -1, "repeatingPaymentID": 1 }, { "tagID": 2, "paymentID": 1, "repeatingPaymentID": -1 } ]} \ No newline at end of file diff --git a/build/BudgetMaster.exe b/build/BudgetMaster.exe index f0468024a67ed446bc2b9497f64e1822184809a6..8f3cc2cdfbe17ffc4462c0c8b75a4baacbef2f80 100644 Binary files a/build/BudgetMaster.exe and b/build/BudgetMaster.exe differ diff --git a/build/BudgetMasterClient.jar b/build/BudgetMasterClient.jar index 1e16f1a058dca374636736ce064b49cfc9d8761b..2cc65b521323311ffafd9c130757d90797b2a6f4 100644 Binary files a/build/BudgetMasterClient.jar and b/build/BudgetMasterClient.jar differ diff --git a/build/BudgetMasterServer.jar b/build/BudgetMasterServer.jar index 4b386473050280b9bdf8c94bddddc396e726697d..da8339bbc21ff0df81bd6c6cb7b22e811b2daa14 100644 Binary files a/build/BudgetMasterServer.jar and b/build/BudgetMasterServer.jar differ diff --git a/build/screenshots/bearbeiten.png b/build/screenshots/bearbeiten.png deleted file mode 100644 index afafb412113723381bc409673ee23ca626ffa9f1..0000000000000000000000000000000000000000 Binary files a/build/screenshots/bearbeiten.png and /dev/null differ diff --git a/build/screenshots/bericht_1.png b/build/screenshots/bericht_1.png deleted file mode 100644 index 792a901381483fd3854599484169330a205da71e..0000000000000000000000000000000000000000 Binary files a/build/screenshots/bericht_1.png and /dev/null differ diff --git a/build/screenshots/bericht_2.png b/build/screenshots/bericht_2.png deleted file mode 100644 index 05f4bfc097a1a669466b9666f8ccdfacb1e92448..0000000000000000000000000000000000000000 Binary files a/build/screenshots/bericht_2.png and /dev/null differ diff --git a/build/screenshots/buchungen.png b/build/screenshots/buchungen.png deleted file mode 100644 index bfb50e226c3d0dc2090416d3a1a4961570b18182..0000000000000000000000000000000000000000 Binary files a/build/screenshots/buchungen.png and /dev/null differ diff --git a/build/screenshots/de/bearbeiten.png b/build/screenshots/de/bearbeiten.png new file mode 100644 index 0000000000000000000000000000000000000000..19412d389e7eb9d82f4b864363a4feceff3c02c0 Binary files /dev/null and b/build/screenshots/de/bearbeiten.png differ diff --git a/build/screenshots/de/bericht_1.png b/build/screenshots/de/bericht_1.png new file mode 100644 index 0000000000000000000000000000000000000000..111c4e747ec17f1c0abdb2a30f6521240f4ddb6e Binary files /dev/null and b/build/screenshots/de/bericht_1.png differ diff --git a/build/screenshots/de/bericht_2.jpg b/build/screenshots/de/bericht_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc6f3f334a0a29d73a01d212729a23a549388df2 Binary files /dev/null and b/build/screenshots/de/bericht_2.jpg differ diff --git a/build/screenshots/de/buchungen.png b/build/screenshots/de/buchungen.png new file mode 100644 index 0000000000000000000000000000000000000000..ad04dcf1156f8265ea188aed624db917021ad860 Binary files /dev/null and b/build/screenshots/de/buchungen.png differ diff --git a/build/screenshots/de/diagramme_1.png b/build/screenshots/de/diagramme_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a13ecbdde835d69e8db6ed06512d22c4d490b0fc Binary files /dev/null and b/build/screenshots/de/diagramme_1.png differ diff --git a/build/screenshots/de/diagramme_2.png b/build/screenshots/de/diagramme_2.png new file mode 100644 index 0000000000000000000000000000000000000000..cb7c2322560c679d64db73145a5e343c3b88174a Binary files /dev/null and b/build/screenshots/de/diagramme_2.png differ diff --git a/build/screenshots/de/diagramme_3.png b/build/screenshots/de/diagramme_3.png new file mode 100644 index 0000000000000000000000000000000000000000..3a3d0d3fb3a39875dea3878760911bf1baa69cad Binary files /dev/null and b/build/screenshots/de/diagramme_3.png differ diff --git a/build/screenshots/de/einstellungen.png b/build/screenshots/de/einstellungen.png new file mode 100644 index 0000000000000000000000000000000000000000..8cff2ca926eb6c2b01f4434a4e243453baa9273c Binary files /dev/null and b/build/screenshots/de/einstellungen.png differ diff --git a/build/screenshots/de/filter.png b/build/screenshots/de/filter.png new file mode 100644 index 0000000000000000000000000000000000000000..796c6bbc682c36a6168c37d3294a6b6354b1c3a6 Binary files /dev/null and b/build/screenshots/de/filter.png differ diff --git a/build/screenshots/de/kategorien.png b/build/screenshots/de/kategorien.png new file mode 100644 index 0000000000000000000000000000000000000000..2841e6f34b1370faa68f1cbce422a3e30a44f72f Binary files /dev/null and b/build/screenshots/de/kategorien.png differ diff --git a/build/screenshots/de/normal.png b/build/screenshots/de/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..6787761d2873065cb9a55770248495c73f6a418e Binary files /dev/null and b/build/screenshots/de/normal.png differ diff --git a/build/screenshots/de/overbudget.png b/build/screenshots/de/overbudget.png new file mode 100644 index 0000000000000000000000000000000000000000..1df03d10456cef6a978ce8360c192b3d1f599f78 Binary files /dev/null and b/build/screenshots/de/overbudget.png differ diff --git a/build/screenshots/de/suche.png b/build/screenshots/de/suche.png new file mode 100644 index 0000000000000000000000000000000000000000..57beba799d5ab5e250fe8b0de40896ce5b3e5dc6 Binary files /dev/null and b/build/screenshots/de/suche.png differ diff --git a/build/screenshots/diagramme_1.png b/build/screenshots/diagramme_1.png deleted file mode 100644 index ef4b60804945102d1c4d36e431d0e24ccc6efbb1..0000000000000000000000000000000000000000 Binary files a/build/screenshots/diagramme_1.png and /dev/null differ diff --git a/build/screenshots/diagramme_2.png b/build/screenshots/diagramme_2.png deleted file mode 100644 index 56969b07ae29a385e7c7d569c56dca91abd59b8a..0000000000000000000000000000000000000000 Binary files a/build/screenshots/diagramme_2.png and /dev/null differ diff --git a/build/screenshots/diagramme_3.png b/build/screenshots/diagramme_3.png deleted file mode 100644 index 2054ec5ffa5ca6b5e617092ea6788325b9cad9ef..0000000000000000000000000000000000000000 Binary files a/build/screenshots/diagramme_3.png and /dev/null differ diff --git a/build/screenshots/einstellungen.png b/build/screenshots/einstellungen.png deleted file mode 100644 index 276a01e48109851a5e0b1bfc5d36869ee7f3d920..0000000000000000000000000000000000000000 Binary files a/build/screenshots/einstellungen.png and /dev/null differ diff --git a/build/screenshots/en/bearbeiten.png b/build/screenshots/en/bearbeiten.png new file mode 100644 index 0000000000000000000000000000000000000000..adb4ae80ce9b8dea7739b81ee0800254267f970d Binary files /dev/null and b/build/screenshots/en/bearbeiten.png differ diff --git a/build/screenshots/en/bericht_1.png b/build/screenshots/en/bericht_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d476fee610b8488f39277cbea347f609babc8a7b Binary files /dev/null and b/build/screenshots/en/bericht_1.png differ diff --git a/build/screenshots/en/bericht_2.jpg b/build/screenshots/en/bericht_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..70f1e83b2a944565951c3bf14c8ab19acfe7d2ba Binary files /dev/null and b/build/screenshots/en/bericht_2.jpg differ diff --git a/build/screenshots/en/buchungen.png b/build/screenshots/en/buchungen.png new file mode 100644 index 0000000000000000000000000000000000000000..3c560daf68c4adb788a1ea2724e19af40aa95d40 Binary files /dev/null and b/build/screenshots/en/buchungen.png differ diff --git a/build/screenshots/en/diagramme_1.png b/build/screenshots/en/diagramme_1.png new file mode 100644 index 0000000000000000000000000000000000000000..81b16c075ec095f330e76fd454b41da0f46952be Binary files /dev/null and b/build/screenshots/en/diagramme_1.png differ diff --git a/build/screenshots/en/diagramme_2.png b/build/screenshots/en/diagramme_2.png new file mode 100644 index 0000000000000000000000000000000000000000..e420d1054f70d80d377c600063022f3254aaa8dc Binary files /dev/null and b/build/screenshots/en/diagramme_2.png differ diff --git a/build/screenshots/en/diagramme_3.png b/build/screenshots/en/diagramme_3.png new file mode 100644 index 0000000000000000000000000000000000000000..83d80499750be94fbc5016c164e42fbbcd105643 Binary files /dev/null and b/build/screenshots/en/diagramme_3.png differ diff --git a/build/screenshots/en/einstellungen.png b/build/screenshots/en/einstellungen.png new file mode 100644 index 0000000000000000000000000000000000000000..532309227190e95a023c423f02bc50881a93254a Binary files /dev/null and b/build/screenshots/en/einstellungen.png differ diff --git a/build/screenshots/en/filter.png b/build/screenshots/en/filter.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d8d3d16011a2f1534a1156b654102ee74c826b Binary files /dev/null and b/build/screenshots/en/filter.png differ diff --git a/build/screenshots/en/kategorien.png b/build/screenshots/en/kategorien.png new file mode 100644 index 0000000000000000000000000000000000000000..002ba97cb194c96d9f2c8b314460a895b8493073 Binary files /dev/null and b/build/screenshots/en/kategorien.png differ diff --git a/build/screenshots/en/normal.png b/build/screenshots/en/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..6b34dfa9d393227fb3c796d473a9f426fd1b17e2 Binary files /dev/null and b/build/screenshots/en/normal.png differ diff --git a/build/screenshots/en/overbudget.png b/build/screenshots/en/overbudget.png new file mode 100644 index 0000000000000000000000000000000000000000..0e70444f32a7073bd58987163b6d89ac5c6e825d Binary files /dev/null and b/build/screenshots/en/overbudget.png differ diff --git a/build/screenshots/en/suche.png b/build/screenshots/en/suche.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7afaf16f27a97409fd058c84f3c432c385ac4d Binary files /dev/null and b/build/screenshots/en/suche.png differ diff --git a/build/screenshots/filter.png b/build/screenshots/filter.png deleted file mode 100644 index 03fcb7deb011302577dfa735d88c874ede461c60..0000000000000000000000000000000000000000 Binary files a/build/screenshots/filter.png and /dev/null differ diff --git a/build/screenshots/kategorien.png b/build/screenshots/kategorien.png deleted file mode 100644 index 522ecf1ac189f72fdb6366e728077a3f82611eb5..0000000000000000000000000000000000000000 Binary files a/build/screenshots/kategorien.png and /dev/null differ diff --git a/build/screenshots/normal.png b/build/screenshots/normal.png deleted file mode 100644 index c2a984eb78f0dc38d33336780c75362bdf8f3ba3..0000000000000000000000000000000000000000 Binary files a/build/screenshots/normal.png and /dev/null differ diff --git a/build/screenshots/overbudget.png b/build/screenshots/overbudget.png deleted file mode 100644 index a9bed0d49de77e4ea2c7941fc0761838d8b96c37..0000000000000000000000000000000000000000 Binary files a/build/screenshots/overbudget.png and /dev/null differ diff --git a/lib/Tools.jar b/lib/Tools.jar new file mode 100644 index 0000000000000000000000000000000000000000..65c7881f2a2ae85bc3ded29e8fac64f62bb78fb1 Binary files /dev/null and b/lib/Tools.jar differ diff --git a/pom.xml b/pom.xml deleted file mode 100644 index fee0e286908f96732d52fe82567d1d3f4891e761..0000000000000000000000000000000000000000 --- a/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>BudgetMaster</groupId> - <artifactId>BudgetMaster</artifactId> - <version>0.0.1-SNAPSHOT</version> - <build> - <sourceDirectory>src</sourceDirectory> - <resources> - <resource> - <directory>src</directory> - <excludes> - <exclude>**/*.java</exclude> - </excludes> - </resource> - </resources> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.3</version> - <configuration> - <source/> - <target/> - </configuration> - </plugin> - </plugins> - - </build> - - <dependencies> - <dependency> - <groupId>com.sparkjava</groupId> - <artifactId>spark-core</artifactId> - <version>2.5.4</version> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-simple</artifactId> - <version>1.7.21</version> - </dependency> - <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - <version>2.8.0</version> - </dependency> - <dependency> - <groupId>org.controlsfx</groupId> - <artifactId>controlsfx</artifactId> - <version>8.40.12</version> - </dependency> - <dependency> - <groupId>mysql</groupId> - <artifactId>mysql-connector-java</artifactId> - <version>6.0.5</version> - </dependency> - <dependency> - <groupId>joda-time</groupId> - <artifactId>joda-time</artifactId> - <version>2.9.7</version> - </dependency> - <dependency> - <groupId>com.itextpdf</groupId> - <artifactId>itextpdf</artifactId> - <version>5.0.6</version> - </dependency> - </dependencies> -</project> \ No newline at end of file diff --git a/settings.json b/settings.json deleted file mode 100644 index 359fd4076b45a92599d74e446d3aa47a4be9578d..0000000000000000000000000000000000000000 --- a/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "databaseUrl": "jdbc:mysql://localhost:3306/", - "databaseName": "budgetmaster", - "databaseUsername": "root", - "databasePassword": "", - "serverPort": 9000, - "serverSecret": "geheim", - "keystorePath": "C:/Programmierung/eclipse/workspace/BudgetMaster/certs/keystore.jks", - "keystorePassword": "geheim" -} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/CategoryController.java b/src/de/deadlocker8/budgetmaster/ui/controller/CategoryController.java deleted file mode 100644 index 2643375e346134070a64aeddee9f6cef25ac674a..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmaster/ui/controller/CategoryController.java +++ /dev/null @@ -1,184 +0,0 @@ -package de.deadlocker8.budgetmaster.ui.controller; - - -import java.io.IOException; -import java.util.ArrayList; - -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler; -import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; -import de.deadlocker8.budgetmaster.logic.utils.Colors; -import de.deadlocker8.budgetmaster.logic.utils.Helpers; -import de.deadlocker8.budgetmaster.logic.utils.Strings; -import de.deadlocker8.budgetmaster.ui.Refreshable; -import de.deadlocker8.budgetmaster.ui.cells.CategoryCell; -import fontAwesome.FontIconType; -import javafx.application.Platform; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.event.EventHandler; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.input.MouseEvent; -import javafx.scene.layout.AnchorPane; -import javafx.scene.paint.Color; -import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.util.Callback; -import logger.Logger; -import tools.ConvertTo; -import tools.Localization; - -public class CategoryController implements Refreshable -{ - @FXML private AnchorPane anchorPaneMain; - @FXML private Button buttonCategory; - @FXML private ListView<Category> listView; - - private Controller controller; - - public void init(Controller controller) - { - this.controller = controller; - - CategoryController thisController = this; - listView.setCellFactory(new Callback<ListView<Category>, ListCell<Category>>() - { - @Override - public ListCell<Category> call(ListView<Category> param) - { - CategoryCell cell = new CategoryCell(thisController); - cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() - { - @Override - public void handle(MouseEvent event) - { - if(event.getClickCount() == 2) - { - // don't allow editing of category "none" - if(cell.getItem().getID() != 1) - { - newCategory(true, cell.getItem()); - } - } - } - }); - return cell; - } - }); - - listView.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() - { - @Override - public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) - { - Platform.runLater(new Runnable() - { - public void run() - { - listView.getSelectionModel().select(-1); - } - }); - } - }); - - Label labelPlaceholder = new Label(Localization.getString(Strings.CATEGORIES_PLACEHOLDER)); - labelPlaceholder.setStyle("-fx-font-size: 16"); - listView.setPlaceholder(labelPlaceholder); - - buttonCategory.setGraphic(Helpers.getFontIcon(FontIconType.PLUS, 18, Color.WHITE)); - - //apply theme - anchorPaneMain.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND)); - buttonCategory.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(Colors.BACKGROUND_BUTTON_BLUE) + "; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;"); - - refreshListView(); - } - - public void refreshListView() - { - listView.getItems().clear(); - - if(controller.getCategoryHandler() != null) - { - ArrayList<Category> categories = controller.getCategoryHandler().getCategories(); - if(categories != null && categories.size() > 0) - { - //remove category NONE (not editable) - categories.remove(0); - listView.getItems().setAll(categories); - } - } - } - - public void createNewCategory() - { - newCategory(false, null); - } - - public void newCategory(boolean edit, Category category) - { - try - { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml")); - fxmlLoader.setResources(Localization.getBundle()); - Parent root = (Parent)fxmlLoader.load(); - Stage newStage = new Stage(); - newStage.initOwner(controller.getStage()); - newStage.initModality(Modality.APPLICATION_MODAL); - - if(edit) - { - newStage.setTitle(Localization.getString(Strings.TITLE_CATEGORY_EDIT)); - } - else - { - newStage.setTitle(Localization.getString(Strings.TITLE_CATEGORY_NEW)); - } - - newStage.setScene(new Scene(root)); - newStage.getIcons().add(controller.getIcon()); - newStage.setResizable(false); - newStage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css"); - NewCategoryController newController = fxmlLoader.getController(); - newController.init(newStage, controller, this, edit, category); - newStage.show(); - } - catch(IOException e) - { - Logger.error(e); - } - } - - public void deleteCategory(int ID) - { - try - { - ServerConnection connection = new ServerConnection(controller.getSettings()); - connection.deleteCategory(ID); - controller.refresh(controller.getFilterSettings()); - } - catch(Exception e) - { - Logger.error(e); - controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e)); - } - } - - public Controller getController() - { - return controller; - } - - @Override - public void refresh() - { - refreshListView(); - } -} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml deleted file mode 100644 index 804c5464c4dad4f4b0c18b3fd15ab910e0f46afb..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml +++ /dev/null @@ -1,141 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.CheckBox?> -<?import javafx.scene.control.Label?> -<?import javafx.scene.control.ScrollPane?> -<?import javafx.scene.control.TextField?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> - -<AnchorPane prefHeight="600.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.FilterController"> - <children> - <VBox prefHeight="273.0" prefWidth="465.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> - <children> - <Label text="%filter.headline"> - <font> - <Font name="System Bold" size="18.0" /> - </font> - </Label> - <VBox prefHeight="15.0" prefWidth="422.0" spacing="10.0"> - <children> - <Label text="%filter.type"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <HBox prefHeight="10.0" prefWidth="422.0" spacing="25.0"> - <children> - <CheckBox fx:id="checkBoxIncome" mnemonicParsing="false" text="%filter.type.income"> - <font> - <Font size="14.0" /> - </font> - </CheckBox> - <CheckBox fx:id="checkBoxPayment" mnemonicParsing="false" text="%filter.type.payment"> - <font> - <Font size="14.0" /> - </font> - </CheckBox> - </children> - </HBox> - </children> - </VBox> - <VBox prefHeight="33.0" prefWidth="422.0" spacing="10.0"> - <children> - <Label text="%filter.repeating"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <CheckBox fx:id="checkBoxNoRepeating" mnemonicParsing="false" text="%filter.repeating.none"> - <font> - <Font size="14.0" /> - </font> - </CheckBox> - <CheckBox fx:id="checkBoxMonthlyRepeating" mnemonicParsing="false" text="%filter.repeating.monthday"> - <font> - <Font size="14.0" /> - </font> - </CheckBox> - <CheckBox fx:id="checkBoxRepeatEveryXDays" mnemonicParsing="false" text="%filter.repeating.interval"> - <font> - <Font size="14.0" /> - </font> - </CheckBox> - </children> - </VBox> - <VBox prefHeight="150.0" prefWidth="422.0" spacing="10.0"> - <children> - <HBox spacing="10.0"> - <children> - <Label text="%filter.categories"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Region prefWidth="200.0" HBox.hgrow="ALWAYS" /> - <Button fx:id="buttonCategoryAll" mnemonicParsing="false" onAction="#enableAllCategories" text="%filter.categories.button.all"> - <font> - <Font name="System Bold" size="13.0" /> - </font> - </Button> - <Button fx:id="buttonCategoryNone" mnemonicParsing="false" onAction="#disableAllCategories" text="%filter.categories.button.none"> - <font> - <Font name="System Bold" size="13.0" /> - </font> - </Button> - </children> - </HBox> - <ScrollPane prefHeight="93.0" prefWidth="422.0" VBox.vgrow="ALWAYS"> - <content> - <VBox fx:id="vboxCategories" spacing="5.0" /> - </content> - </ScrollPane> - </children> - </VBox> - <VBox prefHeight="33.0" prefWidth="422.0" VBox.vgrow="ALWAYS"> - <children> - <Label text="%filter.name"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <TextField fx:id="textFieldSearch" /> - </children> - </VBox> - <HBox alignment="CENTER" prefHeight="30.0" prefWidth="465.0" spacing="10.0"> - <children> - <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="%cancel"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Button> - <Button fx:id="buttonReset" mnemonicParsing="false" onAction="#reset" text="%filter.button.reset"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - <HBox.margin> - <Insets left="25.0" /> - </HBox.margin> - </Button> - <Button fx:id="buttonFilter" mnemonicParsing="false" onAction="#filter" text="%filter.button.filter"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - <HBox.margin> - <Insets left="25.0" /> - </HBox.margin> - </Button> - </children> - <VBox.margin> - <Insets top="10.0" /> - </VBox.margin> - </HBox> - </children> - </VBox> - </children> -</AnchorPane> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml deleted file mode 100644 index 10b33bc9a7b194359838fe0c51d9db4067d1a774..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml +++ /dev/null @@ -1,203 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.CheckBox?> -<?import javafx.scene.control.ComboBox?> -<?import javafx.scene.control.DatePicker?> -<?import javafx.scene.control.Label?> -<?import javafx.scene.control.RadioButton?> -<?import javafx.scene.control.Separator?> -<?import javafx.scene.control.Spinner?> -<?import javafx.scene.control.TextArea?> -<?import javafx.scene.control.TextField?> -<?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="450.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.NewPaymentController"> - <children> - <VBox prefHeight="273.0" prefWidth="465.0" spacing="20.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> - <children> - <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> - <children> - <VBox> - <children> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.name"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.max.characters"> - <font> - <Font size="11.0" /> - </font> - </Label> - </children> - </VBox> - <TextField fx:id="textFieldName" prefHeight="29.0" HBox.hgrow="ALWAYS"> - <font> - <Font size="13.0" /> - </font> - <HBox.margin> - <Insets /> - </HBox.margin> - </TextField> - </children> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> - <children> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.amount"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <TextField fx:id="textFieldAmount" prefHeight="29.0" HBox.hgrow="ALWAYS"> - <font> - <Font size="13.0" /> - </font> - <HBox.margin> - <Insets /> - </HBox.margin> - </TextField> - </children> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> - <children> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.category"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <ComboBox fx:id="comboBoxCategory" maxWidth="1.7976931348623157E308" prefHeight="30.0" HBox.hgrow="ALWAYS" /> - </children> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> - <children> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.date"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <DatePicker fx:id="datePicker" maxWidth="1.7976931348623157E308" prefHeight="29.0" HBox.hgrow="ALWAYS" /> - </children> - </HBox> - <HBox alignment="CENTER_LEFT" maxHeight="1.7976931348623157E308" prefWidth="422.0" VBox.vgrow="ALWAYS"> - <children> - <VBox alignment="CENTER_LEFT"> - <children> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.description"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.max.characters"> - <font> - <Font size="11.0" /> - </font> - </Label> - </children> - </VBox> - <TextArea fx:id="textArea" maxWidth="1.7976931348623157E308" prefHeight="37.0" prefWidth="240.0" HBox.hgrow="ALWAYS" /> - </children> - </HBox> - <VBox prefHeight="214.0" prefWidth="422.0" spacing="20.0"> - <children> - <HBox alignment="CENTER"> - <children> - <CheckBox fx:id="checkBoxRepeat" mnemonicParsing="false" /> - <Label alignment="CENTER" maxWidth="1.7976931348623157E308" prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.repeating"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - </children> - </HBox> - <HBox alignment="TOP_CENTER" prefWidth="422.0"> - <children> - <VBox alignment="TOP_CENTER" spacing="5.0" HBox.hgrow="ALWAYS"> - <children> - <RadioButton fx:id="radioButtonPeriod" mnemonicParsing="false"> - <VBox.margin> - <Insets bottom="10.0" /> - </VBox.margin> - </RadioButton> - <Label fx:id="labelText1" prefHeight="25.0" prefWidth="40.0" text="%payment.new.label.repeating.all"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <Spinner fx:id="spinnerRepeatingPeriod" prefHeight="25.0" prefWidth="90.0" /> - <Label fx:id="labelText2" prefHeight="25.0" prefWidth="36.0" text="%payment.new.label.repeating.days"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - </children> - <padding> - <Insets left="15.0" right="15.0" /> - </padding> - </VBox> - <Separator orientation="VERTICAL" prefHeight="200.0" /> - <VBox alignment="TOP_CENTER" spacing="5.0" HBox.hgrow="ALWAYS"> - <children> - <RadioButton fx:id="radioButtonDay" mnemonicParsing="false"> - <VBox.margin> - <Insets bottom="10.0" /> - </VBox.margin> - </RadioButton> - <Label fx:id="labelText3" prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.repeating.monthday"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <ComboBox fx:id="comboBoxRepeatingDay" prefHeight="25.0" prefWidth="90.0" /> - <Label prefHeight="25.0" prefWidth="36.0"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - </children> - <padding> - <Insets left="15.0" right="15.0" /> - </padding> - </VBox> - </children> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0"> - <children> - <Label prefHeight="29.0" prefWidth="125.0" text="%payment.new.label.enddate"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Label> - <DatePicker fx:id="datePickerEnddate" maxWidth="1.7976931348623157E308" prefHeight="29.0" HBox.hgrow="ALWAYS" /> - </children> - </HBox> - </children> - </VBox> - <HBox alignment="CENTER" prefHeight="30.0" prefWidth="465.0"> - <children> - <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="%cancel"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Button> - <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="%payment.new.button.save"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - <HBox.margin> - <Insets left="25.0" /> - </HBox.margin> - </Button> - </children> - <VBox.margin> - <Insets top="10.0" /> - </VBox.margin> - </HBox> - </children> - </VBox> - </children> -</AnchorPane> diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml deleted file mode 100644 index c7b7ae27a60f15737d519fee587ba14882ba19fe..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml +++ /dev/null @@ -1,213 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.CheckBox?> -<?import javafx.scene.control.ComboBox?> -<?import javafx.scene.control.Label?> -<?import javafx.scene.control.RadioButton?> -<?import javafx.scene.control.TextArea?> -<?import javafx.scene.control.TextField?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> - -<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.SettingsController"> - <children> - <VBox alignment="TOP_CENTER" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0"> - <children> - <HBox prefHeight="359.0" prefWidth="722.0" VBox.vgrow="ALWAYS"> - <children> - <VBox alignment="CENTER_RIGHT" prefHeight="25.0" prefWidth="158.0" spacing="15.0"> - <children> - <Label fx:id="labelClientSecret" prefHeight="25.0" text="%settingstab.label.secret.client"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Label fx:id="labelURL" prefHeight="25.0" text="%settingstab.label.url"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - <VBox.margin> - <Insets /> - </VBox.margin> - </Label> - <Label fx:id="labelSecret" prefHeight="25.0" text="%settingstab.label.secret.server"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Label fx:id="labelCurrency" prefHeight="25.0" text="%settingstab.label.currency"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Label fx:id="labelSecret11" prefHeight="25.0" text="%settingstab.label.rest"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Label fx:id="labelSecret111" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" minHeight="60.0" prefWidth="158.0" text="%settingstab.label.trusted.hosts" textAlignment="RIGHT" wrapText="true"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - <VBox.margin> - <Insets top="-7.0" /> - </VBox.margin> - </Label> - <Label fx:id="labelSecret1111" alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" text="%settingstab.label.trusted.hosts.info" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS"> - <font> - <Font size="14.0" /> - </font> - <VBox.margin> - <Insets top="-20.0" /> - </VBox.margin> - </Label> - <Label fx:id="labelSecret1112" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="%settingstab.label.language" textAlignment="RIGHT" wrapText="true"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - <VBox.margin> - <Insets top="50.0" /> - </VBox.margin> - </Label> - <Label fx:id="labelSecret11122" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="%settingstab.label.database" textAlignment="RIGHT" wrapText="true"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - <VBox.margin> - <Insets /> - </VBox.margin> - </Label> - <Label fx:id="labelSecret111221" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="%settingstab.label.updates" textAlignment="RIGHT" wrapText="true"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - </Label> - <Label fx:id="labelSecret11121" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" textAlignment="RIGHT" wrapText="true"> - <font> - <Font name="System Bold" size="16.0" /> - </font> - <VBox.margin> - <Insets top="15.0" /> - </VBox.margin> - </Label> - <Region prefHeight="19.0" prefWidth="158.0" VBox.vgrow="ALWAYS" /> - </children> - <HBox.margin> - <Insets right="25.0" /> - </HBox.margin> - </VBox> - <VBox alignment="CENTER_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="15.0" HBox.hgrow="ALWAYS"> - <children> - <TextField fx:id="textFieldClientSecret" /> - <TextField fx:id="textFieldURL" /> - <TextField fx:id="textFieldSecret" /> - <TextField fx:id="textFieldCurrency" /> - <HBox alignment="CENTER" prefHeight="11.0" prefWidth="539.0" spacing="30.0"> - <children> - <RadioButton fx:id="radioButtonRestActivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="%settingstab.label.rest.activated"> - <font> - <Font size="14.0" /> - </font> - <HBox.margin> - <Insets /> - </HBox.margin> - </RadioButton> - <RadioButton fx:id="radioButtonRestDeactivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="%settingstab.label.rest.deactivated" HBox.hgrow="ALWAYS"> - <font> - <Font size="14.0" /> - </font> - </RadioButton> - </children> - </HBox> - <TextArea fx:id="textAreaTrustedHosts" minHeight="110.0" prefHeight="148.0" prefWidth="539.0" VBox.vgrow="ALWAYS"> - <VBox.margin> - <Insets /> - </VBox.margin> - </TextArea> - <ComboBox fx:id="comboBoxLanguage" maxWidth="1.7976931348623157E308" /> - <HBox alignment="CENTER_LEFT" prefHeight="11.0" prefWidth="539.0" spacing="30.0"> - <children> - <Button fx:id="buttonExportDB" mnemonicParsing="false" onAction="#exportDB" text="%settingstab.button.database.export"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Button> - <Button fx:id="buttonImportDB" mnemonicParsing="false" onAction="#importDB" text="%settingstab.button.database.import"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Button> - <Button fx:id="buttonDeleteDB" mnemonicParsing="false" onAction="#deleteDB" text="%settingstab.button.database.delete"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - </Button> - </children> - <VBox.margin> - <Insets /> - </VBox.margin> - </HBox> - <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="20.0"> - <children> - <VBox spacing="10.0" HBox.hgrow="ALWAYS"> - <children> - <CheckBox fx:id="checkboxEnableAutoUpdate" mnemonicParsing="false" text="%settingstab.button.updates.automatic"> - <font> - <Font size="13.0" /> - </font></CheckBox> - <Button fx:id="buttonSearchUpdates" mnemonicParsing="false" onAction="#checkForUpdates" text="%settingstab.button.updates.search" /> - </children> - </VBox> - <VBox prefHeight="200.0" prefWidth="100.0" spacing="5.0" HBox.hgrow="ALWAYS"> - <children> - <Label fx:id="labelSecret11111" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="%settingstab.label.updates.current.version" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS"> - <font> - <Font name="System Bold" size="13.0" /> - </font> - </Label> - <Label fx:id="labelSecret111111" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" text="%settingstab.label.updates.latest.version" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS"> - <font> - <Font name="System Bold" size="13.0" /> - </font> - </Label> - </children> - </VBox> - <VBox prefHeight="200.0" prefWidth="100.0" spacing="5.0" HBox.hgrow="ALWAYS"> - <children> - <Label fx:id="labelCurrentVersion" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS"> - <font> - <Font size="13.0" /> - </font></Label> - <Label fx:id="labelLatestVersion" alignment="TOP_LEFT" contentDisplay="CENTER" maxHeight="1.7976931348623157E308" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS"> - <font> - <Font size="13.0" /> - </font></Label> - </children> - </VBox> - </children> - </HBox> - <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="%settings.tab.button.save"> - <font> - <Font name="System Bold" size="14.0" /> - </font> - <VBox.margin> - <Insets top="15.0" /> - </VBox.margin> - </Button> - <Region prefWidth="158.0" VBox.vgrow="ALWAYS" /> - </children> - </VBox> - </children> - </HBox> - </children> - <padding> - <Insets right="50.0" /> - </padding> - </VBox> - </children> -</AnchorPane> diff --git a/src/de/deadlocker8/budgetmasterserver/logic/database/Database.java b/src/de/deadlocker8/budgetmasterserver/logic/database/Database.java deleted file mode 100644 index 0fc7d225244e3de5db5b8e5dbf0b304f7e09246d..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmasterserver/logic/database/Database.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.deadlocker8.budgetmasterserver.logic.database; - -import java.util.ArrayList; - -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; - -public class Database -{ - private ArrayList<Category> categories; - private ArrayList<NormalPayment> normalPayments; - private ArrayList<RepeatingPayment> repeatingPayments; - - public Database() - { - - } - - public Database(ArrayList<Category> categories, ArrayList<NormalPayment> normalPayments, ArrayList<RepeatingPayment> repeatingPayments) - { - this.categories = categories; - this.normalPayments = normalPayments; - this.repeatingPayments = repeatingPayments; - } - - public ArrayList<Category> getCategories() - { - return categories; - } - - public ArrayList<NormalPayment> getNormalPayments() - { - return normalPayments; - } - - public ArrayList<RepeatingPayment> getRepeatingPayments() - { - return repeatingPayments; - } -} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseImporter.java b/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseImporter.java deleted file mode 100644 index db5da2244820c620fd5d3c97ff3b4c5bff692f43..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmasterserver/logic/database/DatabaseImporter.java +++ /dev/null @@ -1,107 +0,0 @@ -package de.deadlocker8.budgetmasterserver.logic.database; - -import java.util.ArrayList; -import java.util.Iterator; - -import de.deadlocker8.budgetmaster.logic.Category; -import de.deadlocker8.budgetmaster.logic.NormalPayment; -import de.deadlocker8.budgetmaster.logic.RepeatingPayment; - -public class DatabaseImporter -{ - private DatabaseHandler handler; - private ArrayList<Category> categories; - private ArrayList<NormalPayment> normalPayments; - private ArrayList<RepeatingPayment> repeatingPayments; - private ArrayList<NormalPayment> changedNormalPayments; - private ArrayList<RepeatingPayment> changedRepeatingPayments; - - public DatabaseImporter(DatabaseHandler handler) throws IllegalStateException - { - this.handler = handler; - } - - public void importDatabase(Database database) - { - this.categories = database.getCategories(); - this.normalPayments = database.getNormalPayments(); - this.repeatingPayments = database.getRepeatingPayments(); - this.changedNormalPayments = new ArrayList<>(); - this.changedRepeatingPayments = new ArrayList<>(); - - importAll(); - } - - private void importAll() - { - for(Category currentCategory : categories) - { - Category existingCategory = handler.getCategory(currentCategory.getName(), currentCategory.getColor()); - if(existingCategory == null) - { - handler.addCategory(currentCategory.getName(), currentCategory.getColor()); - int newID = handler.getLastInsertID(); - - updatePayments(currentCategory.getID(), newID); - } - else - { - updatePayments(currentCategory.getID(), existingCategory.getID()); - } - } - - //merge changed and remaining payments - normalPayments.addAll(changedNormalPayments); - repeatingPayments.addAll(changedRepeatingPayments); - - importNormalPayments(normalPayments); - importRepeatingPayments(repeatingPayments); - } - - private void updatePayments(int oldID, int newID) - { - //check normal payments for old category ID - Iterator<NormalPayment> iterator = normalPayments.iterator(); - while(iterator.hasNext()) - { - NormalPayment currentPayment = iterator.next(); - if(currentPayment.getCategoryID() == oldID) - { - currentPayment.setCategoryID(newID); - //remove payment from list to avoid overriding category ID again in the future - changedNormalPayments.add(currentPayment); - iterator.remove(); - } - } - - //check repeating payments for old category ID - Iterator<RepeatingPayment> iterator2 = repeatingPayments.iterator(); - while(iterator2.hasNext()) - { - RepeatingPayment currentPayment = iterator2.next(); - if(currentPayment.getCategoryID() == oldID) - { - currentPayment.setCategoryID(newID); - //remove payment from list to avoid overriding category ID again in the future - changedRepeatingPayments.add(currentPayment); - iterator2.remove(); - } - } - } - - private void importNormalPayments(ArrayList<NormalPayment> normalPayments) - { - for(NormalPayment currentPayment : normalPayments) - { - handler.addNormalPayment(currentPayment.getAmount(), currentPayment.getDate(), currentPayment.getCategoryID(), currentPayment.getName(), currentPayment.getDescription()); - } - } - - private void importRepeatingPayments(ArrayList<RepeatingPayment> repeatingPayments) - { - for(RepeatingPayment currentPayment : repeatingPayments) - { - handler.addRepeatingPayment(currentPayment.getAmount(), currentPayment.getDate(), currentPayment.getCategoryID(), currentPayment.getName(), currentPayment.getDescription(), currentPayment.getRepeatInterval(), currentPayment.getRepeatEndDate(), currentPayment.getRepeatMonthDay()); - } - } -} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/main/_de.properties b/src/de/deadlocker8/budgetmasterserver/main/_de.properties deleted file mode 100644 index 09cd0df883b038404cbaf06e332e895c5349c342..0000000000000000000000000000000000000000 --- a/src/de/deadlocker8/budgetmasterserver/main/_de.properties +++ /dev/null @@ -1,5 +0,0 @@ -app.name=BudgetMasterServer -version.code=9 -version.name=1.5.0 -version.date=31.08.17 -author=Robert Goldmann \ No newline at end of file diff --git a/tests/de/deadlocker8/budgetmaster/tests/resources/export.json b/tests/de/deadlocker8/budgetmaster/tests/resources/export.json deleted file mode 100644 index 209392219510b137d085d93f7db36fca6faf9754..0000000000000000000000000000000000000000 --- a/tests/de/deadlocker8/budgetmaster/tests/resources/export.json +++ /dev/null @@ -1 +0,0 @@ -{"categories":[{"ID":1,"name":"NONE","color":"#FFFFFF"},{"ID":2,"name":"Übertrag","color":"#FFFF00"},{"ID":3,"name":"Keine Kategorie","color":"#FFFFFF"},{"ID":4,"name":"123 Tü+?est Category","color":"#FF9500"}],"normalPayments":[{"ID":1,"amount":23,"date":"2017-06-02","categoryID":0,"name":"Test Normal","description":"Lorem Ipsum"}],"repeatingPayments":[{"repeatInterval":7,"repeatEndDate":"2017-06-30","repeatMonthDay":0,"ID":1,"amount":-10012,"date":"2017-06-01","categoryID":3,"name":"Test Repeating","description":"Lorem Ipsum"}]} \ No newline at end of file diff --git a/tests/de/deadlocker8/budgetmaster/tests/resources/import.json b/tests/de/deadlocker8/budgetmaster/tests/resources/import.json deleted file mode 100644 index 209392219510b137d085d93f7db36fca6faf9754..0000000000000000000000000000000000000000 --- a/tests/de/deadlocker8/budgetmaster/tests/resources/import.json +++ /dev/null @@ -1 +0,0 @@ -{"categories":[{"ID":1,"name":"NONE","color":"#FFFFFF"},{"ID":2,"name":"Übertrag","color":"#FFFF00"},{"ID":3,"name":"Keine Kategorie","color":"#FFFFFF"},{"ID":4,"name":"123 Tü+?est Category","color":"#FF9500"}],"normalPayments":[{"ID":1,"amount":23,"date":"2017-06-02","categoryID":0,"name":"Test Normal","description":"Lorem Ipsum"}],"repeatingPayments":[{"repeatInterval":7,"repeatEndDate":"2017-06-30","repeatMonthDay":0,"ID":1,"amount":-10012,"date":"2017-06-01","categoryID":3,"name":"Test Repeating","description":"Lorem Ipsum"}]} \ No newline at end of file