native_dialog_fork/
file.rs1use crate::dialog::{DialogImpl, OpenMultipleFile, OpenSingleDir, OpenSingleFile, SaveSingleFile};
2use crate::Result;
3use raw_window_handle::{HasWindowHandle, RawWindowHandle};
4use std::path::{Path, PathBuf};
5
6#[derive(Debug, Clone)]
8pub struct Filter<'a> {
9 pub(crate) description: &'a str,
10 pub(crate) extensions: &'a [&'a str],
11}
12
13#[derive(Debug, Clone)]
15pub struct FileDialog<'a> {
16 pub(crate) filename: Option<&'a str>,
17 pub(crate) location: Option<&'a Path>,
18 pub(crate) filters: Vec<Filter<'a>>,
19 pub(crate) owner: Option<RawWindowHandle>,
20 pub(crate) title: Option<&'a str>,
21}
22
23impl<'a> FileDialog<'a> {
24 pub fn new() -> Self {
26 FileDialog {
27 filename: None,
28 location: None,
29 filters: vec![],
30 owner: None,
31 title: None,
32 }
33 }
34
35 pub fn set_title(mut self, title: &'a str) -> Self {
37 self.title = Some(title);
38 self
39 }
40
41 pub fn set_filename(mut self, filename: &'a str) -> Self {
44 self.filename = Some(filename);
45 self
46 }
47
48 pub fn reset_filename(mut self) -> Self {
50 self.filename = None;
51 self
52 }
53
54 pub fn set_location<P: AsRef<Path> + ?Sized>(mut self, path: &'a P) -> Self {
56 self.location = Some(path.as_ref());
57 self
58 }
59
60 pub fn reset_location(mut self) -> Self {
63 self.location = None;
64 self
65 }
66
67 pub fn add_filter(mut self, description: &'a str, extensions: &'a [&'a str]) -> Self {
70 if extensions.is_empty() {
71 panic!("The file extensions of a filter must be specified.")
72 }
73 self.filters.push(Filter {
74 description,
75 extensions,
76 });
77 self
78 }
79
80 pub fn remove_all_filters(mut self) -> Self {
82 self.filters = vec![];
83 self
84 }
85
86 pub fn set_owner<W: HasWindowHandle>(mut self, window: Option<&W>) -> Self {
88 let handle = window
89 .map(W::window_handle)
90 .transpose()
91 .ok()
92 .flatten()
93 .map(|x| x.as_raw());
94 self.owner = handle;
95 self
96 }
97
98 pub unsafe fn set_owner_handle(mut self, handle: Option<RawWindowHandle>) -> Self {
104 self.owner = handle;
105 self
106 }
107
108 pub fn reset_owner(mut self) -> Self {
110 self.owner = None;
111 self
112 }
113
114 pub fn show_open_single_file(self) -> Result<Option<PathBuf>> {
116 let mut dialog = OpenSingleFile {
117 filename: self.filename,
118 location: self.location,
119 filters: self.filters,
120 owner: self.owner,
121 title: self.title.unwrap_or("Open File"),
122 };
123 dialog.show()
124 }
125
126 pub fn show_open_multiple_file(self) -> Result<Vec<PathBuf>> {
128 let mut dialog = OpenMultipleFile {
129 filename: self.filename,
130 location: self.location,
131 filters: self.filters,
132 owner: self.owner,
133 title: self.title.unwrap_or("Open File"),
134 };
135 dialog.show()
136 }
137
138 pub fn show_open_single_dir(self) -> Result<Option<PathBuf>> {
140 let mut dialog = OpenSingleDir {
141 filename: self.filename,
142 location: self.location,
143 owner: self.owner,
144 title: self.title.unwrap_or("Open Folder"),
145 };
146 dialog.show()
147 }
148
149 pub fn show_save_single_file(self) -> Result<Option<PathBuf>> {
151 let mut dialog = SaveSingleFile {
152 filename: self.filename,
153 location: self.location,
154 filters: self.filters,
155 owner: self.owner,
156 title: self.title.unwrap_or("Save As"),
157 };
158 dialog.show()
159 }
160}
161
162impl Default for FileDialog<'_> {
163 fn default() -> Self {
164 Self::new()
165 }
166}