From 141c048289ac6e324fd7fd4cb3fe37b592cb5ce4 Mon Sep 17 00:00:00 2001 From: aiongg Date: Fri, 16 Oct 2026 04:01:22 +0000 Subject: [PATCH] Integration: #1062 style Preview runs the Justification spacing check OK runs, and shows its reason --- crates/ui-egui/src/dialogs.rs | 44 +++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs index c5c90db83..f55c33033 100644 --- a/crates/ui-egui/src/dialogs.rs +++ b/crates/ui-egui/src/dialogs.rs @@ -3514,13 +3514,18 @@ fn grep_error(p: &str) -> Option { designcraft_compose::grep::Grep::new(p, Default::default()).err().map(|e| e.to_string()) } -fn confirm_paragraph_style_options(app: &mut DesignApp, d: &mut Dialog) -> Result { - let name = d.s("name"); - // What the Justification section showed: the style's own values, or a new style's Based On. - let shown = if d.b("new") { d.s("basedOn") } else { name.clone() }; +/// The Justification spacing check of Paragraph Style Options, against what the section showed: +/// the style's own values, or a new style's Based On. +fn check_paragraph_style_justification(app: &DesignApp, d: &Dialog) -> Result<(), String> { + let shown = if d.b("new") { d.s("basedOn") } else { d.s("name") }; let base = app.session.active().map(|st| serde_json::to_value(st.doc.styles.resolve_para_style(&shown).0).unwrap_or_default()).unwrap_or_default(); - if let Err(e) = check_justification(d, "p.", &base) { + check_justification(d, "p.", &base) +} + +fn confirm_paragraph_style_options(app: &mut DesignApp, d: &mut Dialog) -> Result { + let name = d.s("name"); + if let Err(e) = check_paragraph_style_justification(app, d) { // The caller shows the reason in the dialog's status line. d.fields.insert("section".into(), json!("justify")); return Err(e); @@ -3593,6 +3598,16 @@ fn style_options_preview(app: &mut DesignApp, d: &mut Dialog) { return; } let paragraph = d.id == "paragraphStyleOptions"; + // Values OK would refuse don't reach the page either: the page goes back and the status + // line says why. + if paragraph && let Err(e) = check_paragraph_style_justification(app, d) { + if shown.is_some() { + app.session.cancel_interaction(); + d.fields.remove(PREVIEWED); + } + d.fields.insert("status".into(), json!(e)); + return; + } let mut params = json!({"name": d.s("name"), "chars": {}}); if paragraph { params["para"] = json!({}); @@ -7543,6 +7558,25 @@ mod tests { } } + #[test] + fn style_preview_refuses_justification_spacing_ok_would_refuse() { + let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default()); + app.run("file.new", json!({})).unwrap(); + let before = app.session.doc().unwrap().doc.clone(); + let mut d = Dialog::new( + "paragraphStyleOptions", + json!({"name": designcraft_doc::BASIC_PARAGRAPH, "preview": true, "p.wordSpaceDesired": 1.1}), + ); + style_options_preview(&mut app, &mut d); + assert_ne!(app.session.doc().unwrap().doc, before, "a valid value previews"); + // Minimum above Desired: the page goes back and the dialog says why. + d.fields.insert("p.wordSpaceMin".into(), json!(1.5)); + style_options_preview(&mut app, &mut d); + assert_eq!(app.session.doc().unwrap().doc, before); + assert!(d.s("status").contains("Word Spacing"), "{:?}", d.fields.get("status")); + assert!(app.session.doc().unwrap().interaction.is_none()); + } + #[test] fn invalid_style_preview_leaves_the_starting_document_and_can_be_cancelled() { let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());