From 12c4c06fc120c82a00e571ac05ed23b8eba655d8 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Thu, 12 Nov 2026 15:59:19 -0800 Subject: [PATCH] Save PDF: a PDF automation asked for stays closed after its save panel answers View PDF after Saving checked only whether automation was acting at that moment. When automation asked for Save as PDF without a path, the save panel's answer arrives later, so the written PDF opened in the system viewer. The check now uses automation_asked, which also covers the answer of a save panel automation opened, in view_file and in Export As. --- crates/ui-egui/src/io/export.rs | 5 +++-- crates/ui-egui/src/io/save.rs | 5 +++-- crates/ui-egui/src/tests/picks.rs | 32 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/crates/ui-egui/src/io/export.rs b/crates/ui-egui/src/io/export.rs index 2a23c7e1bf..5050529039 100644 --- a/crates/ui-egui/src/io/export.rs +++ b/crates/ui-egui/src/io/export.rs @@ -66,8 +66,9 @@ pub fn export(app: &mut VectorcraftApp, format: Option<&str>, path: Option /// Open a written file in the system viewer (not on the web, which downloads it). pub(super) fn view_file(app: &mut VectorcraftApp, path: &str) { - // The viewer is another app: an export automation asked for is written but not opened. - if !is_web(app) && app.refuse_automation("viewAfterSaving").is_ok() { + // The viewer is another app: an export automation asked for is written but not opened, also + // when it goes on from a save panel automation opened. + if !is_web(app) && !app.automation_asked() { app.open_url(&file_url(path)); } } diff --git a/crates/ui-egui/src/tests/picks.rs b/crates/ui-egui/src/tests/picks.rs index 90e6fdc78d..e808cf2463 100644 --- a/crates/ui-egui/src/tests/picks.rs +++ b/crates/ui-egui/src/tests/picks.rs @@ -210,6 +210,38 @@ fn save_as_goes_on_with_the_path_picked() { assert_eq!(*written.borrow(), ["/art/poster.svg"]); } +/// Save as PDF with View PDF after Saving, asked for by automation without a path: the save panel +/// it opened answers as automation's, so the PDF is written but not opened in the viewer, even +/// when a person picked the file. The person's own Save as PDF opens it. +#[test] +fn a_pdf_automation_asked_for_is_not_opened_when_its_save_panel_answers() { + let opened = Rc::new(RefCell::new(Vec::::new())); + let u = opened.clone(); + let mut services = + Services { dialogs_are_sheets: true, open_url: Some(Box::new(move |p: &str| u.borrow_mut().push(p.to_string()))), ..Default::default() }; + let (shown, written) = off_the_ui_thread(&mut services); + let mut app = VectorcraftApp::new(Session::new(), services); + app.run("file.new", json!({"width": 100, "height": 80})).unwrap(); + app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 30, "height": 20})).unwrap(); + let view = json!({"viewAfterSaving": true}); + + app.ui.answering_control = true; + let _ = app.run("file.export.pdf", view.clone()); + app.ui.answering_control = false; + assert!(matches!(shown.requests().as_slice(), [PickRequest::Save(_)])); + shown.answer(&["/art/automated.pdf"]); + poll(&mut app); + assert_eq!(*written.borrow(), ["/art/automated.pdf"]); + assert!(opened.borrow().is_empty(), "{:?}", opened.borrow()); + + let _ = app.run("file.export.pdf", view); + shown.answer(&["/art/mine.pdf"]); + poll(&mut app); + assert_eq!(*written.borrow(), ["/art/automated.pdf", "/art/mine.pdf"]); + assert_eq!(opened.borrow().len(), 1, "{:?}", opened.borrow()); + assert!(opened.borrow()[0].ends_with("/art/mine.pdf"), "{:?}", opened.borrow()); +} + #[test] fn a_dialogs_folder_button_fills_its_field_when_the_picker_answers() { let (mut app, shown, _) = app();