diff --git a/crates/engine/src/cmd/fileio/save.rs b/crates/engine/src/cmd/fileio/save.rs index 2a22442c9..22ff2365f 100644 --- a/crates/engine/src/cmd/fileio/save.rs +++ b/crates/engine/src/cmd/fileio/save.rs @@ -637,17 +637,21 @@ pub(super) fn encode_ai(cmd: &str, f: &Format, doc: &Document, p: &Value) -> Res } // The art with placed files resolved as the pages draw them, also when the pages are blank. let resolved; - let art: &Document = if pdf_compatible { - &pages + let (art, mut resolved_warnings): (&Document, Vec) = if pdf_compatible { + (&pages, Vec::new()) } else { - resolved = crate::cmd::place::document::full_documents(&edited).0; - &resolved + let (d, w) = crate::cmd::place::document::full_documents(&edited); + resolved = d; + (&resolved, w) }; let o = vectorcraft_eps::AiEditingOptions { title: doc.title.clone(), created: doc.metadata.created.or_else(vectorcraft_doc::metadata::output_time), }; - vectorcraft_eps::ai_private_data(art, &o).map(Some).map_err(|e| bad(cmd, e)) + let (data, lost) = vectorcraft_eps::ai_private_data(art, &o).map_err(|e| bad(cmd, e))?; + // Placed files that weren't found are written as their previews here too. + resolved_warnings.extend(lost); + Ok(Some((data, resolved_warnings))) }; let (bytes, mut warnings) = super::pdf::encode_carrying(cmd, &pages, ¶ms, native, private)?; warnings.extend(placed_warnings); diff --git a/crates/engine/src/tests/placed_document.rs b/crates/engine/src/tests/placed_document.rs index eb3164db8..45ac24970 100644 --- a/crates/engine/src/tests/placed_document.rs +++ b/crates/engine/src/tests/placed_document.rs @@ -288,6 +288,30 @@ fn ai_export_public_aliases_preserve_missing_placed_links() { } } +/// The `.ai` editing copy for other apps draws a missing placed file as its preview, with the +/// pages or without them, and says so. +#[test] +fn ai_editing_copy_warns_about_missing_placed_files() { + let dir = Folder::new("placed-ai-editing-copy-missing"); + let src = dir.file("logo.vectorcraft"); + star_source(&src, "placed-ai-editing-copy-missing-unique"); + let mut s = session(); + place(&mut s, &src); + let parent = dir.file("parent.vectorcraft"); + save(&mut s, &parent); + std::fs::remove_file(&src).unwrap(); + open(&mut s, &parent); + let doc = &s.doc().unwrap().doc; + let (_, missing) = cmd::place::document::full_documents(doc); + assert!(!missing.is_empty()); + for compatible in [true, false] { + let enc = cmd::fileio::encode_all(doc, "ai", &json!({"pdfCompatible": compatible})).unwrap(); + for w in &missing { + assert!(enc.warnings.contains(w), "pdfCompatible {compatible}: {w:?} not in {:?}", enc.warnings); + } + } +} + /// Include Linked Files must retain relinkable objects when only their previews are available. #[test] fn native_included_links_keep_missing_placed_documents_editable() {