diff --git a/client/src/main/java/envoy/client/data/Settings.java b/client/src/main/java/envoy/client/data/Settings.java index d511553..07bb354 100644 --- a/client/src/main/java/envoy/client/data/Settings.java +++ b/client/src/main/java/envoy/client/data/Settings.java @@ -77,6 +77,10 @@ public class Settings { items.putIfAbsent("enterToSend", new SettingsItem<>(true, "Enter to send", "Sends a message by pressing the enter key.")); items.putIfAbsent("hideOnClose", new SettingsItem<>(true, "Hide on close", "Hides the chat window when it is closed.")); items.putIfAbsent("currentTheme", new SettingsItem<>("dark", "Current Theme Name", "The name of the currently selected theme.")); + items.putIfAbsent("downloadLocation", + new SettingsItem<>(new File(System.getProperty("user.home") + "/Downloads/"), "Download location", + "The location where files will be saved to")); + items.putIfAbsent("autoSaveDownloads", new SettingsItem<>(false, "Save without asking?", "Should downloads be saved without asking?")); } /** @@ -120,6 +124,37 @@ public class Settings { */ public void setEnterToSend(boolean enterToSend) { ((SettingsItem) items.get("enterToSend")).set(enterToSend); } + /** + * @return whether Envoy will prompt a dialogue before saving an + * {@link envoy.data.Attachment} + * @since Envoy Client v0.2-beta + */ + public Boolean isDownloadSavedWithoutAsking() { return (Boolean) items.get("autoSaveDownloads").get(); } + + /** + * Sets whether Envoy will prompt a dialogue before saving an + * {@link envoy.data.Attachment}. + * + * @param autosaveDownload whether a download should be saved without asking + * before + * @since Envoy Client v0.2-beta + */ + public void setDownloadSavedWithoutAsking(boolean autosaveDownload) { ((SettingsItem) items.get("autoSaveDownloads")).set(autosaveDownload); } + + /** + * @return the path where downloads should be saved + * @since Envoy Client v0.2-beta + */ + public File getDownloadLocation() { return (File) items.get("downloadLocation").get(); } + + /** + * Sets the path where downloads should be saved. + * + * @param downloadLocation the path to set + * @since Envoy Client v0.2-beta + */ + public void setDownloadLocation(File downloadLocation) { ((SettingsItem) items.get("downloadLocation")).set(downloadLocation); } + /** * @return the current on close mode. * @since Envoy Client v0.3-alpha diff --git a/client/src/main/java/envoy/client/ui/controller/SettingsScene.java b/client/src/main/java/envoy/client/ui/controller/SettingsScene.java index b7cc49d..f3358a9 100644 --- a/client/src/main/java/envoy/client/ui/controller/SettingsScene.java +++ b/client/src/main/java/envoy/client/ui/controller/SettingsScene.java @@ -4,6 +4,7 @@ import javafx.fxml.FXML; import javafx.scene.control.*; import envoy.client.ui.SceneContext; +import envoy.client.ui.settings.DownloadSettingsPane; import envoy.client.ui.settings.GeneralSettingsPane; import envoy.client.ui.settings.SettingsPane; @@ -29,7 +30,10 @@ public class SettingsScene { * @param sceneContext enables the user to return to the chat scene * @since Envoy Client v0.1-beta */ - public void initializeData(SceneContext sceneContext) { this.sceneContext = sceneContext; } + public void initializeData(SceneContext sceneContext) { + this.sceneContext = sceneContext; + settingsList.getItems().add(new DownloadSettingsPane(sceneContext)); + } @FXML private void initialize() { diff --git a/client/src/main/java/envoy/client/ui/listcell/MessageControl.java b/client/src/main/java/envoy/client/ui/listcell/MessageControl.java index 795cd42..0c0d91b 100644 --- a/client/src/main/java/envoy/client/ui/listcell/MessageControl.java +++ b/client/src/main/java/envoy/client/ui/listcell/MessageControl.java @@ -18,6 +18,7 @@ import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; +import envoy.client.data.Settings; import envoy.client.ui.AudioControl; import envoy.client.ui.IconUtil; import envoy.client.ui.SceneContext; @@ -45,6 +46,7 @@ public class MessageControl extends Label { private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss") .withZone(ZoneId.systemDefault()); private static final Map statusImages = IconUtil.loadByEnum(MessageStatus.class, 16); + private static final Settings settings = Settings.getInstance(); private static final Logger logger = EnvoyLog.getLogger(MessageControl.class); /** @@ -121,16 +123,21 @@ public class MessageControl extends Label { private void loadMessageInfoScene(Message message) { logger.log(Level.FINEST, "message info scene was requested for " + message); } private void saveAttachment(Message message) { - // Show save file dialog - final var fileChooser = new FileChooser(); - fileChooser.setInitialFileName(message.getAttachment().getName()); - - final File file = fileChooser.showSaveDialog(sceneContext.getStage()); + File file; + final var fileName = message.getAttachment().getName(); + final var downloadLocation = settings.getDownloadLocation(); + // Show save file dialog, if the user did not opt-out + if (!settings.isDownloadSavedWithoutAsking()) { + final var fileChooser = new FileChooser(); + fileChooser.setInitialFileName(fileName); + fileChooser.setInitialDirectory(downloadLocation); + file = fileChooser.showSaveDialog(sceneContext.getStage()); + } else file = new File(downloadLocation + (downloadLocation.getName().endsWith("/") ? "" : "/") + fileName); // A file was selected if (file != null) try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(message.getAttachment().getData()); - logger.log(Level.FINE, "Attachment of " + message + " was saved."); + logger.log(Level.FINE, "Attachment of message was saved at " + file.getAbsolutePath()); } catch (final IOException e) { logger.log(Level.WARNING, "Could not save attachment of " + message + ": ", e); } diff --git a/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java new file mode 100644 index 0000000..c97cdd4 --- /dev/null +++ b/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java @@ -0,0 +1,66 @@ +package envoy.client.ui.settings; + +import javafx.geometry.Insets; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.DirectoryChooser; + +import envoy.client.ui.SceneContext; + +/** + * Displays options for downloading {@link envoy.data.Attachment}s. + *

+ * Project: envoy-client
+ * File: DownloadSettingsPane.java
+ * Created: 27.07.2020
+ * + * @author Leon Hofmeister + * @since Envoy Client v0.2-beta + */ +public class DownloadSettingsPane extends SettingsPane { + + /** + * Constructs a new {@code DownloadSettingsPane} + * + * @param sceneContext the {@code SceneContext} used to block input to the + * {@link javafx.stage.Stage} used in Envoy + * @since Envoy Client v0.2-beta + */ + public DownloadSettingsPane(SceneContext sceneContext) { + super("Download"); + final var vbox = new VBox(15); + vbox.setPadding(new Insets(15)); + // checkbox to disable asking + final var checkBox = new CheckBox(settings.getItems().get("autoSaveDownloads").getUserFriendlyName()); + checkBox.setSelected(settings.isDownloadSavedWithoutAsking()); + checkBox.setOnAction(e -> settings.setDownloadSavedWithoutAsking(checkBox.isSelected())); + vbox.getChildren().add(checkBox); + + // Displaying the default path to save to + vbox.getChildren().add(new Label(settings.getItems().get("downloadLocation").getDescription() + ":")); + final var hbox = new HBox(20); + final var currentPath = new Label(settings.getDownloadLocation().getAbsolutePath()); + hbox.getChildren().add(currentPath); + + // Setting the default path + final var button = new Button("Select"); + button.setOnAction(e -> { + final var directoryChooser = new DirectoryChooser(); + directoryChooser.setTitle("Select the directory where attachments should be saved to"); + directoryChooser.setInitialDirectory(settings.getDownloadLocation()); + final var selectedDirectory = directoryChooser.showDialog(sceneContext.getStage()); + + if (selectedDirectory != null) { + currentPath.setText(selectedDirectory.getAbsolutePath()); + settings.setDownloadLocation(selectedDirectory); + } + }); + hbox.getChildren().add(button); + vbox.getChildren().add(hbox); + getChildren().add(vbox); + } + +} diff --git a/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java index c82cb18..af46fbb 100644 --- a/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java @@ -5,7 +5,6 @@ import java.util.List; import javafx.scene.control.ComboBox; import javafx.scene.layout.VBox; -import envoy.client.data.Settings; import envoy.client.data.SettingsItem; import envoy.client.event.ThemeChangeEvent; import envoy.data.User.UserStatus; @@ -21,8 +20,6 @@ import envoy.event.EventBus; */ public class GeneralSettingsPane extends SettingsPane { - private static final Settings settings = Settings.getInstance(); - /** * @since Envoy Client v0.1-beta */ diff --git a/client/src/main/java/envoy/client/ui/settings/SettingsPane.java b/client/src/main/java/envoy/client/ui/settings/SettingsPane.java index 7c84221..49f8abd 100644 --- a/client/src/main/java/envoy/client/ui/settings/SettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/SettingsPane.java @@ -2,11 +2,13 @@ package envoy.client.ui.settings; import javafx.scene.layout.Pane; +import envoy.client.data.Settings; + /** * Project: envoy-client
* File: SettingsPane.java
* Created: 18.04.2020
- * + * * @author Kai S. K. Engelbart * @since Envoy Client v0.1-beta */ @@ -14,6 +16,8 @@ public abstract class SettingsPane extends Pane { protected String title; + protected static final Settings settings = Settings.getInstance(); + protected SettingsPane(String title) { this.title = title; } /**