From cb968353a542249e5559124bd28dab6c7f2c5902 Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Fri, 16 Oct 2026 18:30:56 +0200 Subject: [PATCH] Missing Fonts: a folder the search refuses says why in the dialog, not "Not found" (part of #2200) --- crates/ui-egui/src/dialogs/find_links.rs | 3 +- crates/ui-egui/src/dialogs/missing_fonts.rs | 8 +++- crates/ui-egui/src/tests_picks.rs | 41 +++++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/crates/ui-egui/src/dialogs/find_links.rs b/crates/ui-egui/src/dialogs/find_links.rs index 914be0421..160721561 100644 --- a/crates/ui-egui/src/dialogs/find_links.rs +++ b/crates/ui-egui/src/dialogs/find_links.rs @@ -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); diff --git a/crates/ui-egui/src/dialogs/missing_fonts.rs b/crates/ui-egui/src/dialogs/missing_fonts.rs index 80daaf100..18dd1ab80 100644 --- a/crates/ui-egui/src/dialogs/missing_fonts.rs +++ b/crates/ui-egui/src/dialogs/missing_fonts.rs @@ -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( diff --git a/crates/ui-egui/src/tests_picks.rs b/crates/ui-egui/src/tests_picks.rs index 091f6d390..075bd5ca0 100644 --- a/crates/ui-egui/src/tests_picks.rs +++ b/crates/ui-egui/src/tests_picks.rs @@ -862,3 +862,44 @@ fn only_picks_shows_the_hosts_dialogs() { let found: Vec = 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}"); +}