Merge pull request #1472 from txiki739/fix/linux-async-dialog-filters
#262: Linux file dialogs shown off the UI thread keep case-insensitive filters
This commit is contained in:
commit
629e5e9ee1
|
|
@ -447,11 +447,8 @@ fn run_dialog_off_thread(dialog: filmcraft_ui_egui::native_dialogs::FileDialog)
|
|||
let t = |s: &str| filmcraft_ui_egui::i18n::t(s).to_string();
|
||||
let media = t("Media");
|
||||
let project = t("FilmCraft Project");
|
||||
let dialog = match dialog {
|
||||
FileDialog::OpenFile { filter, exts } => FileDialog::OpenFile { filter: t(&filter), exts },
|
||||
FileDialog::SaveAs { filter, exts, name } => FileDialog::SaveAs { filter: t(&filter), exts, name },
|
||||
other => other,
|
||||
};
|
||||
let project_exts = project_patterns();
|
||||
let dialog = prepare_dialog(dialog);
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
let spawned = std::thread::Builder::new().name("file-dialog".into()).spawn(move || {
|
||||
let shown = std::panic::catch_unwind(move || {
|
||||
|
|
@ -462,9 +459,9 @@ fn run_dialog_off_thread(dialog: filmcraft_ui_egui::native_dialogs::FileDialog)
|
|||
}
|
||||
FileDialog::OpenFile { filter, exts } => rfd::FileDialog::new().add_filter(&filter, &exts).pick_file().map(path).into_iter().collect(),
|
||||
FileDialog::Relink { exts, .. } => rfd::FileDialog::new().add_filter(&media, &exts).pick_file().map(path).into_iter().collect(),
|
||||
FileDialog::OpenProject => rfd::FileDialog::new().add_filter(&project, &["fcproj"]).pick_file().map(path).into_iter().collect(),
|
||||
FileDialog::OpenProject => rfd::FileDialog::new().add_filter(&project, &project_exts).pick_file().map(path).into_iter().collect(),
|
||||
FileDialog::SaveProject { name } => {
|
||||
rfd::FileDialog::new().add_filter(&project, &["fcproj"]).set_file_name(name).save_file().map(path).into_iter().collect()
|
||||
rfd::FileDialog::new().add_filter(&project, &project_exts).set_file_name(name).save_file().map(path).into_iter().collect()
|
||||
}
|
||||
FileDialog::SaveAs { filter, exts, name } => {
|
||||
rfd::FileDialog::new().add_filter(&filter, &exts).set_file_name(name).save_file().map(path).into_iter().collect()
|
||||
|
|
@ -492,6 +489,29 @@ fn run_dialog_off_thread(dialog: filmcraft_ui_egui::native_dialogs::FileDialog)
|
|||
rx
|
||||
}
|
||||
|
||||
/// A dialog as the Linux dialog thread shows it: filter names translated (here, on the UI thread:
|
||||
/// the interface language is per thread) and every extension list turned into the
|
||||
/// case-insensitive patterns the synchronous pickers use, so `CLIP.MP4` stays visible (#262).
|
||||
#[cfg(target_os = "linux")]
|
||||
fn prepare_dialog(dialog: filmcraft_ui_egui::native_dialogs::FileDialog) -> filmcraft_ui_egui::native_dialogs::FileDialog {
|
||||
use filmcraft_ui_egui::native_dialogs::FileDialog;
|
||||
let t = |s: &str| filmcraft_ui_egui::i18n::t(s).to_string();
|
||||
let patterns = |exts: Vec<String>| file_filters::extensions(&exts.iter().map(String::as_str).collect::<Vec<_>>());
|
||||
match dialog {
|
||||
FileDialog::OpenFiles { exts } => FileDialog::OpenFiles { exts: patterns(exts) },
|
||||
FileDialog::OpenFile { filter, exts } => FileDialog::OpenFile { filter: t(&filter), exts: patterns(exts) },
|
||||
FileDialog::SaveAs { filter, exts, name } => FileDialog::SaveAs { filter: t(&filter), exts: patterns(exts), name },
|
||||
FileDialog::Relink { exts, hint } => FileDialog::Relink { exts: patterns(exts), hint },
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
/// The project dialogs' filter patterns (`EDIT.FCPROJ` included).
|
||||
#[cfg(target_os = "linux")]
|
||||
fn project_patterns() -> Vec<String> {
|
||||
file_filters::extensions(&["fcproj"])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// Start-up registers the hardware decoders whether or not anything is logged (no logger is
|
||||
|
|
@ -505,4 +525,31 @@ mod tests {
|
|||
|| (cfg!(target_os = "linux") && matches!(hardware, filmcraft_platform::Availability::Available(_)));
|
||||
assert_eq!(filmcraft_platform::registered(), expected, "{hardware:?}");
|
||||
}
|
||||
|
||||
/// #262 on Linux: the dialogs shown off the UI thread (#260) filter with the same
|
||||
/// case-insensitive patterns as the synchronous pickers, so upper- and mixed-case files show.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn off_thread_dialogs_keep_case_insensitive_filters() {
|
||||
use filmcraft_ui_egui::RelinkHint;
|
||||
use filmcraft_ui_egui::native_dialogs::FileDialog;
|
||||
let mp4 = || vec!["mp4".to_string()];
|
||||
let hint = RelinkHint { command: "media.relink".into(), params: serde_json::json!({}) };
|
||||
for dialog in [
|
||||
FileDialog::OpenFiles { exts: mp4() },
|
||||
FileDialog::OpenFile { filter: "Media".into(), exts: mp4() },
|
||||
FileDialog::SaveAs { filter: "Media".into(), exts: mp4(), name: "clip.mp4".into() },
|
||||
FileDialog::Relink { exts: mp4(), hint },
|
||||
] {
|
||||
let exts = match super::prepare_dialog(dialog) {
|
||||
FileDialog::OpenFiles { exts } | FileDialog::OpenFile { exts, .. } | FileDialog::SaveAs { exts, .. } | FileDialog::Relink { exts, .. } => exts,
|
||||
other => panic!("the dialog changed kind: {other:?}"),
|
||||
};
|
||||
assert_eq!(exts.first().map(String::as_str), Some("mp4"), "the literal extension stays first (save suffix)");
|
||||
assert!(exts.iter().any(|e| e == "[mM][pP]4"), "{exts:?}");
|
||||
}
|
||||
let project = super::project_patterns();
|
||||
assert_eq!(project.first().map(String::as_str), Some("fcproj"));
|
||||
assert!(project.iter().any(|e| e == "[fF][cC][pP][rR][oO][jJ]"), "{project:?}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue