Merge pull request #1650 from hojjatabdollahi/hojjat/fix-open-dialog-mime
Fix mimetype based filtering in dialog
This commit is contained in:
commit
bfb2c6d5b8
2 changed files with 47 additions and 4 deletions
|
|
@ -22,6 +22,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
DialogMessage(DialogMessage),
|
DialogMessage(DialogMessage),
|
||||||
DialogOpen(DialogKind),
|
DialogOpen(DialogKind),
|
||||||
|
DialogOpenImages,
|
||||||
DialogResult(DialogResult),
|
DialogResult(DialogResult),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,6 +106,31 @@ impl Application for App {
|
||||||
return Task::batch(tasks);
|
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) => {
|
Message::DialogResult(result) => {
|
||||||
self.dialog_opt = None;
|
self.dialog_opt = None;
|
||||||
self.result_opt = Some(result);
|
self.result_opt = Some(result);
|
||||||
|
|
@ -130,6 +156,13 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
column = column.push(button);
|
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");
|
let mut button = widget::button::standard("Open Multiple Files");
|
||||||
if self.dialog_opt.is_none() {
|
if self.dialog_opt.is_none() {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ use cosmic::{
|
||||||
segmented_button,
|
segmented_button,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use mime_guess::{Mime, mime};
|
||||||
use notify_debouncer_full::{
|
use notify_debouncer_full::{
|
||||||
DebouncedEvent, Debouncer, RecommendedCache, new_debouncer,
|
DebouncedEvent, Debouncer, RecommendedCache, new_debouncer,
|
||||||
notify::{self, RecommendedWatcher},
|
notify::{self, RecommendedWatcher},
|
||||||
|
|
@ -1887,7 +1888,6 @@ impl Application for App {
|
||||||
if let Some(filter_i) = self.filter_selected
|
if let Some(filter_i) = self.filter_selected
|
||||||
&& let Some(filter) = self.filters.get(filter_i)
|
&& 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 parsed_globs = Vec::new();
|
||||||
let mut mimes = Vec::new();
|
let mut mimes = Vec::new();
|
||||||
for pattern in &filter.patterns {
|
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::<Mime>() {
|
||||||
|
Ok(parsed) => mimes.push(parsed),
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("failed to parse mime {value:?}: {err}");
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items.retain(|item| {
|
items.retain(|item| {
|
||||||
// Directories are always shown
|
// Directories are always shown
|
||||||
item.metadata.is_dir()
|
item.metadata.is_dir()
|
||||||
// Check for mime type match (first because it is faster)
|
|| mimes.iter().any(|filter_mime| {
|
||||||
|| mimes.iter().copied().any(|mime| mime == item.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)
|
// Check for glob match (last because it is slower)
|
||||||
|| parsed_globs.iter().any(|glob| glob.matches(&item.name))
|
|| parsed_globs.iter().any(|glob| glob.matches(&item.name))
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue