diff --git a/BudgetMasterClient/pom.xml b/BudgetMasterClient/pom.xml index 0fd1b201a4cdfd1bc86058a0aba07acd18e5f381..1d5b244e408e3d9a76a5227bf4ce0956747e3f30 100644 --- a/BudgetMasterClient/pom.xml +++ b/BudgetMasterClient/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>de.deadlocker8</groupId> <artifactId>BudgetMasterClient</artifactId> - <version>1.6.0</version> + <version>1.7.0</version> <name>BudgetMasterClient</name> <build> <plugins> @@ -15,6 +15,31 @@ <source>1.8</source> <target>1.8</target> </configuration> + </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> <!-- LAUNCH4J --> <plugin> @@ -48,31 +73,6 @@ </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> diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/RestartHandler.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/RestartHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..34db5c8f2d9fe417a95f4c5863e71acdb22471a2 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/RestartHandler.java @@ -0,0 +1,78 @@ +package de.deadlocker8.budgetmasterclient.ui; + +import java.util.Optional; + +import de.deadlocker8.budgetmaster.logic.utils.LanguageType; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.main.Main; +import de.deadlocker8.budgetmasterclient.ui.controller.Controller; +import de.deadlocker8.budgetmasterclient.ui.controller.SplashScreenController; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.DialogPane; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.image.Image; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.stage.Stage; +import tools.Localization; + +public class RestartHandler +{ + private Controller controller; + + public RestartHandler(Controller controller) + { + this.controller = controller; + } + + public void handleRestart(LanguageType previousLanguage) + { + controller.refresh(controller.getFilterSettings()); + controller.showNotification(Localization.getString(Strings.NOTIFICATION_SETTINGS_SAVE)); + + if(controller.getSettings().isAutoUpdateCheckEnabled()) + { + controller.checkForUpdates(false); + } + + //restart application if language has changed + if(controller.getSettings().getLanguage() != previousLanguage) + { + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle(Localization.getString(Strings.INFO_TITLE_LANGUAGE_CHANGED)); + alert.setHeaderText(""); + alert.setContentText(Localization.getString(Strings.INFO_TEXT_LANGUAGE_CHANGED)); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(controller.getIcon()); + + ButtonType buttonTypeOne = new ButtonType(Localization.getString(Strings.INFO_TEXT_LANGUAGE_CHANGED_RESTART_NOW)); + 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) + { + controller.getStage().close(); + + Localization.loadLanguage(controller.getSettings().getLanguage().getLocale()); + + Image icon = new Image("/de/deadlocker8/budgetmaster/icon.png"); + new SplashScreenController(Main.primaryStage, icon, false); + } + else + { + alert.close(); + } + } + } +} diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java index 7547dcc02c5057121f7ffd1f56c9d09061f40c5d..457d866f00d5fe55f6fd9b4f34073c1f6c170b99 100644 --- a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorView.java @@ -97,7 +97,7 @@ public class ColorView extends GridPane stage.setResizable(false); stage.initModality(Modality.APPLICATION_MODAL); stage.setScene(scene); - stage.getIcons().add(new Image("/de/deadlocker8/budgetmaster/resources/icon.png")); + stage.getIcons().add(new Image("/de/deadlocker8/budgetmaster/icon.png")); stage.show(); } catch(Exception e) diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandBundle.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandBundle.java new file mode 100644 index 0000000000000000000000000000000000000000..b200c8edeaae61c2e9dd13f99ad9c458a0e3dcae --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandBundle.java @@ -0,0 +1,53 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +import de.deadlocker8.budgetmasterclient.ui.controller.Controller; + +public class CommandBundle +{ + private CommandLineController controller; + private ResourceBundle languageBundle; + private Controller parentController; + + public CommandBundle(Controller parentController) + { + this.parentController = parentController; + } + + public CommandLineController getController() + { + return controller; + } + + public ResourceBundle getLanguageBundle() + { + return languageBundle; + } + + public String getString(String key) + { + return languageBundle.getString(key); + } + + public String getString(String key, Object... args) + { + return MessageFormat.format(languageBundle.getString(key), args); + } + + public void setController(CommandLineController controller) + { + this.controller = controller; + } + + public void setLanguageBundle(ResourceBundle languageBundle) + { + this.languageBundle = languageBundle; + } + + public Controller getParentController() + { + return parentController; + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandLine.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandLine.java new file mode 100644 index 0000000000000000000000000000000000000000..eba15f5f9083421d932d6010f8fad5e35d81648b --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandLine.java @@ -0,0 +1,126 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.ResourceBundle; + +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; + +public class CommandLine +{ + private Stage owner; + private Stage newStage; + private Image icon; + private ResourceBundle languageBundle; + public ArrayList<HistoryEntry> globalHistory = new ArrayList<>(); + public int lastShownCommand = 1; + public ArrayList<HistoryEntry> history = new ArrayList<>(); + private final String promptText = ">>>"; + private CommandBundle bundle; + + public CommandLine(Stage owner, Image icon, ResourceBundle languageBundle, CommandBundle commandBundle) + { + this.owner = owner; + this.icon = icon; + this.languageBundle = languageBundle; + this.bundle = commandBundle; + } + + public Stage getOwner() + { + return owner; + } + + public Stage getStage() + { + return newStage; + } + + public Image getIcon() + { + return icon; + } + + public int getLastShwonCommand() + { + return lastShownCommand; + } + + public String getPromptText() + { + return promptText; + } + + public ResourceBundle getLanguageBundle() + { + return languageBundle; + } + + public CommandBundle getBundle() + { + return bundle; + } + + public void showCommandLine(String title, double width, double height, double minWidth, double minHeight, double positionX, double positionY, boolean dark) throws IOException + { + if(newStage != null) + { + if(newStage.isShowing()) + { + return; + } + } + + FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/commandLine/CommandLineGUI.fxml")); + + Parent root = (Parent)fxmlLoader.load(); + newStage = new Stage(); + newStage.setScene(new Scene(root, width, height)); + newStage.setResizable(true); + newStage.setTitle(title); + newStage.initOwner(owner); + + newStage.setMinWidth(minWidth); + newStage.setMinHeight(minHeight); + if(positionX != -1) + { + newStage.setX(positionX); + } + if(positionY != -1) + { + newStage.setY(positionY); + } + + if(dark) + { + root.setStyle("-fx-base: rgb(50, 50, 50); -fx-background: rgb(50, 50, 50); -fx-control-inner-background: rgb(10, 10, 10);"); + } + + if(icon != null) + { + newStage.getIcons().add(icon); + } + + CommandLineController newController = fxmlLoader.getController(); + newController.init(this); + + newStage.initModality(Modality.NONE); + newStage.show(); + } + + public void closeCommandLine() + { + if(newStage != null) + { + if(newStage.isShowing()) + { + newStage.close(); + } + } + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandLineController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandLineController.java new file mode 100644 index 0000000000000000000000000000000000000000..c84fec6b9943921975d76060a00b124dd0eb2da3 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/CommandLineController.java @@ -0,0 +1,246 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine; + +import java.util.ArrayList; +import java.util.Comparator; + +import de.deadlocker8.budgetmasterclient.ui.commandLine.commands.Command; +import de.deadlocker8.budgetmasterclient.ui.commandLine.commands.PossibleCommands; +import javafx.application.Platform; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; + +public class CommandLineController +{ + @FXML private TextArea textareaHistory; + @FXML private TextField textfieldInput; + + private CommandLine commandLine; + + public void init(CommandLine commandLine) + { + this.commandLine = commandLine; + + commandLine.getBundle().setController(this); + commandLine.getBundle().setLanguageBundle(commandLine.getLanguageBundle()); + + textareaHistory.setEditable(false); + textareaHistory.setWrapText(true); + + textfieldInput.setOnKeyPressed(new EventHandler<KeyEvent>() + { + @Override + public void handle(KeyEvent event) + { + if(event.getCode().equals(KeyCode.ENTER)) + { + parse(); + } + + if(event.getCode().equals(KeyCode.UP)) + { + showLastCommand(); + } + + if(event.getCode().equals(KeyCode.ESCAPE)) + { + clearConsole(); + } + + if(event.getCode().equals(KeyCode.TAB)) + { + autocomplete(); + event.consume(); + } + } + }); + + printPrompt(); + } + + public void printPrompt() + { + setConsoleText(); + clearConsole(); + } + + public void print(String message) + { + commandLine.history.add(new HistoryEntry(HistoryType.MESSAGE, message)); + setConsoleText(); + printPrompt(); + } + + public void clearHistoryLog() + { + textareaHistory.setText(""); + } + + public void clearHistory() + { + commandLine.history = new ArrayList<>(); + } + + public void clearConsole() + { + textfieldInput.setText(""); + textfieldInput.requestFocus(); + } + + private void setConsoleText() + { + clearHistoryLog(); + + StringBuilder sb = new StringBuilder(); + boolean printedLastEntry = false; + for(int i = 0; i < commandLine.history.size(); i++) + { + HistoryEntry currentEntry = commandLine.history.get(i); + if(currentEntry.getType().equals(HistoryType.COMMAND)) + { + if(printedLastEntry) + { + sb.append("\n"); + } + sb.append(commandLine.getPromptText()); + sb.append(" "); + sb.append(currentEntry.getText()); + printedLastEntry = true; + } + else + { + if(i != 0) + { + sb.append("\n"); + } + sb.append(currentEntry.getText()); + printedLastEntry = true; + } + } + + textareaHistory.setText(sb.toString()); + textareaHistory.positionCaret(sb.toString().length()); + } + + private boolean executeCommand(String[] command) + { + for(Command cmd : PossibleCommands.possibleCommands) + { + if(cmd.getKeyword().equals(command[0])) + { + cmd.execute(command, commandLine.getBundle()); + return true; + } + } + return false; + } + + private void parse() + { + String input = textfieldInput.getText().replace("\n", ""); + + if(input.equals("")) + { + printPrompt(); + return; + } + + commandLine.globalHistory.add(new HistoryEntry(HistoryType.COMMAND, input)); + commandLine.history.add(new HistoryEntry(HistoryType.COMMAND, input)); + commandLine.lastShownCommand = - 1; + + String[] command = input.split(" "); + if( ! executeCommand(command)) + { + print(commandLine.getLanguageBundle().getString("error.unknown.command")); + } + else + { + printPrompt(); + } + } + + private void showLastCommand() + { + if(commandLine.globalHistory.size() > 0) + { + if(commandLine.lastShownCommand <= 0) + { + textfieldInput.setText(commandLine.globalHistory.get(commandLine.globalHistory.size() - 1).getText()); + commandLine.lastShownCommand = commandLine.globalHistory.size() - 1; + } + else + { + textfieldInput.setText(commandLine.globalHistory.get(commandLine.lastShownCommand - 1).getText()); + commandLine.lastShownCommand--; + } + + Platform.runLater(()-> + { + textfieldInput.positionCaret(textfieldInput.getText().length()); + }); + } + } + + private void autocomplete() + { + String input = textfieldInput.getText().replace("\n", ""); + + if(input.equals("")) + { + return; + } + + ArrayList<Command> commands = PossibleCommands.possibleCommands; + + //filter possible commands + ArrayList<Command> filteredCommands = new ArrayList<>(); + for(Command currentCommand : commands) + { + if(currentCommand.getKeyword().startsWith(input)) + { + filteredCommands.add(currentCommand); + } + } + + //sort commands alphabetically + filteredCommands.sort(new Comparator<Command>() + { + @Override + public int compare(Command o1, Command o2) + { + return o1.keyword.compareTo(o2.keyword); + } + }); + + if(filteredCommands.size() == 1) + { + textfieldInput.setText(filteredCommands.get(0).getKeyword()); + } + else + { + StringBuilder sb = new StringBuilder(); + sb.append(">>> Possible commands for \"" + input + "\":\n"); + for(int i = 0; i < filteredCommands.size(); i++) + { + sb.append(filteredCommands.get(i).keyword); + if(i != (filteredCommands.size()-1)) + { + sb.append("\n"); + } + } + + print(sb.toString()); + + textfieldInput.setText(input); + } + + Platform.runLater(()-> + { + textfieldInput.positionCaret(textfieldInput.getText().length()); + }); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/HistoryEntry.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/HistoryEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..3454e2876e9d6b4d8841d7e947659e24b176f30a --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/HistoryEntry.java @@ -0,0 +1,28 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine; + +public class HistoryEntry +{ + private HistoryType type; + private String text; + + public HistoryEntry(HistoryType type, String text) + { + this.type = type; + this.text = text; + } + + public HistoryType getType() + { + return type; + } + + public String getText() + { + return text; + } + + public String toString() + { + return "HistoryEntry [type=" + type + ", text=" + text + "]"; + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/HistoryType.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/HistoryType.java new file mode 100644 index 0000000000000000000000000000000000000000..3b6f3c87866f1bb39268eaca24d58b8f1f918c15 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/HistoryType.java @@ -0,0 +1,6 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine; + +public enum HistoryType +{ + COMMAND, MESSAGE +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/Command.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/Command.java new file mode 100644 index 0000000000000000000000000000000000000000..c2ad67b0cee0bbfd210b6e4ac508bb7df4834c74 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/Command.java @@ -0,0 +1,39 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; + +public abstract class Command +{ + public String keyword; + public int numberOfParams; + public String helptText; + + public String getKeyword() + { + return keyword; + } + + public int getNumberOfParams() + { + return numberOfParams; + } + + public String getHelpText() + { + return keyword; + } + + public boolean isValid(String[] command) + { + if((command.length - 1) == numberOfParams) + { + return true; + } + else + { + return false; + } + } + + public abstract void execute(String[] command, CommandBundle bundle); +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandClear.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandClear.java new file mode 100644 index 0000000000000000000000000000000000000000..f9aa8f8aac586091e1f14fd9ad8c97895844b6e9 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandClear.java @@ -0,0 +1,31 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; + +/** + * Clears the history log and console + */ +public class CommandClear extends Command +{ + public CommandClear() + { + super.keyword = "clear"; + super.numberOfParams = 0; + super.helptText = "help.clear"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + bundle.getController().clearHistory(); + bundle.getController().clearHistoryLog(); + bundle.getController().clearConsole(); + bundle.getController().printPrompt(); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandDelete.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandDelete.java new file mode 100644 index 0000000000000000000000000000000000000000..2417ac83430932ed1d978f2d8aee683f132e5755 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandDelete.java @@ -0,0 +1,50 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; +import logger.Logger; + +public class CommandDelete extends Command +{ + public CommandDelete() + { + super.keyword = "delete"; + super.numberOfParams = 1; + super.helptText = "help.delete"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + if(command[1].equals("log-client")) + { + Logger.clearLogFile(); + bundle.getController().print(bundle.getString("delete.success", "client logfile")); + return; + } + + if(command[1].equals("log-server")) + { + try + { + ServerConnection connection = new ServerConnection(bundle.getParentController().getSettings()); + connection.deleteLog(); + bundle.getController().print(bundle.getString("delete.success", "server logfile")); + } + catch(Exception e) + { + bundle.getController().print(bundle.getString("delete.error.connection")); + } + + return; + } + + bundle.getController().print(bundle.getString("error.invalid.parameter", command[1], keyword)); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandHelp.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandHelp.java new file mode 100644 index 0000000000000000000000000000000000000000..88680e5ede1108b2613c683dbec53c23809bb1ca --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandHelp.java @@ -0,0 +1,47 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import java.util.MissingResourceException; + +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; + +/** + * prints help for given command + */ +public class CommandHelp extends Command +{ + public CommandHelp() + { + super(); + super.keyword = "help"; + super.numberOfParams = 1; + super.helptText = "help.help"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + for(Command cmd : PossibleCommands.possibleCommands) + { + if(cmd.getKeyword().equals(command[1])) + { + try + { + bundle.getController().print(bundle.getString("help." + command[1])); + } + catch(MissingResourceException e) + { + bundle.getController().print(bundle.getString("error.general")); + } + return; + } + } + + bundle.getController().print(bundle.getString("error.no.help")); + } +} diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandInfo.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..aca29599f04216fdd9b009162e608ef516247582 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandInfo.java @@ -0,0 +1,67 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection; +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerInformation; +import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; +import tools.Localization; + +/** + * prints help for given command + */ +public class CommandInfo extends Command +{ + public CommandInfo() + { + super(); + super.keyword = "info"; + super.numberOfParams = 1; + super.helptText = "help.info"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + if(command[1].equals("client")) + { + String text = Localization.getString(Strings.APP_NAME) + + " v" + Localization.getString(Strings.VERSION_NAME) + + " (" + Localization.getString(Strings.VERSION_CODE) + + ") from " + Localization.getString(Strings.VERSION_DATE); + bundle.getController().print(text); + return; + } + + if(command[1].equals("server")) + { + try + { + ServerConnection connection = new ServerConnection(bundle.getParentController().getSettings()); + ServerInformation serverInfo = connection.getServerInfo(); + VersionInformation versionInfo = serverInfo.getVersionInfo(); + + String text = "BudgetMasterServer v" + versionInfo.getVersionName() + " (" + versionInfo.getVersionCode() + ") from " + versionInfo.getDate() + "\n" + + "Listening on port " + serverInfo.getServerPort() + "\n" + + "Connected with user \"" + serverInfo.getDatabaseUsername() + "\" to database \"" + serverInfo.getDatabaseName() + "@" + serverInfo.getDatabaseUrl() + "\"\n" + + "Keystore location is: \"" + serverInfo.getKeystorePath() + "\""; + + bundle.getController().print(text); + } + catch(Exception e) + { + bundle.getController().print(bundle.getString("delete.error.connection")); + } + + return; + } + + bundle.getController().print(bundle.getString("error.invalid.parameter", command[1], keyword)); + } +} diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandList.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandList.java new file mode 100644 index 0000000000000000000000000000000000000000..6ea40040cc6bfd976210c28791c20187dab56608 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandList.java @@ -0,0 +1,55 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import java.util.ArrayList; +import java.util.Comparator; + +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; + +/** + * Lists all available commands + */ +public class CommandList extends Command +{ + public CommandList() + { + super(); + super.keyword = "list"; + super.numberOfParams = 0; + super.helptText = "help.list"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + //sort possible commands alphabetically + ArrayList<Command> commands = PossibleCommands.possibleCommands; + commands.sort(new Comparator<Command>() + { + @Override + public int compare(Command o1, Command o2) + { + return o1.keyword.compareTo(o2.keyword); + } + }); + + //loop through all possible commands and print keyword + StringBuilder sb = new StringBuilder(); + sb.append("All possible commands:\n"); + for(int i = 0; i < commands.size(); i++) + { + sb.append(commands.get(i).keyword); + if(i != (commands.size()-1)) + { + sb.append("\n"); + } + } + + bundle.getController().print(sb.toString()); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandOpen.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandOpen.java new file mode 100644 index 0000000000000000000000000000000000000000..bf4ef69b82c290420b338382f55694e99119dcc3 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandOpen.java @@ -0,0 +1,48 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; + +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; +import tools.Localization; +import tools.PathUtils; + +public class CommandOpen extends Command +{ + public CommandOpen() + { + super.keyword = "open"; + super.numberOfParams = 1; + super.helptText = "help.open"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + if(!command[1].equals("settings")) + { + bundle.getController().print(bundle.getString("error.invalid.parameter", command[1], keyword)); + return; + } + + try + { + File folder = Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER)).toFile(); + Desktop.getDesktop().open(folder); + bundle.getController().print(bundle.getString("open.success", folder.getAbsolutePath())); + } + catch(IOException e) + { + bundle.getController().print(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandShortcuts.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandShortcuts.java new file mode 100644 index 0000000000000000000000000000000000000000..bb99c3e1ed20a1a3627cf092e89a1dedec9b3bde --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandShortcuts.java @@ -0,0 +1,23 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; + +/** + * Lists all available Shortcuts + */ +public class CommandShortcuts extends Command +{ + public CommandShortcuts() + { + super.keyword = "shortcuts"; + super.numberOfParams = 0; + super.helptText = "help.shortcuts"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + bundle.getController().print("Available Shortcuts:"); + bundle.getController().print(bundle.getString("info.shortcuts")); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandSwitch.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandSwitch.java new file mode 100644 index 0000000000000000000000000000000000000000..5748203222e2325ba641368c294137d59f200ade --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/CommandSwitch.java @@ -0,0 +1,70 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import de.deadlocker8.budgetmaster.logic.utils.FileHelper; +import de.deadlocker8.budgetmaster.logic.utils.LanguageType; +import de.deadlocker8.budgetmaster.logic.utils.Strings; +import de.deadlocker8.budgetmasterclient.ui.RestartHandler; +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandBundle; +import tools.Localization; +import tools.PathUtils; + +public class CommandSwitch extends Command +{ + public CommandSwitch() + { + super.keyword = "switch"; + super.numberOfParams = 0; + super.helptText = "help.switch"; + } + + @Override + public void execute(String[] command, CommandBundle bundle) + { + if(!isValid(command)) + { + bundle.getController().print(bundle.getString("error.invalid.arguments")); + return; + } + + Path currentSettingsFile = Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER) + "/settings.json"); + Path secondSettingsFile = Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER) + "/_settings.json"); + + if(secondSettingsFile.toFile().exists()) + { + try + { + Path temp = Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER) + "/__settings.json"); + Files.move(currentSettingsFile, temp); + Files.move(secondSettingsFile, currentSettingsFile); + Files.move(temp, secondSettingsFile); + } + catch(IOException e) + { + bundle.getController().print(bundle.getString("switch.error")); + } + } + else + { + bundle.getController().print(bundle.getString("switch.new")); + try + { + Files.copy(currentSettingsFile, secondSettingsFile); + } + catch(IOException e) + { + bundle.getController().print(bundle.getString("switch.error")); + } + } + + LanguageType previousLanguage = bundle.getParentController().getSettings().getLanguage(); + bundle.getParentController().setSettings(FileHelper.loadSettings()); + RestartHandler restartHandler = new RestartHandler(bundle.getParentController()); + restartHandler.handleRestart(previousLanguage); + bundle.getController().print(bundle.getString("switch.success")); + } +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/PossibleCommands.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/PossibleCommands.java new file mode 100644 index 0000000000000000000000000000000000000000..0ecfd5ea340a49795b9cc2b5f8cdc1fae07505d4 --- /dev/null +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/commandLine/commands/PossibleCommands.java @@ -0,0 +1,18 @@ +package de.deadlocker8.budgetmasterclient.ui.commandLine.commands; + +import java.util.ArrayList; +import java.util.Arrays; + +public class PossibleCommands +{ + public static final ArrayList<Command> possibleCommands = new ArrayList<>(Arrays.asList( + new CommandList(), + new CommandHelp(), + new CommandClear(), + new CommandShortcuts(), + new CommandOpen(), + new CommandDelete(), + new CommandInfo(), + new CommandSwitch() + )); +} \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java index 2dbef46aa9cf9d86e7ce49edd5f4bc4b52c886af..c6a43ee97742ff7e297b68284d8e8d513195c31f 100644 --- a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/Controller.java @@ -1,10 +1,17 @@ package de.deadlocker8.budgetmasterclient.ui.controller; +import java.awt.Desktop; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Locale; import java.util.Optional; +import java.util.ResourceBundle; import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; import de.deadlocker8.budgetmaster.logic.FilterSettings; import de.deadlocker8.budgetmaster.logic.Settings; @@ -22,6 +29,8 @@ 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.ui.commandLine.CommandBundle; +import de.deadlocker8.budgetmasterclient.ui.commandLine.CommandLine; import de.deadlocker8.budgetmasterclient.utils.UIHelpers; import fontAwesome.FontIconType; import javafx.animation.FadeTransition; @@ -29,19 +38,31 @@ import javafx.animation.SequentialTransition; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.geometry.Insets; +import javafx.geometry.Pos; import javafx.scene.Parent; 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.Hyperlink; import javafx.scene.control.Label; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.VBox; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; import javafx.stage.Stage; import javafx.util.Duration; import logger.Logger; @@ -84,13 +105,15 @@ public class Controller extends BaseController private Updater updater; private Payment selectedPayment; private SearchPreferences searchPreferences; + private CommandLine cmd; private boolean alertIsShowing = false; - private static final String DATE_FORMAT = "MMMM yyyy"; + private static DateTimeFormatter DATE_FORMAT; public Controller(Settings settings) { this.settings = settings; + DATE_FORMAT = DateTimeFormat.forPattern("MMMM yyyy").withLocale(this.settings.getLanguage().getLocale()); load("/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml", Localization.getBundle()); getStage().show(); } @@ -123,10 +146,38 @@ public class Controller extends BaseController paymentHandler = new PaymentHandler(); updater = new Updater(); + CommandBundle commandBundle = new CommandBundle(this); + cmd = new CommandLine(getStage(), icon, ResourceBundle.getBundle("de/deadlocker8/budgetmaster/ui/commandLine/", Locale.ENGLISH), commandBundle); + if(settings.isAutoUpdateCheckEnabled()) { checkForUpdates(false); } + + final KeyCombination keyCombinationSearch = new KeyCodeCombination(KeyCode.F, KeyCombination.CONTROL_DOWN); + + getStage().getScene().setOnKeyReleased((event)->{ + if(event.getCode().toString().equals(Localization.getString(Strings.SHORTCUT_DEV_CONSOLE))) + { + try + { + cmd.showCommandLine("Dev Console", 400, 250, 400, 200, -1, -1, true); + } + catch(IOException e) + { + Logger.error("Error opening dev console"); + Logger.error(e); + } + } + else if(keyCombinationSearch.match(event)) + { + if(!tabPayments.isDisabled()) + { + tabPane.getSelectionModel().select(tabPayments); + paymentController.search(); + } + } + }); initUI(); } @@ -305,7 +356,7 @@ public class Controller extends BaseController alertIsShowing = true; Platform.runLater(() -> { toggleAllTabsExceptSettings(true); - tabPane.getSelectionModel().select(tabSettings); + tabPane.getSelectionModel().select(tabSettings); alertIsShowing = true; Alert alert = new Alert(AlertType.ERROR); @@ -416,8 +467,7 @@ public class Controller extends BaseController { try { - boolean updateAvailable = updater.isUpdateAvailable(Integer.parseInt(Localization.getString(Strings.VERSION_CODE))); - String changes = updater.getChangelog(updater.getLatestVersion().getVersionCode()); + boolean updateAvailable = updater.isUpdateAvailable(Integer.parseInt(Localization.getString(Strings.VERSION_CODE))); if(!updateAvailable) { @@ -429,64 +479,7 @@ public class Controller extends BaseController } Platform.runLater(()->{ - Alert alert = new Alert(AlertType.INFORMATION); - alert.setTitle(Localization.getString(Strings.INFO_TITLE_UPDATE_AVAILABLE)); - alert.setHeaderText(""); - alert.setContentText(Localization.getString(Strings.INFO_TEXT_UPDATE_AVAILABLE, - updater.getLatestVersion().getVersionName(), - changes)); - Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); - dialogStage.getIcons().add(icon); - - ButtonType buttonTypeOne = new ButtonType(Localization.getString(Strings.INFO_TEXT_UPDATE_AVAILABLE_NOW)); - 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 = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_UPDATE), getStage(), icon); - - Worker.runLater(() -> { - try - { - updater.downloadLatestVersion(); - Platform.runLater(() -> { - if(modalStage != null) - { - modalStage.close(); - } - }); - } - catch(Exception ex) - { - Logger.error(ex); - Platform.runLater(() -> { - if(modalStage != null) - { - modalStage.close(); - AlertGenerator.showAlert(AlertType.ERROR, - Localization.getString(Strings.TITLE_ERROR), - "", - Localization.getString(Strings.ERROR_UPDATER_DOWNLOAD_LATEST_VERSION, ex.getMessage()), - icon, getStage(), null, true); - } - }); - } - }); - } - else - { - alert.close(); - } + showUpdateAlert(); }); } catch(Exception e) @@ -499,22 +492,246 @@ public class Controller extends BaseController icon, null, null, true); } } + + private void showUpdateAlert() + { + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle(Localization.getString(Strings.INFO_TITLE_UPDATE_AVAILABLE)); + alert.setHeaderText(""); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + + Hyperlink linkText = new Hyperlink(Localization.getString(Strings.INFO_TEXT_UPDATE_AVAILABLE_SHOW_CHANGES)); + linkText.setOnAction((event)->{ + if(Desktop.isDesktopSupported()) + { + try + { + Desktop.getDesktop().browse(new URI(Localization.getString(Strings.ROADMAP_URL))); + } + catch(IOException | URISyntaxException e) + { + Logger.error(e); + AlertGenerator.showAlert(AlertType.ERROR, + Localization.getString(Strings.TITLE_ERROR), + "", + Localization.getString(Strings.ERROR_OPEN_BROWSER), + icon, getStage(), null, false); + } + } + }); + + Hyperlink detailedMilestones = new Hyperlink(Localization.getString(Strings.INFO_TEXT_UPDATE_AVAILABLE_SHOW_CHANGES_DETAILED)); + detailedMilestones.setOnAction((event)->{ + if(Desktop.isDesktopSupported()) + { + try + { + Desktop.getDesktop().browse(new URI(Localization.getString(Strings.GITHUB_URL))); + } + catch(IOException | URISyntaxException e) + { + Logger.error(e); + AlertGenerator.showAlert(AlertType.ERROR, + Localization.getString(Strings.TITLE_ERROR), + "", + Localization.getString(Strings.ERROR_OPEN_BROWSER), + icon, getStage(), null, false); + } + } + }); + + TextFlow textFlow = new TextFlow( + new Text(Localization.getString(Strings.INFO_TEXT_UPDATE_AVAILABLE, + updater.getLatestVersion().getVersionName())), + linkText, + new Text("\n\n"), + detailedMilestones + ); + + alert.getDialogPane().setContent(textFlow); + + ButtonType buttonTypeOne = new ButtonType(Localization.getString(Strings.INFO_TEXT_UPDATE_AVAILABLE_NOW)); + 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 = UIHelpers.showModal(Localization.getString(Strings.TITLE_MODAL), Localization.getString(Strings.LOAD_UPDATE), getStage(), icon); + + Worker.runLater(() -> { + try + { + updater.downloadLatestVersion(); + Platform.runLater(() -> { + if(modalStage != null) + { + modalStage.close(); + } + }); + } + catch(Exception ex) + { + Logger.error(ex); + Platform.runLater(() -> { + if(modalStage != null) + { + modalStage.close(); + AlertGenerator.showAlert(AlertType.ERROR, + Localization.getString(Strings.TITLE_ERROR), + "", + Localization.getString(Strings.ERROR_UPDATER_DOWNLOAD_LATEST_VERSION, ex.getMessage()), + icon, getStage(), null, true); + } + }); + } + }); + } + else + { + alert.close(); + } + } + + private Label getLabelForAboutColumns(String text, boolean bold) + { + Label label = new Label(text); + if(bold) + { + label.setStyle("-fx-font-size: 14; -fx-font-weight: bold;"); + } + else + { + label.setStyle("-fx-font-size: 14;"); + } + return label; + } public void about() { - ArrayList<String> creditLines = new ArrayList<>(); - creditLines.add(Localization.getString(Strings.CREDITS)); - - AlertGenerator.showAboutAlertWithCredits(Localization.getString(Strings.APP_NAME), - Localization.getString(Strings.VERSION_NAME), - Localization.getString(Strings.VERSION_CODE), - Localization.getString(Strings.VERSION_DATE), - Localization.getString(Strings.AUTHOR), - creditLines, - icon, - getStage(), - null, - false); + Alert alert = new Alert(AlertType.NONE); + alert.setTitle(Localization.getString(Strings.ABOUT, Localization.getString(Strings.APP_NAME))); + alert.setHeaderText(""); + Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); + dialogStage.getIcons().add(icon); + + Hyperlink roadmapLink = new Hyperlink(Localization.getString(Strings.ABOUT_ROADMAP_LINK)); + roadmapLink.setFont(new Font(14)); + roadmapLink.setPadding(new Insets(0)); + roadmapLink.setOnAction((event)->{ + if(Desktop.isDesktopSupported()) + { + try + { + Desktop.getDesktop().browse(new URI(Localization.getString(Strings.ROADMAP_URL))); + } + catch(IOException | URISyntaxException e) + { + Logger.error(e); + AlertGenerator.showAlert(AlertType.ERROR, + Localization.getString(Strings.TITLE_ERROR), + "", + Localization.getString(Strings.ERROR_OPEN_BROWSER), + icon, getStage(), null, false); + } + } + }); + + Hyperlink githubLink = new Hyperlink(Localization.getString(Strings.GITHUB_URL)); + githubLink.setFont(new Font(14)); + githubLink.setPadding(new Insets(0)); + githubLink.setOnAction((event)->{ + if(Desktop.isDesktopSupported()) + { + try + { + Desktop.getDesktop().browse(new URI(Localization.getString(Strings.GITHUB_URL))); + } + catch(IOException | URISyntaxException e) + { + Logger.error(e); + AlertGenerator.showAlert(AlertType.ERROR, + Localization.getString(Strings.TITLE_ERROR), + "", + Localization.getString(Strings.ERROR_OPEN_BROWSER), + icon, getStage(), null, false); + } + } + }); + + VBox vbox = new VBox(); + vbox.setSpacing(10); + HBox hboxLogo = new HBox(); + hboxLogo.setSpacing(25); + ImageView imageViewLogo = new ImageView(icon); + imageViewLogo.setFitHeight(75); + imageViewLogo.setFitWidth(75); + hboxLogo.getChildren().add(imageViewLogo); + + Label labelName = new Label(Localization.getString(Strings.ABOUT, Localization.getString(Strings.APP_NAME))); + labelName.setStyle("-fx-font-weight: bold; -fx-font-size: 22;"); + labelName.setMaxWidth(Double.MAX_VALUE); + hboxLogo.getChildren().add(labelName); + HBox.setHgrow(labelName, Priority.ALWAYS); + hboxLogo.setAlignment(Pos.CENTER); + vbox.getChildren().add(hboxLogo); + + HBox hboxColumns = new HBox(); + VBox vboxLeft = new VBox(); + vboxLeft.setSpacing(7); + VBox vboxRight = new VBox(); + vboxRight.setSpacing(7); + + vboxLeft.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.ABOUT_VERSION), true)); + vboxLeft.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.ABOUT_DATE), true)); + vboxLeft.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.ABOUT_AUTHOR), true)); + vboxLeft.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.ABOUT_ROADMAP), true)); + Label labelSourceCode = getLabelForAboutColumns(Localization.getString(Strings.ABOUT_SOURCECODE), true); + vboxLeft.getChildren().add(labelSourceCode); + VBox.setMargin(labelSourceCode, new Insets(2, 0, 0, 0)); + vboxLeft.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.ABOUT_CREDITS), true)); + + vboxRight.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.VERSION_NAME) + " (" + Localization.getString(Strings.VERSION_CODE) + ")", false)); + vboxRight.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.VERSION_DATE), false)); + vboxRight.getChildren().add(getLabelForAboutColumns(Localization.getString(Strings.AUTHOR), false)); + vboxRight.getChildren().add(roadmapLink); + vboxRight.getChildren().add(githubLink); + + VBox vboxCredits = new VBox(); + for(String line : Localization.getString(Strings.CREDITS).split("\n")) + { + vboxCredits.getChildren().add(getLabelForAboutColumns(line, false)); + } + vboxRight.getChildren().add(vboxCredits); + + vboxLeft.setMinWidth(100); + hboxColumns.getChildren().addAll(vboxLeft, vboxRight); + HBox.setHgrow(vboxLeft, Priority.ALWAYS); + HBox.setHgrow(vboxRight, Priority.ALWAYS); + + vbox.getChildren().add(hboxColumns); + alert.getDialogPane().setContent(vbox); + + alert.getButtonTypes().setAll(new ButtonType(Localization.getString(Strings.OK))); + + 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(); + } + })); + + alert.showAndWait(); } public void refresh(FilterSettings newFilterSettings) diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java index 523b1672a4b0a793fe2c5800ad83cde6b27604ea..13a76e2a41f715b79fe167147b8b61e8ddc82527 100644 --- a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java +++ b/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/controller/SettingsController.java @@ -15,7 +15,7 @@ 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.budgetmasterclient.main.Main; +import de.deadlocker8.budgetmasterclient.ui.RestartHandler; import de.deadlocker8.budgetmasterclient.ui.Styleable; import de.deadlocker8.budgetmasterclient.ui.cells.LanguageCell; import de.deadlocker8.budgetmasterclient.utils.UIHelpers; @@ -36,7 +36,6 @@ 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; @@ -306,52 +305,9 @@ public class SettingsController implements Styleable textFieldClientSecret.setText("******"); textFieldSecret.setText("******"); - controller.refresh(controller.getFilterSettings()); - controller.showNotification(Localization.getString(Strings.NOTIFICATION_SETTINGS_SAVE)); - - if(controller.getSettings().isAutoUpdateCheckEnabled()) - { - controller.checkForUpdates(false); - refreshLabelsUpdate(); - } - - //restart application if language has changed - if(controller.getSettings().getLanguage() != previousLanguage) - { - Alert alert = new Alert(AlertType.INFORMATION); - alert.setTitle(Localization.getString(Strings.INFO_TITLE_LANGUAGE_CHANGED)); - alert.setHeaderText(""); - alert.setContentText(Localization.getString(Strings.INFO_TEXT_LANGUAGE_CHANGED)); - Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); - dialogStage.getIcons().add(controller.getIcon()); - - ButtonType buttonTypeOne = new ButtonType(Localization.getString(Strings.INFO_TEXT_LANGUAGE_CHANGED_RESTART_NOW)); - 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) - { - controller.getStage().close(); - - Localization.loadLanguage(controller.getSettings().getLanguage().getLocale()); - - Image icon = new Image("/de/deadlocker8/budgetmaster/icon.png"); - new SplashScreenController(Main.primaryStage, icon, false); - } - else - { - alert.close(); - } - } + RestartHandler restartHandler = new RestartHandler(controller); + restartHandler.handleRestart(previousLanguage); + refreshLabelsUpdate(); } public void exportDB() diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties index 5a19c4b0a6dccc44aa584547dba8e3691020d332..3c9a5ea1f9bb7715a0db34755aebf2f0c3935d5d 100644 --- a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_de.properties @@ -1,12 +1,14 @@ # DEFAULT app.name=BudgetMaster -version.code=10 -version.name=1.6.0 -version.date=03.10.17 +version.code=11 +version.name=1.7.0 +version.date=26.10.17 author=Robert Goldmann credits=L�nderflaggen von Freepik auf https://www.flaticon.com\nVerwendete Schriftarten: OpenSans folder=Deadlocker/BudgetMaster +roadmap.url=https://deadlocker.thecodelabs.de/roadmap/php/index.php?id=1 +github.url=https://github.com/deadlocker8/BudgetMaster # TITLE @@ -64,6 +66,7 @@ currency.placeholder=z.B. \u20AC, CHF, $ trusted.hosts.placeholder=z.B. localhost undefined=unbekannt tagfield.placeholder=Neuen Tag hier eingeben +shortcut.dev.console=F12 # REPORT report.position=Nr. @@ -84,6 +87,10 @@ report.footer.center=Seite {0} report.repeating.yes=Ja report.repeating.no=Nein report.initial.filename=BudgetMaster Monatsbericht - {0}_{1}.pdf +report.budget=Budget +report.incomes=Einnahmen: +report.payments=Ausgaben: +report.budget.rest=Restbudget: # MONTH month.january=Januar @@ -142,7 +149,9 @@ info.text.language.changed= info.text.language.changed.restart.now=Jetzt neustarten info.text.language.changed.restart.later=Sp�ter neustarten info.title.update.available=Update verf�gbar -info.text.update.available=Ein Update ist verf�gbar.\nNeue Version: {0}\n\n�nderungen:\n{1} +info.text.update.available=Ein Update ist verf�gbar.\nNeue Version: {0}\n\n +info.text.update.available.show.changes=�nderungen anzeigen (�ffnet Webbrowser) +info.text.update.available.show.changes.detailed=(detaillierte Infos auf GitHub.com) 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 @@ -198,6 +207,7 @@ error.database.import.wrong.file=Die angegebene Datei enth error.password.save=Beim Speichern des Passworts ist ein Fehler aufgetreten. error.updater.get.latest.version=Beim �berpr�fen auf Updates ist ein Fehler aufgetreten. Informationen zu neuen Versionen konnten nicht abgerufen werden. Versuche es sp�ter noch einmal. error.updater.download.latest.version=Beim Herunterladen des Updates ist ein Fehler aufgetreten.\n\n{0} +error.open.browser=Beim �ffnen des Standardwebbrowsers ist ein Fehler aufgetreten. # UI categorytab.button.category.new=\ Neue Kategorie @@ -309,3 +319,13 @@ splashscreen.label.password=Passwort: datepicker.label.month=Monat: datepicker.label.year=Jahr: datepicker.button.confirm=�bernehmen + +# ABOUT +about=�ber {0} +about.roadmap.link=Roadmap �ffnen +about.version=Version: +about.date=Datum: +about.author=Author: +about.roadmap=Roadmap: +about.sourcecode=Quellcode: +about.credits=Credits: diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties index 0214f27fde602c718e1bec53b1d896c7d19c875c..f0cb6b14861e1c236799a5a2785d171633ad8f60 100644 --- a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/languages/_en.properties @@ -1,12 +1,14 @@ # DEFAULT app.name=BudgetMaster -version.code=10 -version.name=1.6.0 -version.date=03.10.17 +version.code=11 +version.name=1.7.0 +version.date=26.10.17 author=Robert Goldmann credits=Flags by Freepik on https://www.flaticon.com\nFonts used: OpenSans folder=Deadlocker/BudgetMaster +roadmap.url=https://deadlocker.thecodelabs.de/roadmap/php/index.php?id=2 +github.url=https://github.com/deadlocker8/BudgetMaster # TITLE @@ -64,6 +66,7 @@ currency.placeholder=e.g. \u20AC, CHF, $ trusted.hosts.placeholder=e.g. localhost undefined=undefined tagfield.placeholder=Enter new Tag here +shortcut.dev.console=F12 # REPORT report.position=No. @@ -84,6 +87,10 @@ report.footer.center=Page {0} report.repeating.yes=Yes report.repeating.no=No report.initial.filename=BudgetMaster Month Report - {0}_{1}.pdf +report.budget=Budget +report.incomes=Incomes: +report.payments=Payments: +report.budget.rest=Remaining Budget: # MONTH month.january=January @@ -142,7 +149,9 @@ info.text.language.changed=Changes to the language will only take effect after a info.text.language.changed.restart.now=Restart Now info.text.language.changed.restart.later=Restart Later info.title.update.available=Update available -info.text.update.available=An update is available.\nNew version: {0}\n\nChanges:\n{1} +info.text.update.available=An update is available.\nNew version: {0}\n\n +info.text.update.available.show.changes=Show Changes (opens web browsers) +info.text.update.available.show.changes.detailed=(detailed information on GitHub.com) 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} @@ -198,6 +207,7 @@ error.database.import.wrong.file=The specified file does not contain a valid Bud error.password.save=An error occurred while saving the password. error.updater.get.latest.version=An error occurred while checking for updates. Information about latest versions could not be retrieved. Please try again later. error.updater.download.latest.version=An error occurred while downloading the update.\n\n{0} +error.open.browser=An error occurred while opening the default web browser. # UI categorytab.button.category.new=\ New Category @@ -308,4 +318,14 @@ splashscreen.label.password=Password: datepicker.label.month=Month: datepicker.label.year=Year: -datepicker.button.confirm=Apply \ No newline at end of file +datepicker.button.confirm=Apply + +# ABOUT +about=About {0} +about.roadmap.link=Open Roadmap +about.version=Version: +about.date=Date: +about.author=Author: +about.roadmap=Roadmap: +about.sourcecode=Sourcecode: +about.credits=Credits: \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml similarity index 98% rename from BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickGUI.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml index 7b0f539542397085a05f4febd10d01875ca5c498..8acf7b57b2d276d2a73a6bdd1e02c7ce44b5d470 100644 --- a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/colorPick/ColorPickGUI.fxml +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml @@ -10,7 +10,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.colorPick.ColorPickController"> +<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.colorPick.ColorPickController"> <children> <HBox layoutX="273.0" layoutY="81.0" spacing="30.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/commandLine/CommandLineGUI.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/commandLine/CommandLineGUI.fxml new file mode 100644 index 0000000000000000000000000000000000000000..539c299ed11944f92733487994da9ec0674875c7 --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/commandLine/CommandLineGUI.fxml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.TextArea?> +<?import javafx.scene.control.TextField?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.VBox?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmasterclient.ui.commandLine.CommandLineController"> + <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> + <TextArea fx:id="textareaHistory" prefHeight="508.0" prefWidth="572.0" VBox.vgrow="ALWAYS" /> + <TextField fx:id="textfieldInput" prefHeight="46.0" prefWidth="572.0"> + <VBox.margin> + <Insets top="14.0" /> + </VBox.margin> + </TextField> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/commandLine/_en.properties b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/commandLine/_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..7aee4c0633193d4d979808892e7883975091243c --- /dev/null +++ b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/commandLine/_en.properties @@ -0,0 +1,31 @@ +help.list=list - lists all possible commands +help.help=help - shows help for given command\nSYNTAX: help [COMMAND] +help.clear=clear - clears the history +help.shortcuts=shortcuts - lists all available shortcuts + +error.general=An error occurred. +error.unknown.command=Unknown command. Use \"list\" for a list of possible commands. +error.invalid.arguments=Invalid arguments. Use \"help commandname\" for help. +error.invalid.parameter=Invalid parameter {0}.\nUse \"help {1}\" for a detailed list. +error.no.help=Unknown command as parameter. Can't display help. Use \"list\" for a list of possible commands. + +info.shortcuts=[ENTER] - execute command\n[UP] - scroll through recently used commands\n[ESC] - clear input\n[TAB] - autocomplete + +# open +help.open=open - opens files and folders\nSYNTAX: open [PARAMETER]\npossible parameters: settings +open.success=Successfully opened folder {0} + +# delete +help.delete=delete - deletes files\nSYNTAX: delete [PARAMETER]\npossible parameters:\nlog-client\nlog-server +delete.success=Successfully deleted {0} +delete.error.connection=An error occurred while establishing the server connection + +# info +help.info=info - information about client and server \nSYNTAX: info [PARAMETER]\npossible parameters:\client\nserver +info.error.connection=An error occurred while establishing the server connection + +# switch +help.switch=switch - switch betwwen two client settings +switch.new=Second settings file is not present. Copying current settings file... +switch.success=Successfully switched settings +switch.error=An error occurred while switching the settings \ No newline at end of file diff --git a/BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlert.fxml b/BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/customAlert/CustomAlert.fxml similarity index 100% rename from BudgetMasterClient/src/main/java/de/deadlocker8/budgetmasterclient/ui/customAlert/CustomAlert.fxml rename to BudgetMasterClient/src/main/resources/de/deadlocker8/budgetmaster/ui/customAlert/CustomAlert.fxml diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java index 38f7d53bd7e60d29ec468b769f46e3d5e5e685ad..780c74199c5d76709ea2667640cf462e138574b5 100644 --- a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java @@ -167,11 +167,11 @@ public class ReportGenerator 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(new Paragraph(Localization.getString(Strings.REPORT_BUDGET), headerFont)); document.add(Chunk.NEWLINE); - document.add(new Paragraph("Einnahmen: " + Helpers.getCurrencyString(budget.getIncomeSum(), currency), fontGreen)); - document.add(new Paragraph("Ausgaben: " + Helpers.getCurrencyString(budget.getPaymentSum(), currency), fontRed)); - document.add(new Paragraph("Restbudget: " + Helpers.getCurrencyString(budget.getIncomeSum() + budget.getPaymentSum(), currency), fontBlack)); + document.add(new Paragraph(Localization.getString(Strings.REPORT_INCOMES) + Helpers.getCurrencyString(budget.getIncomeSum(), currency), fontGreen)); + document.add(new Paragraph(Localization.getString(Strings.REPORT_PAYMENTS) + Helpers.getCurrencyString(budget.getPaymentSum(), currency), fontRed)); + document.add(new Paragraph(Localization.getString(Strings.REPORT_BUDGET_REST) + Helpers.getCurrencyString(budget.getIncomeSum() + budget.getPaymentSum(), currency), fontBlack)); document.add(Chunk.NEWLINE); } diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java index 86191f4c14ed4a065a880a7bc5f38934abd8f4df..cd04ca5d70863a407fd6ca139a189ea4eb86570d 100644 --- a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java @@ -561,8 +561,26 @@ public class ServerConnection } /* - * VERSION + * INFORMATION */ + public ServerInformation getServerInfo() throws Exception + { + URL url = new URL(settings.getUrl() + "/info?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, ServerInformation.class); + } + else + { + throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); + } + } + public VersionInformation getServerVersion() throws Exception { URL url = new URL(settings.getUrl() + "/version?secret=" + Helpers.getURLEncodedString(settings.getSecret())); @@ -580,4 +598,22 @@ public class ServerConnection throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode())); } } + + public void deleteLog() throws Exception + { + URL url = new URL(settings.getUrl() + "/log?secret=" + Helpers.getURLEncodedString(settings.getSecret())); + 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())); + } + } } \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerInformation.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerInformation.java new file mode 100644 index 0000000000000000000000000000000000000000..d4172b446694ea58eb4b269f57903837d87f17bc --- /dev/null +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/serverconnection/ServerInformation.java @@ -0,0 +1,84 @@ +package de.deadlocker8.budgetmaster.logic.serverconnection; + +import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; + +public class ServerInformation +{ + private String databaseUrl; + private String databaseName; + private String databaseUsername; + private int serverPort; + private String keystorePath; + private VersionInformation versionInfo; + + public ServerInformation() + { + + } + + public String getDatabaseUrl() + { + return databaseUrl; + } + + public void setDatabaseUrl(String databaseUrl) + { + this.databaseUrl = databaseUrl; + } + + public String getDatabaseName() + { + return databaseName; + } + + public void setDatabaseName(String databaseName) + { + this.databaseName = databaseName; + } + + public String getDatabaseUsername() + { + return databaseUsername; + } + + public void setDatabaseUsername(String databaseUsername) + { + this.databaseUsername = databaseUsername; + } + + public int getServerPort() + { + return serverPort; + } + + public void setServerPort(int serverPort) + { + this.serverPort = serverPort; + } + + public String getKeystorePath() + { + return keystorePath; + } + + public void setKeystorePath(String keystorePath) + { + this.keystorePath = keystorePath; + } + + public VersionInformation getVersionInfo() + { + return versionInfo; + } + + public void setVersionInfo(VersionInformation versionInfo) + { + this.versionInfo = versionInfo; + } + + @Override + public String toString() + { + return "ServerInfo [databaseUrl=" + databaseUrl + ", databaseName=" + databaseName + ", databaseUsername=" + databaseUsername + ", serverPort=" + serverPort + ", keystorePath=" + keystorePath + ", versionInfo=" + versionInfo + "]"; + } +} \ No newline at end of file diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java index 9b6fc104146616f9425f090353dd0ca9f8ba9389..1eb50a9c751204c7d61a535d62c9ce3f7fad978a 100644 --- a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/updater/Updater.java @@ -13,9 +13,6 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Properties; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - import de.deadlocker8.budgetmaster.logic.utils.Strings; import logger.Logger; import nativeWindows.NativeLauncher; @@ -28,7 +25,6 @@ public class Updater { private VersionInformation latestVersion; private static final String LATEST_VERSION_INFO_URL = "https://raw.githubusercontent.com/deadlocker8/BudgetMaster/master/src/de/deadlocker8/budgetmaster/resources/languages/_de.properties"; - private static final String CHANGELOG_URL = "https://raw.githubusercontent.com/deadlocker8/BudgetMaster/master/src/de/deadlocker8/budgetmaster/resources/changelog.json"; private static final String BUILD_FOLDER = "https://github.com/deadlocker8/BudgetMaster/raw/master/build/"; public Updater() @@ -65,35 +61,7 @@ public class Updater public VersionInformation getLatestVersion() { return latestVersion; - } - - public JsonObject getChangelogFromURL() throws IOException - { - URL webseite = new URL(CHANGELOG_URL); - URLConnection connection = webseite.openConnection(); - - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String line; - StringBuilder data = new StringBuilder(); - while ((line = br.readLine()) != null) - { - data.append(line); - } - - JsonParser parser = new JsonParser(); - return parser.parse(data.toString()).getAsJsonObject(); - } - - public String getChangelog(int versionCode) throws Exception - { - JsonObject changelogJSON = getChangelogFromURL(); - - if(changelogJSON != null) - { - return changelogJSON.get(String.valueOf(versionCode)).getAsString(); - } - return null; - } + } private void downloadLatestUpdater(OSType osType) throws IOException { @@ -119,16 +87,11 @@ public class Updater { File currentExecutable = getCurrentExecutableName(); String currentFileName = currentExecutable.getName(); - String fileEnding; //check if BudgetMaster is running from executable //no updating procedure if running from source - if(currentFileName.contains(".")) - { - fileEnding = currentExecutable.getAbsolutePath().substring(currentExecutable.getAbsolutePath().indexOf("."), currentExecutable.getAbsolutePath().length()); - } - else - { + if(!currentFileName.contains(".")) + { Logger.debug("Update procedure will be skipped because BudgetMaster is running from source"); return; } @@ -141,7 +104,7 @@ public class Updater //download into temp directory and file Path target; - if(fileEnding.equalsIgnoreCase("exe")) + if(currentFileName.endsWith(".exe")) { target = Paths.get(PathUtils.getOSindependentPath() + Localization.getString(Strings.FOLDER) + "/update_BudgetMaster.exe"); download(BUILD_FOLDER + "BudgetMaster.exe", target); diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java index 53539a1a10de04426648db4730dc03188c29d650..9f031cf910a597139a59065ca9a8956a98b938f2 100644 --- a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Helpers.java @@ -16,6 +16,7 @@ public class Helpers { public static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.00"); public static final String SALT = "ny9/Y+G|WrJ,82|oIYQQ X %i-sq#4,uA-qKPtwFPnw+s(k2`rV)^-a1|t{D3Z>S"; + public static final String ROADMAP_URL = "https://deadlocker.thecodelabs.de/roadmap/php/index.php?id=1"; public static String getCurrencyString(int amount, String currency) { diff --git a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java index 9ab0bee5897f92c683e6615f4775343b82e6ed58..ebbd78bc29c9c42ba37fcc655f86c5bb7bad19fd 100644 --- a/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java +++ b/BudgetMasterCore/src/main/java/de/deadlocker8/budgetmaster/logic/utils/Strings.java @@ -9,7 +9,9 @@ public class Strings public static final String VERSION_DATE = "version.date"; public static final String AUTHOR = "author"; public static final String CREDITS = "credits"; - public static final String FOLDER = "folder"; + public static final String FOLDER = "folder"; + public static final String ROADMAP_URL = "roadmap.url"; + public static final String GITHUB_URL = "github.url"; //TITLE public static final String TITLE_INCOMES = "title.incomes"; @@ -67,6 +69,7 @@ public class Strings public static final String VERSION = "version"; public static final String UNDEFINED = "undefined"; public static final String TAGFIELD_PLACEHOLDER = "tagfield.placeholder"; + public static final String SHORTCUT_DEV_CONSOLE = "shortcut.dev.console"; //REPORT public static final String REPORT_POSITION = "report.position"; @@ -87,6 +90,10 @@ public class Strings public static final String REPORT_REPEATING_YES ="report.repeating.yes"; public static final String REPORT_REPEATING_NO ="report.repeating.no"; public static final String REPORT_INITIAL_FILENAME ="report.initial.filename"; + public static final String REPORT_BUDGET = "report.budget"; + public static final String REPORT_INCOMES = "report.incomes"; + public static final String REPORT_PAYMENTS = "report.payments"; + public static final String REPORT_BUDGET_REST = "report.budget.rest"; //MONTH_NAMES public static final String MONTH_JANUARY ="month.january"; @@ -146,6 +153,8 @@ public class Strings public static final String INFO_TEXT_LANGUAGE_CHANGED_RESTART_LATER = "info.text.language.changed.restart.later"; public static final String INFO_TITLE_UPDATE_AVAILABLE = "info.title.update.available"; public static final String INFO_TEXT_UPDATE_AVAILABLE = "info.text.update.available"; + public static final String INFO_TEXT_UPDATE_AVAILABLE_SHOW_CHANGES = "info.text.update.available.show.changes"; + public static final String INFO_TEXT_UPDATE_AVAILABLE_SHOW_CHANGES_DETAILED = "info.text.update.available.show.changes.detailed"; public static final String INFO_TEXT_UPDATE_AVAILABLE_NOW = "info.text.update.available.now"; 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"; @@ -201,4 +210,15 @@ public class Strings public static final String ERROR_PASSWORD_SAVE = "error.password.save"; public static final String ERROR_UPDATER_GET_LATEST_VERSION = "error.updater.get.latest.version"; public static final String ERROR_UPDATER_DOWNLOAD_LATEST_VERSION = "error.updater.download.latest.version"; + public static final String ERROR_OPEN_BROWSER = "error.open.browser"; + + //ABOUT + public static final String ABOUT = "about"; + public static final String ABOUT_ROADMAP_LINK = "about.roadmap.link"; + public static final String ABOUT_VERSION = "about.version"; + public static final String ABOUT_DATE = "about.date"; + public static final String ABOUT_AUTHOR = "about.author"; + public static final String ABOUT_ROADMAP = "about.roadmap"; + public static final String ABOUT_SOURCECODE = "about.sourcecode"; + public static final String ABOUT_CREDITS = "about.credits"; } \ No newline at end of file diff --git a/BudgetMasterServer/pom.xml b/BudgetMasterServer/pom.xml index f0aff38da07c472479abd04afc342b0dc32962e4..0a022441b5bd9151224aec81871cea2c5bf2e5e9 100644 --- a/BudgetMasterServer/pom.xml +++ b/BudgetMasterServer/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>de.deadlocker8</groupId> <artifactId>BudgetMasterServer</artifactId> - <version>1.6.0</version> + <version>1.7.0</version> <name>BudgetMasterServer</name> <build> <plugins> diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java index 72558d5dab04ffb6195f48f450b3c5af3602fe3d..2e4d55abf7d2113c3ada2fe859f6d97ac484f2ae 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/SparkServer.java @@ -33,6 +33,9 @@ import de.deadlocker8.budgetmasterserver.server.charts.MonthInOutSum; import de.deadlocker8.budgetmasterserver.server.database.DatabaseDelete; import de.deadlocker8.budgetmasterserver.server.database.DatabaseExport; import de.deadlocker8.budgetmasterserver.server.database.DatabaseImport; +import de.deadlocker8.budgetmasterserver.server.info.InformationGet; +import de.deadlocker8.budgetmasterserver.server.info.VersionGet; +import de.deadlocker8.budgetmasterserver.server.log.LogDelete; import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentAdd; import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentDelete; import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentGet; @@ -58,7 +61,6 @@ 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; import spark.Spark; import spark.route.RouteOverview; @@ -166,7 +168,9 @@ public class SparkServer post("/database", new DatabaseImport(handler, tagHandler, gson)); delete("/database", new DatabaseDelete(handler, settings)); + get("/info", new InformationGet(gson, versionInfo, settings)); get("/version", new VersionGet(gson, versionInfo)); + delete("/log", new LogDelete()); after((request, response) -> { new RepeatingPaymentUpdater(handler).updateRepeatingPayments(DateTime.now()); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/info/InformationGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/info/InformationGet.java new file mode 100644 index 0000000000000000000000000000000000000000..199b19a2a283a7bce75bb9352d6af8d62489b679 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/info/InformationGet.java @@ -0,0 +1,38 @@ +package de.deadlocker8.budgetmasterserver.server.info; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.serverconnection.ServerInformation; +import de.deadlocker8.budgetmaster.logic.updater.VersionInformation; +import de.deadlocker8.budgetmasterserver.logic.Settings; +import spark.Request; +import spark.Response; +import spark.Route; + +public class InformationGet implements Route +{ + private Gson gson; + private VersionInformation versionInfo; + private Settings settings; + + public InformationGet(Gson gson, VersionInformation versionInfo, Settings settings) + { + this.gson = gson; + this.versionInfo = versionInfo; + this.settings = settings; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + ServerInformation serverInfo = new ServerInformation(); + serverInfo.setDatabaseUrl(settings.getDatabaseUrl()); + serverInfo.setDatabaseName(settings.getDatabaseName()); + serverInfo.setDatabaseUsername(settings.getDatabaseUsername()); + serverInfo.setServerPort(settings.getServerPort()); + serverInfo.setKeystorePath(settings.getKeystorePath()); + serverInfo.setVersionInfo(versionInfo); + + return gson.toJson(serverInfo); + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/info/VersionGet.java similarity index 86% rename from BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java rename to BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/info/VersionGet.java index dfbb05e481e274b158baf6c4e5e0371ae4cd7313..eb77c8cbc3f574f2818093c2289864e174fa62bf 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/version/VersionGet.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/info/VersionGet.java @@ -1,4 +1,4 @@ -package de.deadlocker8.budgetmasterserver.server.version; +package de.deadlocker8.budgetmasterserver.server.info; import com.google.gson.Gson; @@ -14,7 +14,7 @@ public class VersionGet implements Route public VersionGet(Gson gson, VersionInformation versionInfo) { - this.gson=gson; + this.gson = gson; this.versionInfo = versionInfo; } diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/log/LogDelete.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/log/LogDelete.java new file mode 100644 index 0000000000000000000000000000000000000000..366973c54cdcafb79a0cff444bd926da7ba45f28 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmasterserver/server/log/LogDelete.java @@ -0,0 +1,32 @@ +package de.deadlocker8.budgetmasterserver.server.log; + +import static spark.Spark.halt; + +import logger.Logger; +import spark.Request; +import spark.Response; +import spark.Route; + +public class LogDelete implements Route +{ + public LogDelete() + { + + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + try + { + Logger.clearLogFile(); + return ""; + } + catch(IllegalStateException ex) + { + halt(500, "Internal Server Error"); + } + + return ""; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties b/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties index 8de2a69fbfed7d822d9ebdf32a042ce1c98893ef..5cb7f01cc467be6ffc386715960412e28a2df9c3 100644 --- a/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties +++ b/BudgetMasterServer/src/main/resources/de/deadlocker8/budgetmasterserver/_en.properties @@ -1,7 +1,7 @@ app.name=BudgetMasterServer -version.code=10 -version.name=1.6.0 -version.date=03.10.17 +version.code=11 +version.name=1.7.0 +version.date=26.10.17 author=Robert Goldmann category.none=No Category diff --git a/build/BudgetMaster.exe b/build/BudgetMaster.exe index 8f3cc2cdfbe17ffc4462c0c8b75a4baacbef2f80..bf47c71db09e77c36e79047a082a567414c081b6 100644 Binary files a/build/BudgetMaster.exe and b/build/BudgetMaster.exe differ diff --git a/build/BudgetMasterClient.jar b/build/BudgetMasterClient.jar index 2cc65b521323311ffafd9c130757d90797b2a6f4..8a48c9429ec34d87b4670b1a46a6f423d3e16db5 100644 Binary files a/build/BudgetMasterClient.jar and b/build/BudgetMasterClient.jar differ diff --git a/build/BudgetMasterServer.jar b/build/BudgetMasterServer.jar index da8339bbc21ff0df81bd6c6cb7b22e811b2daa14..a66a4e59a296d091fdfa41123331d072273c6a6d 100644 Binary files a/build/BudgetMasterServer.jar and b/build/BudgetMasterServer.jar differ