diff --git a/crates/ui-egui/src/panels/variables.rs b/crates/ui-egui/src/panels/variables.rs index 160d0fe0a..ca1fc29f6 100644 --- a/crates/ui-egui/src/panels/variables.rs +++ b/crates/ui-egui/src/panels/variables.rs @@ -317,10 +317,10 @@ pub fn menu(app: &mut VectorcraftApp, ui: &mut Ui) { } ui.separator(); if widgets::menu_item(ui, tl!("Import Data Sets…"), true, false) { - import_datasets(app); + crate::picks::button(app, import_datasets); } if widgets::menu_item(ui, tl!("Export Data Sets…"), !vars.is_empty(), false) { - export_datasets(app); + crate::picks::button(app, export_datasets); } ui.separator(); // What the highlighted variable drives, selected — its bindings are left alone. diff --git a/crates/ui-egui/src/tests_picks.rs b/crates/ui-egui/src/tests_picks.rs index 2c071fa2f..e2198699a 100644 --- a/crates/ui-egui/src/tests_picks.rs +++ b/crates/ui-egui/src/tests_picks.rs @@ -221,6 +221,33 @@ fn load_profile_asks_off_the_ui_thread() { assert!(app.ui.status.contains("/no/such/profile.icc"), "color.loadProfile ran on the path: {}", app.ui.status); } +/// The Variables panel menu's Import Data Sets… and Export Data Sets… ask off the UI thread: the +/// data sets in the file picked are loaded, and the data sets are written to the path the dialog +/// answers. +#[test] +fn variables_panel_data_sets_ask_off_the_ui_thread() { + let (mut app, shown, _) = app(); + app.run("file.new", json!({"width": 100, "height": 80})).unwrap(); + let dir = std::env::temp_dir().join(format!("vc-picks-data-sets-{}", std::process::id())); + std::fs::create_dir_all(&dir).unwrap(); + let (csv, out) = (dir.join("sets.csv"), dir.join("out.csv")); + std::fs::write(&csv, "name,Name\nB,y\n").unwrap(); + let sets = |app: &VectorcraftApp| app.session.doc().unwrap().doc.variables.datasets.iter().map(|d| d.name.clone()).collect::>(); + + click(&mut app, "Import Data Sets…", crate::panels::variables::menu); + assert!(matches!(shown.requests().as_slice(), [PickRequest::Open(_)])); + shown.answer(&[&csv.to_string_lossy()]); + poll(&mut app); + assert_eq!(sets(&app), ["B"], "{}", app.ui.status); + + click(&mut app, "Export Data Sets…", crate::panels::variables::menu); + assert!(matches!(shown.requests().as_slice(), [PickRequest::Save(_)])); + shown.answer(&[&out.to_string_lossy()]); + poll(&mut app); + assert!(std::fs::read_to_string(&out).is_ok_and(|text| text.starts_with("name,Name\n")), "{}", app.ui.status); + let _ = std::fs::remove_dir_all(dir); +} + /// The Swatches libraries menu's Other Library… asks off the UI thread; the file picked (another /// document) loads as a library and opens in the library panel. #[test]