Merge branch 'main' into fix/1419-clear-skips-filtered-rows

This commit is contained in:
Gert Pellin
2026-10-15 22:25:42 +02:00
9 changed files with 199 additions and 7 deletions
+21 -4
View File
@@ -1260,6 +1260,9 @@ fn clear(s: &mut Session, p: &Json, what: &str) -> Result<Json> {
.sheet(sheet)
.map(|sh| sh.cells.iter_range(r).filter(|(c, _)| !skip.contains(&c.row)).map(|(c, x)| (c, x.clone())).collect())
.unwrap_or_default();
// Report every stored cell we touch, even beyond a million coordinates in a sparse
// selection. Removed formula anchors must also reach calc so their spills disappear.
cx.changed.extend(cells.iter().map(|(c, _)| (sheet, *c)));
let mut cells = cells;
if what == "contents" {
for (_, cell) in cells.iter_mut() {
@@ -1299,10 +1302,24 @@ fn clear(s: &mut Session, p: &Json, what: &str) -> Result<Json> {
sh.hyperlinks.retain(|c, _| !cleared(*c));
}
if matches!(what, "all" | "formats") {
sh.merges.retain(|m| !r.contains_range(m) || skip.range(m.start.row..=m.end.row).next().is_some());
}
for c in r.iter().take(1_000_000) {
cx.changed.push((sheet, c));
let mut unmerged = false;
sh.merges.retain(|m| {
let keep = !r.contains_range(m) || skip.range(m.start.row..=m.end.row).next().is_some();
unmerged |= !keep;
keep
});
if unmerged {
// An empty merge can block a spill without storing any cells in this range.
// As in Unmerge, retry blocked formula anchors that could reach the freed area.
let reach = RangeRef::new(CellRef::new(0, 0), r.end);
let blocked: Vec<_> = sh
.cells
.iter_range(reach)
.filter(|(_, cell)| cell.formula.is_some() && cell.value == Value::Error(gridcraft_core::CellError::Spill))
.map(|(c, _)| (sheet, c))
.collect();
cx.changed.extend(blocked);
}
}
}
Ok(Json::Null)