native_dialog/builder/
file.rs

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