1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
use crate::{Dialog, Error, OpenMultipleFile, OpenSingleFile, Result}; use std::path::PathBuf; use wfd::{ DialogError, DialogParams, OpenDialogResult, FOS_ALLOWMULTISELECT, FOS_FILEMUSTEXIST, FOS_NOREADONLYRETURN, FOS_OVERWRITEPROMPT, FOS_PATHMUSTEXIST, }; impl Dialog for OpenSingleFile<'_> { type Output = Option<String>; fn show(self) -> Result<Self::Output> { super::process_init(); open_dialog(OpenDialogParams { dir: self.dir, filter: self.filter, multiple: false, }) .map(|ok| ok.map(|some| path_to_string(some.selected_file_path))) } } impl Dialog for OpenMultipleFile<'_> { type Output = Vec<String>; fn show(self) -> Result<Self::Output> { super::process_init(); let result = open_dialog(OpenDialogParams { dir: self.dir, filter: self.filter, multiple: true, }); match result { Ok(Some(t)) => { let paths = t.selected_file_paths; let strings = paths.into_iter().map(path_to_string).collect(); Ok(strings) } Ok(None) => Ok(vec![]), Err(e) => Err(e), } } } fn path_to_string(path: PathBuf) -> String { path.to_string_lossy().to_string() } struct OpenDialogParams<'a> { dir: Option<&'a str>, filter: Option<&'a [&'a str]>, multiple: bool, } fn open_dialog(params: OpenDialogParams) -> Result<Option<OpenDialogResult>> { let file_types = match params.filter { Some(filter) => { let types: Vec<String> = filter.iter().map(|s| format!("*.{}", s)).collect(); types.join(";") } None => String::new(), }; let file_types = match params.filter { Some(_) => vec![("", file_types.as_str())], None => vec![], }; let mut options = FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST; if params.multiple { options |= FOS_ALLOWMULTISELECT; } let params = DialogParams { default_folder: params.dir.unwrap_or(""), file_types, options, ..Default::default() }; let result = wfd::open_dialog(params); match result { Ok(t) => Ok(Some(t)), Err(e) => match e { DialogError::UserCancelled => Ok(None), DialogError::HResultFailed { error_method, .. } => { Err(Error::ImplementationError(error_method)) } }, } } #[allow(dead_code)] fn save_dialog() { let mut _options = FOS_OVERWRITEPROMPT | FOS_PATHMUSTEXIST | FOS_NOREADONLYRETURN; }