Missing Fonts: a folder the search refuses says why in the dialog, not "Not found" (part of #2200)

This commit is contained in:
Marco Arnulfo
2026-10-17 14:43:14 +07:00
committed by bflatastic
parent 08dc614938
commit cb968353a5
3 changed files with 49 additions and 3 deletions
+2 -1
View File
@@ -279,7 +279,8 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
touched.push(json!(i));
}
}
if files.is_empty() && !state.is_empty() {
// A failed search (a folder it refuses) didn't look: `progress` says why.
if files.is_empty() && !state.is_empty() && state != "failed" {
widgets::dim_label(ui, if searching { tl!("Searching…") } else { tl!("Not found") });
}
ui.add_space(3.0);
+6 -2
View File
@@ -264,7 +264,8 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
}
ui.add(egui::Label::new(egui::RichText::new(path).size(11.0).color(t.text_dim)).truncate()).on_hover_text(path);
}
if files.is_empty() && !state.is_empty() {
// A failed search (a folder it refuses) didn't look: `progress` says why.
if files.is_empty() && !state.is_empty() && state != "failed" {
widgets::dim_label(ui, if searching { tl!("Searching…") } else { tl!("Not found") });
}
ui.add_space(3.0);
@@ -326,11 +327,14 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
}
/// A folder search's progress under the dialog's buttons (fields `state`, `folder`, `searched`,
/// `skipped`, `unreadable` and `stopped`), in Find Linked Files too.
/// `skipped`, `unreadable`, `stopped` and `error`), in Find Linked Files too.
pub(super) fn progress(ui: &mut egui::Ui, d: &Dialog) {
if d.str("state") == "searching" {
widgets::dim_name(ui, &d.str("folder"));
}
if let Some(e) = d.fields.get("error").and_then(Value::as_str) {
widgets::dim_name(ui, &crate::i18n::message(crate::i18n::current(), e));
}
if let Some(s) = d.fields.get("searched") {
let (folders, files) = (s["folders"].to_string(), s["files"].to_string());
widgets::dim_name(
+41
View File
@@ -862,3 +862,44 @@ fn only_picks_shows_the_hosts_dialogs() {
let found: Vec<String> = scanned.iter().flat_map(|(file, code)| in_line_dialogs(code).into_iter().map(move |c| format!("{file}: {c}"))).collect();
assert!(found.is_empty(), "file dialogs shown in line, not through `picks`: {found:#?}");
}
/// #2200: Missing Fonts › Find in Folder… (a sheet on macOS) on a folder the search refuses, a
/// home folder's Library where font tools leave fonts to test: the dialog says why. Without it
/// the dialog reads as before the folder was picked, only with "Not found" under each font, and
/// the reason is in the status bar alone.
#[test]
fn missing_fonts_says_why_the_folder_picked_wasnt_searched() {
let (mut app, shown, _) = app();
app.services.read = Some(Box::new(|p: &str| std::fs::read(p).map_err(|e| e.to_string())));
app.services.write = None;
let root = std::fs::canonicalize(vectorcraft_testkit::temp_dir("missing-fonts-refused")).unwrap();
app.run("file.new", json!({"width": 400, "height": 300})).unwrap();
app.run("text.create", json!({"x": 10, "y": 40, "text": "Type", "font": "Findme Sans 3"})).unwrap();
let doc = root.join("doc.vectorcraft");
app.run("document.save", json!({"path": doc.to_string_lossy()})).unwrap();
app.session.execute("file.close", &json!({})).unwrap();
crate::io::open_path(&mut app, &doc.to_string_lossy()).unwrap();
assert_eq!(dialog_kind(&app), Some("missingFonts"));
// The test's folder is the home folder: its Library holds other apps' folders.
app.session.search_rules = Some(vectorcraft_engine::cmd::findfiles::Rules { home: Some(root.clone()), ..Default::default() });
let fonts = root.join("Library").join("Application Support").join("Font Tool").join("Export");
std::fs::create_dir_all(&fonts).unwrap();
std::fs::write(fonts.join("Findme.otf"), vectorcraft_testkit::fonts::renamed("Findme Sans 3")).unwrap();
click(&mut app, "Find in Folder…", dialogs);
assert_eq!(shown.requests(), [PickRequest::Folder]);
shown.answer(&[&fonts.to_string_lossy()]);
let ctx = egui::Context::default();
let until = std::time::Instant::now() + std::time::Duration::from_secs(10);
loop {
app_frame(&ctx, &mut app, false);
let searching = app.ui.dialog.as_ref().is_some_and(|d| d.str("state") == "searching");
if !searching || std::time::Instant::now() > until {
break;
}
std::thread::sleep(std::time::Duration::from_millis(5));
}
assert_eq!(app.ui.dialog.as_ref().map(|d| d.str("state")).as_deref(), Some("failed"));
let text = crate::tests_labels::painted_text(&mut app, |app, ui| crate::dialogs::show(app, ui.ctx()));
assert!(text.contains("VectorCraft doesn't search other apps' or the system's folders"), "{text}");
assert!(!text.contains("Not found"), "the folder wasn't searched: {text}");
}