cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

cat/module-path
012 / internal / sheet / validcheck.go
validcheck.go 1.7K
1package sheet23import "slices"45// Validation of what pastes and fills write, as Sheets does it: they6// don't ask cell by cell, so the UI checks the range they wrote after7// the fact, and takes the whole change back (Discard) when a rule that8// rejects fails.910// InvalidIn lists the cells in r whose contents fail their validation,11// in reading order: blanks never do. A cell's rule decides whether its12// entry is refused (Reject) or kept and marked. The cost is the cells13// stored where r meets a rule's ranges.14func (s *Sheet) InvalidIn(r Rect) []*InvalidEntry {15 var out []*InvalidEntry16 for _, v := range s.rules.validations {17 for _, vr := range v.Ranges {18 in := Rect{19 From: Addr{Col: max(vr.From.Col, r.From.Col), Row: max(vr.From.Row, r.From.Row)},20 To: Addr{Col: min(vr.To.Col, r.To.Col), Row: min(vr.To.Row, r.To.Row)},21 }22 if in.From.Col > in.To.Col || in.From.Row > in.To.Row {23 continue24 }25 for _, a := range s.cellsIn(in) {26 if c := s.cells.get(a); !c.Blank() && s.Look(a).Invalid {27 out = append(out, &InvalidEntry{Addr: a, Help: v.HelpText(), Reject: v.Reject})28 }29 }30 }31 }32 slices.SortFunc(out, func(a, b *InvalidEntry) int {33 if a.Addr.Row != b.Addr.Row {34 return a.Addr.Row - b.Addr.Row35 }36 return a.Addr.Col - b.Addr.Col37 })38 return out39}4041// Discard takes back the last change and forgets it, so redo can't bring42// it back: a paste or fill refused after the fact. It reports whether43// there was a change to take back.44func (w *Workbook) Discard() bool {45 if _, ok := w.swap(true); !ok {46 return false47 }48 w.hist.redo = w.hist.redo[:len(w.hist.redo)-1]49 return true50}5152// Discard takes back the workbook's last change; see Workbook.Discard.53func (s *Sheet) Discard() bool { return s.wb.Discard() }