mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-10 12:29:58 -06:00
Merge origin/main (3379f12a) into the Python cells branch
Main gained #470 (floating objects) and #501 (Solver Sensitivity report). Conflicts: - cmd/edit.rs, edit/paste_special.rs, sheet/tabs.rs: #470 adds rewrite_cell_links for chart references beside this branch's rewrite_python_refs; every structural edit, sheet rename and sheet delete runs both, the Python one last where it can refuse the edit (the edit then changes nothing). - cmd/sheet.rs: rewrite() keeps this branch's Result with main's doc comment. - model/src/sheet.rs and engine tests.rs: both sides' additions kept. - ROADMAP.md: header combined, both sides' rows kept. Main's new code writes no cells, so no Python handling was needed beyond these.
This commit is contained in:
@@ -391,9 +391,38 @@ pub(crate) fn rewrite_all_formulas(wb: &mut gridcraft_model::Workbook, target: &
|
||||
n.formula = gridcraft_formula::print(&new);
|
||||
}
|
||||
}
|
||||
rewrite_cell_links(wb, |host, expr| gridcraft_formula::adjust::adjust(expr, host, target, e));
|
||||
rewrite_python_refs(wb, &|host, expr| gridcraft_formula::adjust::adjust(expr, host, target, e))
|
||||
}
|
||||
|
||||
/// Runs `f` over every reference a floating object holds (a chart's series values, categories,
|
||||
/// name and bubble sizes, and the source block it was made from). Every edit that moves
|
||||
/// references calls it: inserting and deleting lines and cells and cut-moves (through
|
||||
/// [`rewrite_all_formulas`]), and renaming and deleting sheets. `f` maps a reference held by an
|
||||
/// object on the sheet named `host` to its new form; text that does not parse is kept. A source
|
||||
/// block that no longer exists is dropped.
|
||||
pub(crate) fn rewrite_cell_links(wb: &mut gridcraft_model::Workbook, f: impl Fn(&str, gridcraft_formula::Expr) -> gridcraft_formula::Expr) {
|
||||
for si in 0..wb.sheets.len() {
|
||||
let Some(host) = wb.sheets.get(si).filter(|s| !s.charts.is_empty()).map(|s| s.name.clone()) else { continue };
|
||||
let Some(sh) = wb.sheet_mut(si) else { continue };
|
||||
let fix = |text: &str| -> String {
|
||||
match gridcraft_formula::parse(text) {
|
||||
Ok(expr) => gridcraft_formula::print(&f(&host, expr)),
|
||||
Err(_) => text.to_string(),
|
||||
}
|
||||
};
|
||||
for ch in sh.charts.iter_mut() {
|
||||
ch.source = ch.source.as_deref().map(fix).filter(|s| !s.contains("#REF!"));
|
||||
for se in ch.series.iter_mut() {
|
||||
se.values = fix(&se.values);
|
||||
se.categories = se.categories.as_deref().map(fix);
|
||||
se.name = se.name.as_deref().map(fix);
|
||||
se.bubble_sizes = se.bubble_sizes.as_deref().map(fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Rewrites the `xl("…")` literals in every Python cell with `f`, which maps a reference held on
|
||||
/// sheet `host` to its new form. Every reference-moving edit (insert and delete of lines or cells,
|
||||
/// cut-move, sheet rename and delete) runs it, as it adjusts formulas. A literal is only replaced
|
||||
|
||||
Reference in New Issue
Block a user