mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-25 18:27:02 -06:00
Save: warn when SVG keeps only one of several artboards
A document with more than one artboard saved as SVG/SVGZ without Preserve Editing Capabilities is written as one artboard and reopens with one, so the others were lost without a word. The save now says so (first, since the status bar shows only the first warning) and names the two ways to keep them all. Refs storytold/vectorcraft#2091 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
f106f32af4
commit
c2a605ce8e
@@ -322,6 +322,19 @@ fn fidelity_warning(f: &Format) -> Option<String> {
|
||||
})
|
||||
}
|
||||
|
||||
/// What an SVG save loses of a document with several artboards: the file is one artboard and
|
||||
/// reopens as one, unless it carries the native document (Preserve Editing Capabilities).
|
||||
fn artboards_warning(f: &Format, doc: &Document, params: &Value) -> Option<String> {
|
||||
let n = doc.artboards.len();
|
||||
let preserved = super::svg::options_map(params).ok().and_then(|m| m.get("preserveEditing").and_then(Value::as_bool)).unwrap_or(false);
|
||||
(is_svg(f) && n > 1 && !preserved).then(|| {
|
||||
format!(
|
||||
"{} keeps 1 of the document's {n} artboards (the first, unless one is chosen) and reopens with only that one: turn on Preserve Editing Capabilities or save as VectorCraft to keep them all",
|
||||
f.label
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// A save of the active document, snapshotted and ready to encode and write anywhere (Background
|
||||
/// Save does both on a worker thread): [`save_job`], then [`SaveJob::write`], then
|
||||
/// [`SaveJob::finish`]. Cheap to clone (the documents are shared).
|
||||
@@ -549,7 +562,9 @@ impl SaveJob {
|
||||
let one = self.encode_one(&artboard_doc(&self.doc, b))?;
|
||||
enc.files.extend(one.files.into_iter().map(|(_, bytes)| (Some(b), bytes)));
|
||||
}
|
||||
enc.warnings.splice(0..0, fidelity_warning(self.plan.format));
|
||||
// Lost artboards first: the status bar shows only the first warning.
|
||||
let f = self.plan.format;
|
||||
enc.warnings.splice(0..0, artboards_warning(f, &self.doc, &self.params).into_iter().chain(fidelity_warning(f)));
|
||||
Ok(enc)
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,23 @@ fn preserve_editing_reopens_the_native_document() {
|
||||
assert_eq!(s.doc().unwrap().doc.artboards.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn saving_several_artboards_as_plain_svg_warns_they_are_lost() {
|
||||
let artboards = |r: &Value| r["warnings"].as_array().unwrap().iter().filter(|w| w.as_str().unwrap().contains("artboards")).count();
|
||||
let mut s = session(3);
|
||||
let r = s.execute("document.save", &json!({"format": "svg"})).unwrap();
|
||||
assert_eq!(artboards(&r), 1, "{r}");
|
||||
// First: the status bar shows only the first warning.
|
||||
assert!(r["warnings"][0].as_str().unwrap().contains("1 of the document's 3 artboards"), "{r}");
|
||||
assert_eq!(artboards(&s.execute("file.saveAs", &json!({"format": "svgz"})).unwrap()), 1);
|
||||
// Preserve Editing keeps them all (they reopen); a single artboard loses none.
|
||||
for p in [json!({"format": "svg", "preserveEditing": true}), json!({"format": "svg", "svg": {"preserveEditing": true}})] {
|
||||
let r = s.execute("document.save", &p).unwrap();
|
||||
assert_eq!(artboards(&r), 0, "{p}: {r}");
|
||||
}
|
||||
assert_eq!(artboards(&session(1).execute("document.save", &json!({"format": "svg"})).unwrap()), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_writes_svg_and_remembers_its_options() {
|
||||
let mut s = session(1);
|
||||
|
||||
Reference in New Issue
Block a user