forked from 1b-agent/opencadstudio-upstream
Implement DELOBJ source deletion policies
This commit is contained in:
1 parent
f69f0b32be
commit
10d1d9b7d9
7 files changed
+196
-19
No files matched your search
@@ -1113,7 +1113,8 @@ impl OpenCADStudio {
|
||||
use acadrust::entities::Region;
|
||||
use acadrust::types::Vector3;
|
||||
let mut regions = Vec::new();
|
||||
for (_, e) in self.tabs[i].scene.selected_entities().iter() {
|
||||
let mut sources = Vec::new();
|
||||
for (handle, e) in self.tabs[i].scene.selected_entities().iter() {
|
||||
let supported = matches!(
|
||||
e,
|
||||
acadrust::EntityType::LwPolyline(pl)
|
||||
@@ -1136,6 +1137,7 @@ impl OpenCADStudio {
|
||||
);
|
||||
region.common.layer = self.tabs[i].active_layer.clone();
|
||||
regions.push((region, body));
|
||||
sources.push(*handle);
|
||||
}
|
||||
}
|
||||
if regions.is_empty() {
|
||||
@@ -1154,6 +1156,10 @@ impl OpenCADStudio {
|
||||
}
|
||||
created.push(handle);
|
||||
}
|
||||
if self.delete_objects != 0 {
|
||||
self.tabs[i].scene.erase_entities(&sources);
|
||||
self.refresh_properties();
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line
|
||||
.push_output(crate::tf!("REGION: created {count} region(s).").as_ref());
|
||||
@@ -1530,3 +1536,47 @@ impl OpenCADStudio {
|
||||
Some(self.finish_dispatch(cmd))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod region_tests {
|
||||
use crate::app::OpenCADStudio;
|
||||
|
||||
#[test]
|
||||
fn region_respects_delobj_and_preserves_unconverted_sources() {
|
||||
for delete_sources in [false, true] {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
app.automation_op(r#"{"op":"run","cmd":"CIRCLE 5,5 3"}"#);
|
||||
app.automation_op(r#"{"op":"run","cmd":"LINE 0,0 10,10"}"#);
|
||||
let i = app.active_tab;
|
||||
let sources: Vec<_> = app.tabs[i].scene.document.entities()
|
||||
.map(|entity| {
|
||||
(entity.common().handle, matches!(entity, acadrust::EntityType::Circle(_)))
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(sources.len(), 2);
|
||||
let handles: Vec<_> = sources.iter().map(|(handle, _)| *handle).collect();
|
||||
app.tabs[i].scene.select_entities(&handles);
|
||||
app.delete_objects = i16::from(delete_sources);
|
||||
|
||||
let _ = app.dispatch_command("REGION");
|
||||
|
||||
for (handle, is_circle) in &sources {
|
||||
assert_eq!(
|
||||
app.tabs[i].scene.document.get_entity(*handle).is_some(),
|
||||
!delete_sources || !is_circle,
|
||||
);
|
||||
}
|
||||
let region_count = app.tabs[i].scene.document.entities()
|
||||
.filter(|entity| matches!(entity, acadrust::EntityType::Region(_)))
|
||||
.count();
|
||||
assert_eq!(region_count, 1);
|
||||
|
||||
app.automation_op(r#"{"op":"undo"}"#);
|
||||
for (handle, _) in &sources {
|
||||
assert!(app.tabs[i].scene.document.get_entity(*handle).is_some());
|
||||
}
|
||||
assert_eq!(app.tabs[i].scene.document.entities().count(), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1159,6 +1159,11 @@ impl OpenCADStudio {
|
||||
"0" | "OFF" | "FALSE" => Some(false),
|
||||
_ => None,
|
||||
};
|
||||
let current_delete_objects = self.delete_objects;
|
||||
let requested_delete_objects = (name == "DELOBJ")
|
||||
.then(|| value.as_deref()?.parse::<i16>().ok())
|
||||
.flatten()
|
||||
.filter(|value| (0..=3).contains(value));
|
||||
let outcome: Result<(String, bool), String> = {
|
||||
let h = &mut self.tabs[i].scene.document.header;
|
||||
match name.as_str() {
|
||||
@@ -1633,15 +1638,18 @@ impl OpenCADStudio {
|
||||
}
|
||||
},
|
||||
"DELOBJ" => match &value {
|
||||
Some(v) => parse_bool(v)
|
||||
.map(|b| {
|
||||
h.delete_objects = b;
|
||||
(format!("DELOBJ = {}", b as i32), true)
|
||||
Some(v) => v
|
||||
.parse::<i16>()
|
||||
.ok()
|
||||
.filter(|value| (0..=3).contains(value))
|
||||
.map(|value| {
|
||||
(format!("DELOBJ = {value}"), true)
|
||||
})
|
||||
.ok_or_else(|| "SETVAR: 0 or 1 required.".into()),
|
||||
None => {
|
||||
Ok((format!("DELOBJ = {}", h.delete_objects as i32), false))
|
||||
}
|
||||
.ok_or_else(|| "SETVAR: integer from 0 to 3 required.".into()),
|
||||
None => Ok((
|
||||
format!("DELOBJ = {current_delete_objects}"),
|
||||
false,
|
||||
)),
|
||||
},
|
||||
"PLINEGEN" => match &value {
|
||||
Some(v) => parse_bool(v)
|
||||
@@ -2119,6 +2127,9 @@ impl OpenCADStudio {
|
||||
};
|
||||
match outcome {
|
||||
Ok((msg, changed)) => {
|
||||
if let Some(value) = requested_delete_objects {
|
||||
self.delete_objects = value;
|
||||
}
|
||||
if changed {
|
||||
if matches!(
|
||||
name.as_str(),
|
||||
@@ -2144,6 +2155,7 @@ impl OpenCADStudio {
|
||||
| "GRIPHOT"
|
||||
| "GRIPHOVER"
|
||||
| "GRIPOBJLIMIT"
|
||||
| "DELOBJ"
|
||||
) {
|
||||
self.persist_settings_if_changed();
|
||||
} else {
|
||||
@@ -3120,4 +3132,17 @@ mod tests {
|
||||
assert!(app.tabs[app.active_tab].active_cmd.is_none());
|
||||
assert_eq!(app.commandline_fade_ms, 5000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delobj_accepts_values_zero_through_three() {
|
||||
let mut app = fresh_app();
|
||||
|
||||
for value in 0..=3 {
|
||||
let _ = app.run_command_line(&format!("SETVAR DELOBJ {value}"));
|
||||
assert_eq!(app.delete_objects, value);
|
||||
}
|
||||
|
||||
let _ = app.run_command_line("SETVAR DELOBJ 4");
|
||||
assert_eq!(app.delete_objects, 3);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user