feat(styles): make style managers transactional — persist only on Apply

A style manager is now a staged transaction. When it opens, a snapshot of
the style tables, style objects and current-style pointers is taken. Every
New / Copy / Delete / Rename / Set Current / property edit mutates the
document live so the dialog previews the result, but the tab is not marked
dirty, nothing is pushed to undo, and the drawing is not rebuilt.

- Apply commits: one undo entry (restoring the pre-edit state), the tab is
  marked dirty, the drawing rebuilds, and the baseline is reset so further
  edits stage afresh.
- Closing the window without Apply discards: the opening snapshot is
  restored, so none of the changes persist.

Side effects (dirty / undo / bump_geometry) were removed from every style
edit handler and routed exclusively through the commit. Multiline's Apply
is a structural-only commit since its editor has no editable properties.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-10 15:38:32 +03:00
commit de4eb31003
6 changed files with 205 additions and 101 deletions

View file

@ -391,6 +391,10 @@ pub(super) struct OpenCADStudio {
style_rename: Option<String>,
/// Edit buffer for the inline rename text input.
style_rename_buf: String,
/// Active style-manager transaction. Edits mutate the document live for an
/// in-dialog preview but only persist on Apply; closing without Apply
/// restores this snapshot. `None` when no style manager is staging.
style_stage: Option<style_ops::StyleStage>,
// ── TextStyle Font Browser ────────────────────────────────────────────
textstyle_selected: String,
@ -1390,6 +1394,7 @@ impl OpenCADStudio {
// TextStyle font browser
style_rename: None,
style_rename_buf: String::new(),
style_stage: None,
textstyle_selected: "Standard".to_string(),
textstyle_font: String::new(),
textstyle_width: "1.0".to_string(),