native_dialog/builder/
file.rs

1use raw_window_handle::HasWindowHandle;
2use std::path::{Path, PathBuf};
3
4use crate::dialog::{Filter, OpenMultipleFile, OpenSingleDir, OpenSingleFile, SaveSingleFile};
5use crate::utils::UnsafeWindowHandle;
6
7/// Builder for file dialogs.
8#[derive(Debug, Clone, Default)]
9pub struct FileDialogBuilder {
10    pub filename: Option<String>,
11    pub location: Option<PathBuf>,
12    pub filters: Vec<Filter>,
13    pub owner: UnsafeWindowHandle,
14    pub title: Option<String>,
15}
16
17impl FileDialogBuilder {
18    /// Sets the window title for the dialog.
19    pub fn set_title(mut self, title: impl ToString) -> Self {
20        self.title = Some(title.to_string());
21        self
22    }
23
24    /// Sets the default value of the filename text field in the dialog. For open dialogs of macOS
25    /// and zenity, this is a no-op because there's no such text field on the dialog.
26    pub fn set_filename(mut self, filename: impl ToString) -> Self {
27        self.filename = Some(filename.to_string());
28        self
29    }
30
31    /// Resets the default value of the filename field in the dialog.
32    pub fn reset_filename(mut self) -> Self {
33        self.filename = None;
34        self
35    }
36
37    /// Sets the default directory that the dialog shows at open.
38    pub fn set_location<P: AsRef<Path> + ?Sized>(mut self, path: &P) -> Self {
39        self.location = Some(path.as_ref().to_path_buf());
40        self
41    }
42
43    /// Resets the default directory that the dialog shows at open.
44    /// If a location is not set, the dialog will probably go to the current working directory.
45    pub fn reset_location(mut self) -> Self {
46        self.location = None;
47        self
48    }
49
50    /// Adds a file type filter. The filter must contains at least one extension, otherwise this
51    /// method will be a no-op. For dialogs that open directories, this is also a no-op.
52    pub fn add_filter(mut self, description: impl ToString, extensions: &[impl ToString]) -> Self {
53        if extensions.is_empty() {
54            return self;
55        }
56
57        self.filters.push(Filter {
58            description: description.to_string(),
59            extensions: extensions.iter().map(ToString::to_string).collect(),
60        });
61
62        self
63    }
64
65    /// Removes all file type filters.
66    pub fn reset_filters(mut self) -> Self {
67        self.filters = vec![];
68        self
69    }
70
71    /// Sets the owner of the dialog.
72    pub fn set_owner<W: HasWindowHandle>(mut self, window: &W) -> Self {
73        self.owner = UnsafeWindowHandle::new(window);
74        self
75    }
76
77    /// Resets the owner of the dialog to nothing.
78    pub fn reset_owner(mut self) -> Self {
79        self.owner = UnsafeWindowHandle::default();
80        self
81    }
82
83    /// Builds a dialog that let users to open one file.
84    pub fn open_single_file(self) -> OpenSingleFile {
85        OpenSingleFile {
86            filename: self.filename,
87            location: self.location,
88            filters: self.filters,
89            owner: self.owner,
90            title: self.title.unwrap_or("Open File".to_string()),
91        }
92    }
93
94    /// Builds a dialog that let users to open multiple files.
95    pub fn open_multiple_file(self) -> OpenMultipleFile {
96        OpenMultipleFile {
97            filename: self.filename,
98            location: self.location,
99            filters: self.filters,
100            owner: self.owner,
101            title: self.title.unwrap_or("Open File".to_string()),
102        }
103    }
104
105    /// Builds a dialog that let users to open one directory.
106    pub fn open_single_dir(self) -> OpenSingleDir {
107        OpenSingleDir {
108            filename: self.filename,
109            location: self.location,
110            owner: self.owner,
111            title: self.title.unwrap_or("Open Folder".to_string()),
112        }
113    }
114
115    /// Builds a dialog that let users to save one file.
116    pub fn save_single_file(self) -> SaveSingleFile {
117        SaveSingleFile {
118            filename: self.filename,
119            location: self.location,
120            filters: self.filters,
121            owner: self.owner,
122            title: self.title.unwrap_or("Save As".to_string()),
123        }
124    }
125}