From a3f7445c481ac0f23109a0ee5ff617b8b47d0b63 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Fri, 24 Nov 2017 13:05:12 +0100 Subject: [PATCH] Fixed #19 - allow user to choose database save directory --- src/charts/ChartGUIController.java | 4 +- src/core/Settings.java | 20 ++- src/core/Utils.java | 2 + src/userInterface/EditController.java | 6 +- src/userInterface/InsertTimeController.java | 6 +- .../ProjektFensterController.java | 6 +- .../UserInterfaceController.java | 149 +++++++++++------- src/userInterface/userInterface.fxml | 18 ++- 8 files changed, 145 insertions(+), 66 deletions(-) diff --git a/src/charts/ChartGUIController.java b/src/charts/ChartGUIController.java index b69a73f..0395293 100644 --- a/src/charts/ChartGUIController.java +++ b/src/charts/ChartGUIController.java @@ -6,6 +6,7 @@ import java.util.HashSet; import core.LogObject; import core.SQL; +import core.Settings; import core.Utils; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -42,12 +43,13 @@ public class ChartGUIController private SummaryGenerator summaryGenerator; private BarChartGenerator barChartGenertator; - public void init(String savePath, Stage stage, Image icon) + public void init(Settings settings, Stage stage, Image icon) { try { this.stage = stage; this.icon = icon; + String savePath = settings.getSavePath() + "/" + Utils.DATABASE_NAME; sql = new SQL(savePath); ArrayList<String> projects = new ArrayList<String>(); diff --git a/src/core/Settings.java b/src/core/Settings.java index 91f8fe0..fd6a151 100644 --- a/src/core/Settings.java +++ b/src/core/Settings.java @@ -2,20 +2,32 @@ package core; public class Settings { + private String savePath; private String lastProject; private String lastTask; - + public Settings() { - + } - public Settings(String lastProject, String lastTask) + public Settings(String savePath, String lastProject, String lastTask) { + this.savePath = savePath; this.lastProject = lastProject; this.lastTask = lastTask; } + public String getSavePath() + { + return savePath; + } + + public void setSavePath(String savePath) + { + this.savePath = savePath; + } + public String getLastProject() { return lastProject; @@ -39,6 +51,6 @@ public class Settings @Override public String toString() { - return "Settings [lastProject=" + lastProject + ", lastTask=" + lastTask + "]"; + return "Settings [savePath=" + savePath + ", lastProject=" + lastProject + ", lastTask=" + lastTask + "]"; } } \ No newline at end of file diff --git a/src/core/Utils.java b/src/core/Utils.java index a43ac18..a040493 100644 --- a/src/core/Utils.java +++ b/src/core/Utils.java @@ -20,6 +20,8 @@ public class Utils private static final ResourceBundle bundle = ResourceBundle.getBundle("userInterface/", Locale.GERMANY); private static final String[] AVAILABLE_MONTH_NAMES = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}; + + public static final String DATABASE_NAME = "SmartTime.db"; public static String getMonthName(int monthNumberOneIndexed) { diff --git a/src/userInterface/EditController.java b/src/userInterface/EditController.java index 6a5c64f..27ad81b 100644 --- a/src/userInterface/EditController.java +++ b/src/userInterface/EditController.java @@ -6,6 +6,8 @@ import java.util.Optional; import core.LogObject; import core.SQL; +import core.Settings; +import core.Utils; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; @@ -30,7 +32,7 @@ public class EditController private Image icon; private LogObject object; - public void init(UserInterfaceController controller, Stage stage, String savePath, Image icon, LogObject object) + public void init(UserInterfaceController controller, Stage stage, Settings settings, Image icon, LogObject object) { this.controller = controller; this.stage = stage; @@ -39,7 +41,7 @@ public class EditController ArrayList<String> objects = new ArrayList<String>(); - SQL sql = new SQL(savePath); + SQL sql = new SQL(settings.getSavePath() + "/" + Utils.DATABASE_NAME); try { objects = sql.getProjectNames(); diff --git a/src/userInterface/InsertTimeController.java b/src/userInterface/InsertTimeController.java index 9dcd9b3..0142eb6 100644 --- a/src/userInterface/InsertTimeController.java +++ b/src/userInterface/InsertTimeController.java @@ -14,6 +14,8 @@ import java.util.Date; import core.LogObject; import core.SQL; +import core.Settings; +import core.Utils; import fontAwesome.FontIcon; import fontAwesome.FontIconType; import javafx.beans.value.ChangeListener; @@ -54,9 +56,9 @@ public class InsertTimeController private String savePath; private Image icon; - public void init(Stage stage, UserInterfaceController controller, String savePath, Image icon) + public void init(Stage stage, UserInterfaceController controller, Settings settings, Image icon) { - this.savePath = savePath; + this.savePath = settings.getSavePath() + "/" + Utils.DATABASE_NAME; this.stage = stage; this.controller = controller; this.icon = icon; diff --git a/src/userInterface/ProjektFensterController.java b/src/userInterface/ProjektFensterController.java index 57c93b8..ca02d1d 100644 --- a/src/userInterface/ProjektFensterController.java +++ b/src/userInterface/ProjektFensterController.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.Collections; import core.SQL; +import core.Settings; +import core.Utils; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; @@ -31,7 +33,7 @@ public class ProjektFensterController private UserInterfaceController controller; private Image icon; - public void init(UserInterfaceController controller, Stage stage, String savePath, Image icon) + public void init(UserInterfaceController controller, Stage stage, Settings settings, Image icon) { this.controller = controller; this.stage = stage; @@ -43,7 +45,7 @@ public class ProjektFensterController ArrayList<String> objects = new ArrayList<String>(); - SQL sql = new SQL(savePath); + SQL sql = new SQL(settings.getSavePath() + "/" + Utils.DATABASE_NAME); try { objects = sql.getProjectNames(); diff --git a/src/userInterface/UserInterfaceController.java b/src/userInterface/UserInterfaceController.java index 597767f..f2d38f8 100644 --- a/src/userInterface/UserInterfaceController.java +++ b/src/userInterface/UserInterfaceController.java @@ -55,6 +55,7 @@ import javafx.scene.image.Image; import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; +import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.stage.Modality; import javafx.stage.Stage; @@ -65,7 +66,6 @@ import tools.AlertGenerator; import tools.ConvertTo; import tools.PathUtils; - public class UserInterfaceController { @FXML private Label aktuellesProjektAusgabe; @@ -79,6 +79,7 @@ public class UserInterfaceController @FXML private TableView<LogObject> table; @FXML private ScrollPane scrollPane; @FXML private Label labelSeparator; + @FXML private Label labelSavePath; private Stage stage; private Timer timer; @@ -89,8 +90,8 @@ public class UserInterfaceController private long startTimestamp; private long endTimestamp; private int longestProject; - private ArrayList<LogObject> logObjects = new ArrayList<LogObject>(); - private final String savePath = PathUtils.getOSindependentPath() + "/Deadlocker/SmartTime/save.db"; + private ArrayList<LogObject> logObjects = new ArrayList<LogObject>(); + private final String DEFAULT_SAVE_PATH = PathUtils.getOSindependentPath() + "/Deadlocker/SmartTime/"; private SQL sql; private Stage waitingStage = new Stage(); private Image icon; @@ -98,50 +99,47 @@ public class UserInterfaceController private Settings settings; public void init(Stage stage) - { - this.stage = stage; - - labelSeparator.setStyle("-fx-background-color: #cdc6c6; -fx-font-size: 0.7"); - - PathUtils.checkFolder(new File(new File(savePath).getParent())); - icon = new Image("/userInterface/icon.png"); + { + this.stage = stage; + labelSeparator.setStyle("-fx-background-color: #cdc6c6; -fx-font-size: 0.7"); + PathUtils.checkFolder(new File(DEFAULT_SAVE_PATH)); + icon = new Image("/userInterface/icon.png"); accordion.setExpandedPane(gesamtesLog); - projektExistiertFlag = false; + labelTime.setText("0 h 0 min 0 sek"); - labelTime.setText("0 h 0 min 0 sek"); - + loadSettings(); createLogView(); loadAll(); + + setLabelSavePath(); // verwaltet den Start/Stopp-Button startButton.setOnAction(event -> { - if(projektExistiertFlag == true) - + { if(startButton.isSelected()) - { + { startButton.setText("Stopp"); startClock(); timer = new Timer(labelTime); timer.start(); } else - { + { startButton.setText("Start"); timer.stop(); endClock(); loadAll(); } + } else { AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Kein Projekt ausgewählt.", icon, stage, null, false); startButton.setSelected(false); } }); - - loadSettings(); } /** @@ -153,14 +151,14 @@ public class UserInterfaceController // Prüft, ob die Stoppuhr noch läuft if(isTimerRunning()) { - AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Stoppuhr läuft noch!", icon, stage, null, false); + AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Stoppuhr läuft noch!", icon, stage, null, false); } else { stage.close(); } } - + public boolean isTimerRunning() { return timer != null && timer.isRunning(); @@ -171,6 +169,14 @@ public class UserInterfaceController aktuellesProjektAusgabe.setText(project); aktuellerTaskAusgabe.setText(task); } + + private void setLabelSavePath() + { + String savePathForLabel = settings.getSavePath() + "/" + Utils.DATABASE_NAME; + savePathForLabel = savePathForLabel.replace("\\", "/"); + savePathForLabel = savePathForLabel.replaceAll("//", "/"); + labelSavePath.setText(savePathForLabel); + } public void openProjectGUI(ActionEvent e) { @@ -188,7 +194,7 @@ public class UserInterfaceController newStage.getIcons().add(icon); ProjektFensterController pfc = (ProjektFensterController)fxmlLoader.getController(); - pfc.init(this, newStage, savePath, icon); + pfc.init(this, newStage, settings, icon); newStage.setResizable(false); newStage.initModality(Modality.APPLICATION_MODAL); @@ -278,7 +284,7 @@ public class UserInterfaceController private void loadFromDB() { - sql = new SQL(savePath); + sql = new SQL(settings.getSavePath() + "/" + Utils.DATABASE_NAME); try { logObjects = sql.getLogObjects(); @@ -308,7 +314,7 @@ public class UserInterfaceController } } } - + private void updateTableView() { table.getItems().clear(); @@ -317,9 +323,9 @@ public class UserInterfaceController } private void createLogView() - { + { table.getItems().clear(); - table.getColumns().clear(); + table.getColumns().clear(); TableColumn<LogObject, String> dates = new TableColumn<>("Datum"); dates.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<LogObject, String>, ObservableValue<String>>() @@ -416,13 +422,13 @@ public class UserInterfaceController { // clicking on text part row = (TableRow<LogObject>)node.getParent(); - } - + } + editEntry(row.getItem()); } } }); - + table.prefWidthProperty().bind(scrollPane.widthProperty().subtract(2)); table.prefHeightProperty().bind(scrollPane.heightProperty().subtract(2)); } @@ -440,7 +446,7 @@ public class UserInterfaceController newStage.setScene(scene); newStage.setTitle("Diagramme"); ChartGUIController controller = (ChartGUIController)fxmlLoader.getController(); - controller.init(savePath, newStage, icon); + controller.init(settings, newStage, icon); newStage.getIcons().add(icon); newStage.initOwner(stage); @@ -460,7 +466,7 @@ public class UserInterfaceController { loadFromDB(); updateTableView(); - createTreeView(); + createTreeView(); } public void newProject(String project, String task) @@ -485,7 +491,7 @@ public class UserInterfaceController endTimestamp = System.currentTimeMillis(); log.setDuration(endTimestamp - startTimestamp); - SQL sql = new SQL(savePath); + SQL sql = new SQL(settings.getSavePath() + "/" + Utils.DATABASE_NAME); try { sql.insert(log); @@ -522,7 +528,7 @@ public class UserInterfaceController newStage.setTitle("Zeit nachträglich einfügen"); InsertTimeController controller = (InsertTimeController)fxmlLoader.getController(); - controller.init(newStage, this, savePath, icon); + controller.init(newStage, this, settings, icon); newStage.getIcons().add(icon); newStage.initOwner(stage); @@ -552,7 +558,7 @@ public class UserInterfaceController Platform.runLater(() -> { showWaitingDialog("Importiere...", "Bitte warten..."); }); - Importer importer = new Importer(savePath, stage, icon); + Importer importer = new Importer(settings.getSavePath() + "/" + Utils.DATABASE_NAME, stage, icon); importer.importFromSmartTime(file); Platform.runLater(() -> { closeWaitingDialog(); @@ -580,7 +586,7 @@ public class UserInterfaceController Platform.runLater(() -> { showWaitingDialog("Importiere...", "Bitte warten..."); }); - Importer importer = new Importer(savePath, stage, icon); + Importer importer = new Importer(settings.getSavePath() + "/" + Utils.DATABASE_NAME, stage, icon); importer.importFromDB(file); Platform.runLater(() -> { closeWaitingDialog(); @@ -608,7 +614,7 @@ public class UserInterfaceController Platform.runLater(() -> { showWaitingDialog("Importiere...", "Bitte warten..."); }); - Importer importer = new Importer(savePath, stage, icon); + Importer importer = new Importer(settings.getSavePath() + "/" + Utils.DATABASE_NAME, stage, icon); importer.importFromJSON(file); Platform.runLater(() -> { closeWaitingDialog(); @@ -631,13 +637,13 @@ public class UserInterfaceController { try { - Files.copy(new File(savePath).toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(new File(settings.getSavePath() + "/" + Utils.DATABASE_NAME).toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch(IOException e) { Logger.error(e); AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Exportieren der Daten ist ein Fehler aufgetreten.", icon, stage, null, false); - } + } AlertGenerator.showAlert(AlertType.INFORMATION, "Erfolgreich exportiert", "", "Export erfolgreich abgeschlossen.", icon, stage, null, false); } } @@ -658,7 +664,7 @@ public class UserInterfaceController Platform.runLater(() -> { showWaitingDialog("Exportiere...", "Bitte warten..."); }); - Exporter exporter = new Exporter(savePath, stage, icon); + Exporter exporter = new Exporter(settings.getSavePath() + "/" + Utils.DATABASE_NAME, stage, icon); exporter.exportAsJSON(file); Platform.runLater(() -> { closeWaitingDialog(); @@ -707,7 +713,7 @@ public class UserInterfaceController waitingStage.close(); } } - + private void editEntry(LogObject object) { try @@ -720,19 +726,19 @@ public class UserInterfaceController newStage.getIcons().add(icon); newStage.initOwner(stage); - EditController pfc = (EditController)fxmlLoader.getController(); - pfc.init(this, newStage, savePath, icon, object); + EditController pfc = (EditController)fxmlLoader.getController(); + pfc.init(this, newStage, settings, icon, object); newStage.setResizable(false); newStage.initModality(Modality.APPLICATION_MODAL); - newStage.showAndWait(); + newStage.showAndWait(); } catch(IOException d) { Logger.error(d); } } - + public void updateEntry(LogObject oldLog, LogObject newLog) { try @@ -760,7 +766,43 @@ public class UserInterfaceController AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Löschen des Eintrags ist ein Fehler aufgetreten.", icon, stage, null, false); } } - + + @FXML + public void changeSavePath() + { + DirectoryChooser directoryChooser = new DirectoryChooser(); + directoryChooser.setTitle("Speicherort auswählen"); + File file = directoryChooser.showDialog(stage); + if(file != null) + { + String oldSavePath = settings.getSavePath(); + settings.setSavePath(file.getAbsolutePath()); + saveSettings(); + if(!oldSavePath.equals(settings.getSavePath())) + { + if(new File(oldSavePath + "/" + Utils.DATABASE_NAME).exists()) + { + try + { + Files.move(new File(oldSavePath + "/" + Utils.DATABASE_NAME).toPath(), new File(settings.getSavePath() + "/" + Utils.DATABASE_NAME).toPath(), StandardCopyOption.REPLACE_EXISTING); + } + catch(IOException e) + { + Logger.error(e); + AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Verschieben der Datenbank ist ein Fehler aufgetreten", icon, stage, null, false); + } + } + else + { + loadFromDB(); + loadAll(); + } + } + setLabelSavePath(); + } + } + + @FXML public void deleteDB() { Alert alert = new Alert(AlertType.CONFIRMATION); @@ -769,7 +811,7 @@ public class UserInterfaceController alert.setContentText("Möchten Sie die gesamte Datenbank wirklich unwiederruflich löschen?"); Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow(); dialogStage.getIcons().add(icon); - + Optional<ButtonType> result = alert.showAndWait(); if(result.get() == ButtonType.OK) { @@ -783,10 +825,10 @@ public class UserInterfaceController { Logger.error(e); AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Löschen der Datenbank ist ein Fehler aufgetreten.", icon, stage, null, false); - } - } + } + } } - + public void saveSettings() { try @@ -798,7 +840,7 @@ public class UserInterfaceController Logger.error(e); } } - + public void loadSettings() { settings = Utils.loadSettings(); @@ -811,13 +853,14 @@ public class UserInterfaceController else { settings = new Settings(); + settings.setSavePath(DEFAULT_SAVE_PATH); } } - + public void about() { ArrayList<String> creditLines = new ArrayList<>(); creditLines.add(bundle.getString("credits")); - AlertGenerator.showAboutAlertWithCredits(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date"), "Robert Goldmann", creditLines, icon, stage, null, false); - } + AlertGenerator.showAboutAlertWithCredits(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date"), "Robert Goldmann", creditLines, icon, stage, null, false); + } } \ No newline at end of file diff --git a/src/userInterface/userInterface.fxml b/src/userInterface/userInterface.fxml index 71f206b..48dad1f 100644 --- a/src/userInterface/userInterface.fxml +++ b/src/userInterface/userInterface.fxml @@ -16,7 +16,7 @@ <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<AnchorPane prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.UserInterfaceController"> +<AnchorPane prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="userInterface.UserInterfaceController"> <children> <VBox alignment="TOP_CENTER" layoutX="143.0" layoutY="69.0" prefHeight="800.0" prefWidth="650.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <children> @@ -25,6 +25,7 @@ <Menu mnemonicParsing="false" text="Datei"> <items> <MenuItem mnemonicParsing="false" onAction="#insertTime" text="Zeit nachträglich einfügen" /> + <MenuItem mnemonicParsing="false" onAction="#changeSavePath" text="Speicherort ändern" /> <MenuItem mnemonicParsing="false" onAction="#deleteDB" text="Datenbank löschen" /> </items></Menu> <Menu mnemonicParsing="false" text="Import"> @@ -88,7 +89,7 @@ </Button> </children> <VBox.margin> - <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" /> + <Insets bottom="30.0" left="30.0" right="30.0" top="20.0" /> </VBox.margin> </HBox> <HBox> @@ -151,6 +152,19 @@ </TitledPane> </panes> </Accordion> + <HBox alignment="CENTER_LEFT" spacing="14.0"> + <children> + <Label text="Speicherort der Datenbank:"> + <font> + <Font name="System Bold" size="12.0" /> + </font> + </Label> + <Label fx:id="labelSavePath" /> + </children> + <VBox.margin> + <Insets bottom="10.0" left="30.0" right="30.0" top="10.0" /> + </VBox.margin> + </HBox> </children> </VBox> </children> -- GitLab