From 55c54ae004757d664b7d89bbab41be15f2885f3e Mon Sep 17 00:00:00 2001 From: Jannis <55352293+fluxxcode@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:34:14 +0200 Subject: [PATCH] Save path from path edit (#160) * Save path from path edit * Update changelog --- CHANGELOG.md | 4 ++++ src/config/mod.rs | 10 +++++++++ src/file_dialog.rs | 53 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4abec47c..33a60411 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # egui-file-dialog changelog +## Unreleased +### 🔧 Changes +- Use path edit as file to save [#160](https://github.com/fluxxcode/egui-file-dialog/pull/160) + ## 2024-10-01 - v0.7.0 - egui update and QoL changes ### 🚨 Breaking Changes - Updated `egui` from version `0.28.0` to version `0.29.1` [#155](https://github.com/fluxxcode/egui-file-dialog/pull/155) and [#157](https://github.com/fluxxcode/egui-file-dialog/pull/157) (thanks [@crumblingstatue](https://github.com/crumblingstatue)!) diff --git a/src/config/mod.rs b/src/config/mod.rs index 544e2652..5d343ee3 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -84,6 +84,15 @@ pub struct FileDialogConfig { /// If the user is allowed to select an already existing file when the dialog is /// in `DialogMode::SaveFile` mode. pub allow_file_overwrite: bool, + /// If the path edit is allowed to select the path as the file to save + /// if it does not have an extension. + /// + /// This can lead to confusion if the user wants to open a directory with the path edit, + /// types it incorrectly and the dialog tries to select the incorrectly typed folder as + /// the file to be saved. + /// + /// This only affects the `DialogMode::SaveFile` mode. + pub allow_path_edit_to_save_file_without_extension: bool, /// Sets the separator of the directories when displaying a path. /// Currently only used when the current path is displayed in the top panel. pub directory_separator: String, @@ -196,6 +205,7 @@ impl Default for FileDialogConfig { initial_directory: std::env::current_dir().unwrap_or_default(), default_file_name: String::new(), allow_file_overwrite: true, + allow_path_edit_to_save_file_without_extension: false, directory_separator: String::from(">"), canonicalize_paths: true, diff --git a/src/file_dialog.rs b/src/file_dialog.rs index df41c3f7..9c24911d 100644 --- a/src/file_dialog.rs +++ b/src/file_dialog.rs @@ -540,6 +540,19 @@ impl FileDialog { self } + /// Sets if the path edit is allowed to select the path as the file to save + /// if it does not have an extension. + /// + /// This can lead to confusion if the user wants to open a directory with the path edit, + /// types it incorrectly and the dialog tries to select the incorrectly typed folder as + /// the file to be saved. + /// + /// This only affects the `DialogMode::SaveFile` mode. + pub const fn allow_path_edit_to_save_file_without_extension(mut self, allow: bool) -> Self { + self.config.allow_path_edit_to_save_file_without_extension = allow; + self + } + /// Sets the separator of the directories when displaying a path. /// Currently only used when the current path is displayed in the top panel. pub fn directory_separator(mut self, separator: &str) -> Self { @@ -2506,21 +2519,25 @@ impl FileDialog { // Should always contain a value since `is_selection_valid` is used to // validate the selection. if let Some(path) = self.current_directory() { - let mut full_path = path.to_path_buf(); - full_path.push(&self.file_name_input); - - if full_path.exists() { - self.open_modal(Box::new(OverwriteFileModal::new(full_path))); - - return; - } - - self.state = DialogState::Selected(full_path); + let full_path = path.join(&self.file_name_input); + self.submit_save_file(full_path); } } } } + /// Submits the file dialog with the specified path and opens the `OverwriteFileModal` + /// if the path already exists. + fn submit_save_file(&mut self, path: PathBuf) { + if path.exists() { + self.open_modal(Box::new(OverwriteFileModal::new(path))); + + return; + } + + self.state = DialogState::Selected(path); + } + /// Cancels the dialog. fn cancel(&mut self) { self.state = DialogState::Cancelled; @@ -2759,6 +2776,22 @@ impl FileDialog { return; } + // Assume the user wants to save the given path when + // - an extension to the file name is given or the path + // edit is allowed to save a file without extension, + // - the path is not an existing directory, + // - and the parent directory exists + // Otherwise we will assume the user wants to open the path as a directory. + if self.mode == DialogMode::SaveFile + && (path.extension().is_some() + || self.config.allow_path_edit_to_save_file_without_extension) + && !path.is_dir() + && path.parent().is_some_and(std::path::Path::exists) + { + self.submit_save_file(path); + return; + } + let _ = self.load_directory(&path); }