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.
This commit is contained in:
dotCooCoo
2026-11-12 15:59:19 -08:00
parent 5beed58f0f
commit 12c4c06fc1
3 changed files with 38 additions and 4 deletions
+3 -2
View File
@@ -66,8 +66,9 @@ pub fn export(app: &mut VectorcraftApp, format: Option<&str>, path: Option<Strin
// encoder is told the file it writes (an exporter plug-in gets its name and extension).
let label = format!("Exporting {}", fileio::file_name(&path));
// A PDF's View PDF after saving: the first file written opens in the system viewer, unless
// automation asked for the export (checked now: a background export ends after the request).
let view = params.get("viewAfterSaving").and_then(Value::as_bool).unwrap_or(false) && app.refuse_automation("viewAfterSaving").is_ok();
// automation asked for the export, also through a save panel it opened (checked now: a
// background export ends after the request).
let view = params.get("viewAfterSaving").and_then(Value::as_bool).unwrap_or(false) && !app.automation_asked();
let (mut params, target) = (params.clone(), path.clone());
if let Some(o) = params.as_object_mut() {
o.insert("path".into(), json!(path));
+3 -2
View File
@@ -472,8 +472,9 @@ pub fn save_pdf(app: &mut VectorcraftApp, mode: SaveMode, mut params: Value) ->
/// 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));
}
}
+32
View File
@@ -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::<String>::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();