mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-10 04:19:48 -06:00
Engine: a Python cell that keeps only its value keeps its whole cached result
When a file is opened, a Python cell falls back to keeping only its value in four cases: its code is missing from the Python part or the part is damaged (the xlsx reader), its code is too long for a cell, its kept result is malformed, or its result is past the adoption budget. The first kept the values the cell spilled as plain values; the others dropped them, so values the file showed were lost. All of them now follow one rule, through Sheet::settle_spill: the anchor and every spilled cell keep their cached values as plain values, with no live spill range; a cell's own content and format are never overwritten; and the work is bounded by the spilled values stored, not by the range. The values move from the spill into the cells, so nothing is copied. The cut-by-budget test is renamed for what it now checks, the dropped-result test now expects the values kept, and the adoption warning and the file-format docs say so.
This commit is contained in:
@@ -215,6 +215,29 @@ impl Sheet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Turns the spill anchored at `anchor` into plain values, for a Python cell that keeps only
|
||||
/// its value: the range is forgotten, and each spilled value in it becomes its cell's value,
|
||||
/// unless the cell holds content of its own (its format is kept either way). The work is
|
||||
/// bounded by the spilled values stored, not by the size of the range.
|
||||
pub fn settle_spill(&mut self, anchor: CellRef) {
|
||||
let Some(r) = self.spill_ranges.remove(&anchor) else { return };
|
||||
let inside: Vec<CellRef> = self.spill.range(r.start..=r.end).map(|(c, _)| *c).filter(|c| r.contains(*c)).collect();
|
||||
for c in inside {
|
||||
let Some(v) = self.spill.remove(&c) else { continue };
|
||||
if v.is_empty() || c == anchor {
|
||||
continue;
|
||||
}
|
||||
match self.cells.get_mut(c) {
|
||||
Some(cell) if cell.has_content() => {}
|
||||
Some(cell) => cell.value = v,
|
||||
None => {
|
||||
let style = self.style_id(c);
|
||||
self.cells.set(c, Cell::styled(v, style));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Displayed value of a cell: its own value, or a spilled value.
|
||||
pub fn value(&self, c: CellRef) -> Value {
|
||||
match self.cells.get(c) {
|
||||
|
||||
Reference in New Issue
Block a user