M6: deleting the default radio button clears the group's default too

CodeRabbit on #4631: with /V already Off, a /DV naming the deleted button's
state was kept, so Reset would put back a state no button has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LymhVaGZCWwB9HNEbLzeMM
This commit is contained in:
Claude
2026-10-25 17:39:30 +00:00
parent 5a1b9065bc
commit 9fb07e4ac7
2 changed files with 31 additions and 0 deletions
+9
View File
@@ -1616,6 +1616,15 @@ pub fn delete_widget(doc: &mut Document, name: &str, widget: usize) -> Result<()
d.set(b"V".to_vec(), Object::name("Off"));
changed = true;
}
// The default (`/DV`, what Reset puts back) can't name a state no button has any more.
let dv_only_here = w.on_state.as_deref().is_some_and(|on| {
d.get(b"DV").map(|v| doc.resolve(v)).and_then(|v| v.as_name().map(<[u8]>::to_vec)).is_some_and(|dv| dv == on.as_bytes())
&& !f.widgets.iter().enumerate().any(|(i, o)| i != widget && o.on_state.as_deref() == Some(on))
});
if dv_only_here {
d.set(b"DV".to_vec(), Object::name("Off"));
changed = true;
}
if changed {
doc.set(f.obj, Object::Dict(d));
}
+22
View File
@@ -4654,6 +4654,28 @@ fn deleting_the_chosen_radio_button_turns_the_group_off_when_a_twin_is_not_shown
assert!(size.value.is_empty(), "no button shows S any more: {:?}", size.value);
}
#[test]
fn deleting_the_default_radio_button_clears_the_default_too() {
// The group is off, but Reset would put back Small, which no button has once it is gone.
let mut doc = radio_group_form();
let size = ObjRef::new(5, 0);
let mut d = doc.get(size).as_dict().cloned().unwrap();
d.set(b"V".to_vec(), Object::name("Off"));
d.set(b"DV".to_vec(), Object::name("S"));
doc.set(size, Object::Dict(d));
delete_widget(&mut doc, "size", 0).unwrap();
let doc = reopen(&doc);
let dv = doc.get(size).as_dict().and_then(|d| d.get(b"DV").cloned());
assert_eq!(dv, Some(Object::name("Off")));
// A default another button still has stays.
let mut doc = radio_group_form();
let mut d = doc.get(size).as_dict().cloned().unwrap();
d.set(b"DV".to_vec(), Object::name("S"));
doc.set(size, Object::Dict(d));
delete_widget(&mut doc, "size", 1).unwrap();
assert_eq!(doc.get(size).as_dict().and_then(|d| d.get(b"DV").cloned()), Some(Object::name("S")));
}
#[test]
fn deleting_one_copy_of_a_field_keeps_the_field_and_its_value() {
let mut doc = radio_group_form();