native_dialog/builder/
file.rs

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