fix: keep layer rename state in sync

This commit is contained in:
NgoQuocViet2001 2026-08-15 15:56:15 +07:00
commit 9c6adedc44

View file

@ -1103,9 +1103,11 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.get(idx) .get(idx)
.map(|l| l.name.clone()) .map(|l| l.name.clone())
.unwrap_or_default(); .unwrap_or_default();
let case_only_rename = new_name.eq_ignore_ascii_case(&old_name);
if !new_name.is_empty() if !new_name.is_empty()
&& new_name != old_name && new_name != old_name
&& !self.tabs[i].scene.document.layers.contains(&new_name) && (case_only_rename
|| !self.tabs[i].scene.document.layers.contains(&new_name))
{ {
self.push_undo_snapshot(i, "LAYER RENAME"); self.push_undo_snapshot(i, "LAYER RENAME");
// Keep the whole record (handle, color, linetype, // Keep the whole record (handle, color, linetype,
@ -1113,21 +1115,28 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// renamed layer still has a valid handle and survives a // renamed layer still has a valid handle and survives a
// DWG save (issue #67). // DWG save (issue #67).
if let Some(mut nl) = if let Some(mut nl) =
self.tabs[i].scene.document.layers.get(&old_name).cloned() self.tabs[i].scene.document.layers.remove(&old_name)
{ {
nl.name = new_name.clone(); nl.name = new_name.clone();
if !nl.handle.is_valid() { if !nl.handle.is_valid() {
nl.handle = self.tabs[i].scene.document.allocate_handle(); nl.handle = self.tabs[i].scene.document.allocate_handle();
} }
let _ = self.tabs[i].scene.document.layers.add(nl); let _ = self.tabs[i].scene.document.layers.add(nl);
} for e in self.tabs[i].scene.document.entities_mut() {
self.tabs[i].scene.document.layers.remove(&old_name); if e.as_entity().layer() == old_name {
for e in self.tabs[i].scene.document.entities_mut() { e.as_entity_mut().set_layer(new_name.clone());
if e.as_entity().layer() == old_name { }
e.as_entity_mut().set_layer(new_name.clone());
} }
if self.tabs[i]
.active_layer
.eq_ignore_ascii_case(&old_name)
{
self.tabs[i].active_layer = new_name.clone();
self.tabs[i].scene.document.header.current_layer_name =
new_name.clone();
}
self.tabs[i].dirty = true;
} }
self.tabs[i].dirty = true;
} }
let doc_layers = self.tabs[i].scene.document.layers.clone(); let doc_layers = self.tabs[i].scene.document.layers.clone();
let vp_info = self.tabs[i].scene.viewport_list(); let vp_info = self.tabs[i].scene.viewport_list();
@ -2604,3 +2613,64 @@ fn block_attr_prompts(
} }
map map
} }
#[cfg(test)]
mod layer_rename_tests {
use crate::app::OpenCADStudio;
fn app_with_editing_layer() -> OpenCADStudio {
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
let _ = app.on_layer_new();
app
}
#[test]
fn current_layer_rename_updates_active_layer() {
let mut app = app_with_editing_layer();
let i = app.active_tab;
let idx = app.tabs[i]
.layers
.editing
.expect("new layer is being edited");
app.tabs[i].layers.selected = Some(idx);
let _ = app.on_layer_set_current();
app.tabs[i].layers.editing = Some(idx);
app.tabs[i].layers.edit_buf = "Renamed".to_string();
let _ = app.on_layer_rename_commit();
assert_eq!(app.tabs[i].active_layer, "Renamed");
assert_eq!(
app.tabs[i].scene.document.header.current_layer_name,
"Renamed"
);
assert_eq!(app.tabs[i].layers.current_layer, "Renamed");
assert_eq!(app.ribbon.active_layer, "Renamed");
}
#[test]
fn layer_rename_allows_case_only_change() {
let mut app = app_with_editing_layer();
let i = app.active_tab;
assert!(app.tabs[i].layers.editing.is_some());
app.tabs[i].layers.edit_buf = "TEST".to_string();
let _ = app.on_layer_rename_commit();
let idx = app.tabs[i]
.layers
.layers
.iter()
.position(|layer| layer.name == "TEST")
.expect("first rename succeeded");
app.tabs[i].layers.editing = Some(idx);
app.tabs[i].layers.edit_buf = "test".to_string();
let _ = app.on_layer_rename_commit();
assert!(app.tabs[i].scene.document.layers.get("test").is_some());
assert_eq!(
app.tabs[i].scene.document.layers.get("test").unwrap().name,
"test"
);
}
}