forked from 1b-agent/opencadstudio-upstream
fix(styles): reload Table/MLine buffers on structural ops, validate cell text style
style_new/copy/delete funneled through a load_style_bufs no-op for Table/MLine, leaving stale editor buffers pointed at the fresh style; both arms now route to the existing loaders. Table cell text-style typos persisted as dangling names; unknown names are now rejected with command-line feedback, keeping the buffer text for correction. Silent numeric parse-drops deliberately untouched (codebase-wide keep-old-valid norm). Tests: table_new_reloads_cell_buffers plus table_cell_unknown_text_style_is_rejected incl. retention assert (RED each verified by temporary revert). Full suite: 2048 passed / 0 failed / 25 ignored, zero warnings.
This commit is contained in:
1 parent
2c2bb9bba5
commit
2824b2943f
3 files changed
+79
-3
No files matched your search
@@ -309,7 +309,8 @@ impl OpenCADStudio {
|
||||
StyleKind::Text => self.load_textstyle_bufs(i),
|
||||
StyleKind::Dim => self.load_dimstyle_bufs(i),
|
||||
StyleKind::MLeader => self.load_mleaderstyle_bufs(i),
|
||||
StyleKind::Table | StyleKind::MLine => {}
|
||||
StyleKind::Table => self.load_tablestyle_bufs(i),
|
||||
StyleKind::MLine => self.load_mlstyle_bufs(i),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4924,6 +4924,68 @@ mod tablestyle_ribbon_tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tablestyle_buffer_tests {
|
||||
// #53: New/Copy/Delete must reload Table/MLine buffers (no stale edits
|
||||
// into the fresh style), and cell text-style typos must not persist.
|
||||
use crate::app::{OpenCADStudio, StyleKind};
|
||||
|
||||
#[test]
|
||||
fn table_new_reloads_cell_buffers() {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
app.ts_cell_textstyle[0] = "STALE_SENTINEL".to_string();
|
||||
app.style_new(StyleKind::Table);
|
||||
assert_ne!(
|
||||
app.ts_cell_textstyle[0], "STALE_SENTINEL",
|
||||
"buffers must reload from the fresh style"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_cell_unknown_text_style_is_rejected() {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
let i = app.active_tab;
|
||||
let style_name = app
|
||||
.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.objects
|
||||
.values()
|
||||
.find_map(|o| match o {
|
||||
codec::objects::ObjectType::TableStyle(s) => Some(s.name.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.expect("fresh doc ships a table style");
|
||||
app.tablestyle_selected = style_name.clone();
|
||||
app.ts_cell_textstyle[0] = "NOPE".to_string();
|
||||
let before = app.command_line.history.len();
|
||||
let _ = app.on_table_style_cell_apply(0);
|
||||
let cell_name = app.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.objects
|
||||
.values()
|
||||
.find_map(|o| match o {
|
||||
codec::objects::ObjectType::TableStyle(s) if s.name == style_name => {
|
||||
Some(s.data_row_style.text_style_name.clone())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap();
|
||||
assert_ne!(cell_name, "NOPE", "dangling name must not persist");
|
||||
assert_eq!(
|
||||
app.ts_cell_textstyle[0], "NOPE",
|
||||
"rejected text stays in the buffer for correction"
|
||||
);
|
||||
assert!(
|
||||
app.command_line.history.len() > before,
|
||||
"rejection must say something"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod plot_style_ctb_guard_tests {
|
||||
use crate::app::OpenCADStudio;
|
||||
|
||||
+15
-2
@@ -692,12 +692,20 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
self.ts_border_spacing[r][b].trim().parse().ok(),
|
||||
)
|
||||
});
|
||||
// Reject dangling references: a typo must not persist as a text
|
||||
// style that does not exist (#53). Decided up front so the
|
||||
// cell borrow below does not conflict with command-line I/O.
|
||||
let ts_known = ts.is_empty()
|
||||
|| self.tabs[i].scene.document.text_styles.iter().any(|s| {
|
||||
s.name.eq_ignore_ascii_case(&ts)
|
||||
});
|
||||
let ts_rejected = !ts.is_empty() && !ts_known;
|
||||
if let Some(c) = self
|
||||
.tablestyle_mut(i)
|
||||
.and_then(|s| Self::ts_cell_of(s, row))
|
||||
{
|
||||
if !ts.is_empty() {
|
||||
c.text_style_name = ts;
|
||||
if !ts.is_empty() && ts_known {
|
||||
c.text_style_name = ts.clone();
|
||||
}
|
||||
if let Some(h) = height {
|
||||
c.text_height = h;
|
||||
@@ -729,6 +737,11 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ts_rejected {
|
||||
self.command_line.push_error(
|
||||
crate::tf!("Unknown text style '{ts}'.").as_ref(),
|
||||
);
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user