diff --git a/crates/engine/src/cmd/layer.rs b/crates/engine/src/cmd/layer.rs index 1867ce90..0b462abe 100644 --- a/crates/engine/src/cmd/layer.rs +++ b/crates/engine/src/cmd/layer.rs @@ -195,10 +195,15 @@ fn run_set(s: &mut Session, p: &Value) -> Result { *l = updated; if let Some(nn) = new_name { l.name = nn.clone(); - // Re-point entities. - let hs: Vec<_> = d.model.iter().filter(|e| e.common.layer.eq_ignore_ascii_case(&old)).map(|e| e.handle).collect(); - for h in hs { - d.model.modify(h, |e| e.common.layer = nn.clone()); + // Re-point entities in model space, every layout and every block definition. + repoint(&mut d.model, &old, &nn); + for layout in &mut d.layouts { + repoint(&mut layout.entities, &old, &nn); + } + for block in d.blocks.values_mut() { + if block.entities.iter().any(|e| e.common.layer.eq_ignore_ascii_case(&old)) { + repoint(&mut std::sync::Arc::make_mut(block).entities, &old, &nn); + } } if cur.eq_ignore_ascii_case(&old) { d.header.set_str("CLAYER", &nn); @@ -207,6 +212,13 @@ fn run_set(s: &mut Session, p: &Value) -> Result { ok() } +fn repoint(store: &mut cadcraft_doc::EntityStore, old: &str, new: &str) { + let hs: Vec<_> = store.iter().filter(|e| e.common.layer.eq_ignore_ascii_case(old)).map(|e| e.handle).collect(); + for h in hs { + store.modify(h, |e| e.common.layer = new.to_string()); + } +} + fn run_current(s: &mut Session, p: &Value) -> Result { let name = str_param(p, "name").ok_or_else(|| bad("layer.current", "`name` is required"))?.to_string(); let d = s.doc_mut()?; @@ -453,4 +465,24 @@ mod tests { s.execute("purge", &json!({})).unwrap(); assert!(s.doc().unwrap().layer("A").is_some()); } + + #[test] + fn rename_repoints_paper_space_and_block_entities() { + let mut s = Session::new(); + s.execute("layer.new", &json!({ "name": "A", "color": "red", "current": true })).unwrap(); + s.execute("line", &json!({ "points": [[0, 0], [1, 1]] })).unwrap(); + s.execute("selectall", &json!({})).unwrap(); + s.execute("block", &json!({ "name": "Part", "base": [0, 0], "keep": "delete" })).unwrap(); + s.execute("layout.set", &json!({ "name": "Layout1" })).unwrap(); + s.execute("line", &json!({ "points": [[0, 0], [1, 1]] })).unwrap(); + s.execute("layer.set", &json!({ "name": "A", "newName": "B" })).unwrap(); + let d = s.doc().unwrap(); + let on_layer = |name: &str| { + let paper = d.layouts.iter().flat_map(|l| l.entities.iter()); + let blocks = d.blocks.values().flat_map(|b| b.entities.iter()); + paper.chain(blocks).filter(|e| e.common.layer == name).count() + }; + assert_eq!(on_layer("A"), 0); + assert_eq!(on_layer("B"), 2); + } }