From 71df6f0fd2da6e7e9b56ca2620fc2a26c4280823 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Thu, 12 Nov 2026 14:06:35 -0800 Subject: [PATCH] Save PDF: ui.savePdfDialog refuses a useArtboards that is not true or false A value such as "false" or 0 used to open the dialog for the artboards. It is now refused before the dialog opens, as document.exportPdf refuses it. --- crates/ui-egui/src/dialogs/save_pdf.rs | 7 ++++++- crates/ui-egui/src/dialogs/save_pdf/tests.rs | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/dialogs/save_pdf.rs b/crates/ui-egui/src/dialogs/save_pdf.rs index 8e02bac956..2e19375994 100644 --- a/crates/ui-egui/src/dialogs/save_pdf.rs +++ b/crates/ui-egui/src/dialogs/save_pdf.rs @@ -83,6 +83,11 @@ pub(super) const TOP_LABEL_WIDTH: f32 = LIST_WIDTH + 26.0; /// Open the dialog with `params` (`document.exportPdf` options and `path?`) applied over their /// preset. `useArtboards: false` makes the page the bounds of the visible art. pub fn open(app: &mut VectorcraftApp, params: &Value) -> Result { + let art_bounds = match params.get("useArtboards") { + None | Some(Value::Null) => false, + Some(Value::Bool(b)) => !b, + Some(v) => return Err(format!("useArtboards must be true or false, not {v}")), + }; let mut fields = settings_fields(app, params)?; let s = |k: &str| params.get(k).and_then(Value::as_str); fields.insert("preset".into(), json!(s("preset").unwrap_or(pdf::DEFAULT_PRESET))); @@ -93,7 +98,7 @@ pub fn open(app: &mut VectorcraftApp, params: &Value) -> Result { if let Some(path) = s("path") { fields.insert("path".into(), json!(path)); } - if params.get("useArtboards") == Some(&json!(false)) { + if art_bounds { fields.insert(ART_BOUNDS.into(), json!(true)); } app.ui.dialog = Some(Dialog { kind: KIND.into(), fields }); diff --git a/crates/ui-egui/src/dialogs/save_pdf/tests.rs b/crates/ui-egui/src/dialogs/save_pdf/tests.rs index 162ee2e519..a3a6cc4768 100644 --- a/crates/ui-egui/src/dialogs/save_pdf/tests.rs +++ b/crates/ui-egui/src/dialogs/save_pdf/tests.rs @@ -130,6 +130,22 @@ fn a_page_of_the_arts_bounds_has_no_artboards_section_and_takes_the_options() { assert!(opened.borrow()[0].0.ends_with("/tmp/art.pdf")); } +/// `useArtboards` other than true, false or null is refused, as `document.exportPdf` refuses it, +/// and no dialog opens. +#[test] +fn a_use_artboards_that_is_not_true_or_false_is_refused() { + let (mut app, _, _) = app(); + for bad in [json!("false"), json!(0), json!({})] { + let e = app.run("ui.savePdfDialog", json!({"path": "/tmp/x.pdf", "useArtboards": bad})).unwrap_err(); + assert!(e.contains("useArtboards must be true or false"), "{bad}: {e}"); + assert!(app.ui.dialog.is_none(), "{bad}: no dialog opens"); + } + for ok in [json!(true), json!(null)] { + app.run("ui.savePdfDialog", json!({"path": "/tmp/x.pdf", "useArtboards": ok})).unwrap(); + assert!(!app.ui.dialog.take().unwrap().bool(ART_BOUNDS), "{ok}: the artboards' dialog"); + } +} + /// With Background Export on, a page of the art's bounds is written in the background, as Export /// As writes its other formats. #[test]