diff --git a/examples/dialog.rs b/examples/dialog.rs index bc64519..687d070 100644 --- a/examples/dialog.rs +++ b/examples/dialog.rs @@ -22,6 +22,7 @@ fn main() -> Result<(), Box> { pub enum Message { DialogMessage(DialogMessage), DialogOpen(DialogKind), + DialogOpenImages, DialogResult(DialogResult), } @@ -105,6 +106,31 @@ impl Application for App { return Task::batch(tasks); } } + Message::DialogOpenImages => { + if self.dialog_opt.is_none() { + let (mut dialog, task) = Dialog::new( + DialogSettings::new().kind(DialogKind::OpenFile), + Message::DialogMessage, + Message::DialogResult, + ); + let mut tasks = vec![task]; + tasks.push(dialog.set_filters( + vec![ + DialogFilter { + label: "Images".into(), + patterns: vec![DialogFilterPattern::Mime("image/*".into())], + }, + DialogFilter { + label: "Any file".into(), + patterns: vec![DialogFilterPattern::Glob("*".into())], + }, + ], + Some(0), + )); + self.dialog_opt = Some(dialog); + return Task::batch(tasks); + } + } Message::DialogResult(result) => { self.dialog_opt = None; self.result_opt = Some(result); @@ -130,6 +156,13 @@ impl Application for App { } column = column.push(button); } + { + let mut button = widget::button::standard("Open Image"); + if self.dialog_opt.is_none() { + button = button.on_press(Message::DialogOpenImages); + } + column = column.push(button); + } { let mut button = widget::button::standard("Open Multiple Files"); if self.dialog_opt.is_none() { diff --git a/src/dialog.rs b/src/dialog.rs index 33d3ff9..f1c9395 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -24,6 +24,7 @@ use cosmic::{ segmented_button, }, }; +use mime_guess::{Mime, mime}; use notify_debouncer_full::{ DebouncedEvent, Debouncer, RecommendedCache, new_debouncer, notify::{self, RecommendedWatcher}, @@ -1887,7 +1888,6 @@ impl Application for App { if let Some(filter_i) = self.filter_selected && let Some(filter) = self.filters.get(filter_i) { - // Parse globs (Mime implements PartialEq with &str, so no need to parse) let mut parsed_globs = Vec::new(); let mut mimes = Vec::new(); for pattern in &filter.patterns { @@ -1900,15 +1900,25 @@ impl Application for App { } } } - DialogFilterPattern::Mime(value) => mimes.push(value.as_str()), + DialogFilterPattern::Mime(value) => match value.parse::() { + Ok(parsed) => mimes.push(parsed), + Err(err) => { + log::warn!("failed to parse mime {value:?}: {err}"); + } + }, } } items.retain(|item| { // Directories are always shown item.metadata.is_dir() - // Check for mime type match (first because it is faster) - || mimes.iter().copied().any(|mime| mime == item.mime) + || mimes.iter().any(|filter_mime| { + if filter_mime.subtype() == mime::STAR { + filter_mime.type_() == item.mime.type_() + } else { + *filter_mime == item.mime + } + }) // Check for glob match (last because it is slower) || parsed_globs.iter().any(|glob| glob.matches(&item.name)) });