UPDATEFIELD: an undo step on every run

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-10-07 11:03:57 +03:00
1 parent 6da3fea563
commit ac186d3967
4 files changed
+18 -5

No files matched your search

+3 -1
View File
@@ -546,6 +546,9 @@ impl OpenCADStudio {
/// its attributes and the texts of its block definition; a table, the
/// cell texts of its drawing (its `*T` block).
fn update_fields(&mut self, i: usize, handles: &[Handle]) {
// Every run is an undo step, as in the reference, even with nothing
// selected, no field found or no value changed.
self.push_undo_mark(i, "UPDATEFIELD");
if handles.is_empty() {
return;
}
@@ -588,7 +591,6 @@ impl OpenCADStudio {
}
// The reference counts fields, not the texts holding them, and
// reports every field it evaluated as updated, changed or not.
self.push_undo_snapshot(i, "UPDATEFIELD");
let (changed, found) = self.tabs[i].scene.update_fields(32, Some(&hosts));
if changed > 0 {
self.tabs[i].dirty = true;
+2
View File
@@ -901,4 +901,6 @@ pub(super) struct PendingHistorySnapshot {
pub(super) dirty_before: bool,
pub(super) structure_before: CadDocument,
pub(super) recorder: Arc<codec::document::EntityChangeRecorder>,
/// Kept as an undo step even when nothing changed.
pub(super) keep_empty: bool,
}
+12 -1
View File
@@ -313,7 +313,8 @@ impl OpenCADStudio {
let selected_after: Vec<Handle> = self.tabs[i].scene.selected.iter().copied().collect();
let dirty_after = self.tabs[i].dirty;
let active_layer_after = self.tabs[i].active_layer.clone();
if entities.is_empty()
if !pending.keep_empty
&& entities.is_empty()
&& !structure_changed
&& pending.selected_before == selected_after
&& pending.dirty_before == dirty_after
@@ -365,9 +366,19 @@ impl OpenCADStudio {
dirty_before,
structure_before,
recorder,
keep_empty: false,
});
}
/// [`Self::push_undo_snapshot`] for a command that is an undo step even
/// when it changes nothing (UNDO and U then name it and undo nothing).
pub(super) fn push_undo_mark(&mut self, i: usize, label: impl Into<String>) {
self.push_undo_snapshot(i, label);
if let Some(pending) = self.tabs[i].history.pending.as_mut() {
pending.keep_empty = true;
}
}
/// Begin undo capture for an entity edit that will touch `touched` entities.
/// Starts a cheap Scene delta recording and returns the pre-command state to
/// pass to [`OpenCADStudio::commit_undo_delta`] after the mutation. A command
+1 -3
View File
@@ -434,9 +434,7 @@ impl CadCommand for UpdateFieldCommand {
}
fn on_enter(&mut self) -> CmdResult {
if self.selected.is_empty() {
return CmdResult::Cancel;
}
// An empty selection still runs (the reference keeps an undo step).
let handles: Vec<String> = self.selected.iter().map(|h| format!("{:X}", h.value())).collect();
CmdResult::Dispatch(format!("_UPDATEFIELDRUN {}", handles.join(",")))
}