Skip to content

Commit

Permalink
Fix not every path is canonicalized (#76)
Browse files Browse the repository at this point in the history
* Canonicalize disk mount points

* Fix some path not beeing canonicalized

* Move canonicalize to open method

* Cleanup

* Update CHANGELOG.md
  • Loading branch information
fluxxcode authored Feb 24, 2024
1 parent 2d8541e commit d3d0aa7
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
- Added `FileDialog::show_left_panel` to show or hide the left panel [#54](https://github.com/fluxxcode/egui-file-dialog/pull/54)
- Added `FileDialog::show_places`, `FileDialog::show_devices` and `FileDialog::show_removable_devices` to show or hide individual section of the left panel [#57](https://github.com/fluxxcode/egui-file-dialog/pull/57)

### 🐛 Bug Fixes
- Fixed not every path being canonicalized [#76](https://github.com/fluxxcode/egui-file-dialog/pull/76)

### 🔧 Changes
- Cleanup and restructure `FileDialog` UI methods [#56](https://github.com/fluxxcode/egui-file-dialog/pull/56)

Expand Down
14 changes: 12 additions & 2 deletions src/data/disks.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::fs;
use std::path::{Path, PathBuf};

/// Wrapper above the sysinfo::Disk struct.
Expand All @@ -14,7 +15,7 @@ impl Disk {
/// Create a new Disk object based on the data of a sysinfo::Disk.
pub fn from_sysinfo_disk(disk: &sysinfo::Disk) -> Self {
Self {
mount_point: disk.mount_point().to_path_buf(),
mount_point: Self::canonicalize(disk.mount_point()),
display_name: gen_display_name(disk),
is_removable: disk.is_removable(),
}
Expand All @@ -33,6 +34,15 @@ impl Disk {
pub fn is_removable(&self) -> bool {
self.is_removable
}

/// Canonicalizes the given path.
/// Returns the input path in case of an error.
fn canonicalize(path: &Path) -> PathBuf {
match fs::canonicalize(path) {
Ok(p) => p,
Err(_) => path.to_path_buf(),
}
}
}

/// Wrapper above the sysinfo::Disks struct
Expand Down Expand Up @@ -72,7 +82,7 @@ fn gen_display_name(disk: &sysinfo::Disk) -> String {
.to_str()
.unwrap_or_default()
.to_string()
.replace("\\", "");
.replace('\\', "");

// Try using the mount point as the display name if the specified name
// from sysinfo::Disk is empty or contains invalid characters
Expand Down
40 changes: 19 additions & 21 deletions src/file_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,6 @@ impl FileDialog {
) -> io::Result<()> {
self.reset();

// Try to use the parent directory if the initial directory is a file.
// If the path then has no parent directory, the user will see an error that the path
// does not exist. However, using the user directories or disks, the user is still able
// to select an item or save a file.
if self.config.initial_directory.is_file() {
if let Some(parent) = self.config.initial_directory.parent() {
self.config.initial_directory = parent.to_path_buf();
}
}

if mode == DialogMode::SelectFile {
show_files = true;
}
Expand All @@ -269,7 +259,7 @@ impl FileDialog {
};
}

self.load_directory(&self.config.initial_directory.clone())
self.load_directory(&self.gen_initial_directory(&self.config.initial_directory))
}

/// Shortcut function to open the file dialog to prompt the user to select a directory.
Expand Down Expand Up @@ -1413,6 +1403,22 @@ impl FileDialog {
self.state = DialogState::Cancelled;
}

/// This function generates the initial directory based on the configuration.
/// The function does the following things:
/// - Canonicalize the path if enabled
/// - Attempts to use the parent directory if the path is a file
fn gen_initial_directory(&self, path: &Path) -> PathBuf {
let mut path = fs::canonicalize(path).unwrap_or(path.to_path_buf());

if path.is_file() {
if let Some(parent) = path.parent() {
path = parent.to_path_buf();
}
}

path
}

/// Gets the currently open directory.
fn current_directory(&self) -> Option<&Path> {
if let Some(x) = self.directory_stack.iter().nth_back(self.directory_offset) {
Expand Down Expand Up @@ -1546,18 +1552,10 @@ impl FileDialog {
///
/// The function also sets the loaded directory as the selected item.
fn load_directory(&mut self, path: &Path) -> io::Result<()> {
let full_path = match fs::canonicalize(path) {
Ok(path) => path,
Err(err) => {
self.directory_error = Some(err.to_string());
return Err(err);
}
};

// Do not load the same directory again.
// Use reload_directory if the content of the directory should be updated.
if let Some(x) = self.current_directory() {
if x == full_path {
if x == path {
return Ok(());
}
}
Expand All @@ -1567,7 +1565,7 @@ impl FileDialog {
.drain(self.directory_stack.len() - self.directory_offset..);
}

self.directory_stack.push(full_path);
self.directory_stack.push(path.to_path_buf());
self.directory_offset = 0;

self.load_directory_content(path)?;
Expand Down

0 comments on commit d3d0aa7

Please sign in to comment.