mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-01 06:36:47 -06:00
Protection: keep hidden formulas hidden
On a protected sheet a formula formatted Hidden still showed with Show Formulas on, matched Find in formulas, and showed in the formula bar when a cell of its spill range was selected.
This commit is contained in:
@@ -1175,7 +1175,11 @@ fn find(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
.cells
|
||||
.iter()
|
||||
.filter_map(|(c, cell)| {
|
||||
let text = if values || cell.formula.is_none() { crate::display::cell_text(&d.wb, sh, c) } else { cell.input_text() };
|
||||
let text = if values || cell.formula.is_none() || crate::display::formula_hidden(&d.wb, sh, c) {
|
||||
crate::display::cell_text(&d.wb, sh, c)
|
||||
} else {
|
||||
cell.input_text()
|
||||
};
|
||||
matches(&text, &what, case, whole).then_some((c, text))
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -31,11 +31,28 @@ pub fn format(v: &Value, code: &str, wb: &Workbook) -> Formatted {
|
||||
format_value(v, &parsed(code), wb.date_system)
|
||||
}
|
||||
|
||||
/// Whether `c` has a formula that must not be shown: its cell is formatted Hidden on a
|
||||
/// protected sheet. A spilled cell follows its anchor.
|
||||
pub fn formula_hidden(wb: &Workbook, sheet: &Sheet, c: CellRef) -> bool {
|
||||
if !sheet.is_protected() {
|
||||
return false;
|
||||
}
|
||||
let at = match sheet.cell(c) {
|
||||
Some(x) if x.formula.is_some() => c,
|
||||
_ => match sheet.spill_ranges.iter().find(|(_, r)| r.contains(c)) {
|
||||
Some((anchor, _)) => *anchor,
|
||||
None => return false,
|
||||
},
|
||||
};
|
||||
wb.styles.get(sheet.style_id(at)).protection.hidden
|
||||
}
|
||||
|
||||
/// The text a cell shows (full precision General; the grid narrows General to fit the column).
|
||||
pub fn cell_text(wb: &Workbook, sheet: &Sheet, c: CellRef) -> String {
|
||||
let v = sheet.value(c);
|
||||
if sheet.show_formulas
|
||||
&& let Some(f) = sheet.cell(c).and_then(|x| x.formula.as_ref())
|
||||
&& !formula_hidden(wb, sheet, c)
|
||||
{
|
||||
return format!("={}", f.text);
|
||||
}
|
||||
|
||||
@@ -165,6 +165,32 @@ fn protection_allows_permitted_row_and_column_edits() {
|
||||
assert!(s.execute("home.deleteColumns", json!({"cols": "Z:Z"})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hidden_formulas_stay_hidden_on_protected_sheets() {
|
||||
let mut s = s();
|
||||
s.execute("cell.set", json!({"cell": "A1", "input": "=SEQUENCE(3)*7"})).unwrap();
|
||||
s.execute("cell.set", json!({"cell": "B1", "input": "=1+1"})).unwrap();
|
||||
s.execute("home.formatCells", json!({"range": "A1", "style": {"protection": {"locked": true, "hidden": true}}})).unwrap();
|
||||
s.execute("formulas.showFormulas", json!({"on": true})).unwrap();
|
||||
let text = |s: &Session, a: &str| {
|
||||
let d = s.doc().unwrap();
|
||||
let sh = d.wb.active().unwrap();
|
||||
crate::display::cell_text(&d.wb, sh, CellRef::parse(a).unwrap())
|
||||
};
|
||||
assert_eq!(text(&s, "A1"), "=SEQUENCE(3)*7");
|
||||
assert_eq!(s.execute("edit.find", json!({"what": "SEQUENCE", "all": true})).unwrap()["count"], 1);
|
||||
s.execute("review.protectSheet", json!({})).unwrap();
|
||||
assert_eq!(text(&s, "A1"), "7");
|
||||
assert_eq!(text(&s, "B1"), "=1+1");
|
||||
let d = s.doc().unwrap();
|
||||
let sh = d.wb.active().unwrap();
|
||||
assert!(crate::display::formula_hidden(&d.wb, sh, CellRef::parse("A2").unwrap()));
|
||||
assert!(!crate::display::formula_hidden(&d.wb, sh, CellRef::parse("B1").unwrap()));
|
||||
assert!(s.execute("edit.find", json!({"what": "SEQUENCE", "all": true})).is_err());
|
||||
let r = s.execute("edit.find", json!({"what": "7", "all": true})).unwrap();
|
||||
assert_eq!(r["results"][0]["value"], "7");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formatting_and_styles() {
|
||||
let mut s = s();
|
||||
|
||||
@@ -77,6 +77,9 @@ fn active_input(app: &SheetApp) -> String {
|
||||
if r.contains(a)
|
||||
&& let Some(f) = sh.cell(*anchor).and_then(|c| c.formula.as_ref())
|
||||
{
|
||||
if gridcraft_engine::display::formula_hidden(&d.wb, sh, *anchor) {
|
||||
return String::new();
|
||||
}
|
||||
return format!("={}", f.text);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user