1use crate::dialog::{DialogImpl, OpenMultipleFile, OpenSingleDir, OpenSingleFile, SaveSingleFile};
2use crate::Result;
3use raw_window_handle::{HasRawWindowHandle, 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: HasRawWindowHandle>(mut self, window: &W) -> Self {
88 self.owner = Some(window.raw_window_handle());
89 self
90 }
91
92 pub unsafe fn set_owner_handle(mut self, handle: RawWindowHandle) -> Self {
98 self.owner = Some(handle);
99 self
100 }
101
102 pub fn reset_owner(mut self) -> Self {
104 self.owner = None;
105 self
106 }
107
108 pub fn show_open_single_file(self) -> Result<Option<PathBuf>> {
110 let mut dialog = OpenSingleFile {
111 filename: self.filename,
112 location: self.location,
113 filters: self.filters,
114 owner: self.owner,
115 title: self.title.unwrap_or("Open File"),
116 };
117 dialog.show()
118 }
119
120 pub fn show_open_multiple_file(self) -> Result<Vec<PathBuf>> {
122 let mut dialog = OpenMultipleFile {
123 filename: self.filename,
124 location: self.location,
125 filters: self.filters,
126 owner: self.owner,
127 title: self.title.unwrap_or("Open File"),
128 };
129 dialog.show()
130 }
131
132 pub fn show_open_single_dir(self) -> Result<Option<PathBuf>> {
134 let mut dialog = OpenSingleDir {
135 filename: self.filename,
136 location: self.location,
137 owner: self.owner,
138 title: self.title.unwrap_or("Open Folder"),
139 };
140 dialog.show()
141 }
142
143 pub fn show_save_single_file(self) -> Result<Option<PathBuf>> {
145 let mut dialog = SaveSingleFile {
146 filename: self.filename,
147 location: self.location,
148 filters: self.filters,
149 owner: self.owner,
150 title: self.title.unwrap_or("Save As"),
151 };
152 dialog.show()
153 }
154}
155
156impl Default for FileDialog<'_> {
157 fn default() -> Self {
158 Self::new()
159 }
160}