Rules edited, removed or moved in the panel have no command a macro could replay, so a recording notes them as comments, as dialogs are. Format > Clear conditional formats sits beside Conditional formatting.
- commit
- a26fb6bba29ac5f301feaef9a85c4b854e334d09
- parent
- c1ab15fa2e7c81c58a1f613e70b970da4a1ed46d
- author
- Dami <dami.etoile@gmail.com>
| M | internal/ | 2 | ++ |
| M | internal/ | 2 | +- |
| M | internal/ | 20 | ++++++++++++++++++++ |
| M | internal/ | 9 | +++++---- |
| M | internal/ | 2 | +- |
| M | internal/ | 17 | ++++++++++++----- |
@@ -9,6 +9,7 @@ import (
99 "github.com/FelineStateMachine/012/internal/ui/findbar"1010 "github.com/FelineStateMachine/012/internal/ui/lineedit"1111 "github.com/FelineStateMachine/012/internal/ui/picker"12+ "github.com/FelineStateMachine/012/internal/ui/rules"1213 "github.com/FelineStateMachine/012/internal/ui/theme"1314 "github.com/FelineStateMachine/012/internal/ui/themepicker"1415 )@@ -26,6 +27,7 @@ var (
2627 _ cmdline.Host = host{}2728 _ findbar.Host = host{}2829 _ themepicker.Host = host{}30+ _ rules.Host = host{}2931 )3032 3133 // The in-package hosts the model implements itself.@@ -84,7 +84,7 @@ var menuBar = []menuDef{
8484 {cmd: "format.bold", title: "Bold"}, {cmd: "format.italic", title: "Italic"}, {cmd: "format.underline", title: "Underline"}, {cmd: "format.strikethrough", title: "Strikethrough"}, sep,8585 {cmd: "format.align_left", title: "Align left"}, {cmd: "format.align_center", title: "Align center"}, {cmd: "format.align_right", title: "Align right"}, sep,8686 {cmd: "column.width"}, {cmd: "column.reset"}, sep,87- {cmd: "format.conditional"}, sep,87+ {cmd: "format.conditional"}, {cmd: "format.conditional_clear"}, sep,8888 {cmd: "format.clear", title: "Clear formatting"},8989 }},9090 {title: "Data", accel: 'd', items: []menuItem{@@ -283,11 +283,29 @@ func (h host) SaveFormat(i int, f sheet.CondFormat) error {
283283 m.changed = true284284 if i < 0 {285285 m.recordRule("format.conditional_add", f.JSON())286+ } else {287+ m.noteUnrecorded()286288 }287289 }288290 return err289291 }290292 293+// Reworked follows a rule removed or moved in the panel.294+func (h host) Reworked() {295+ h.m.changed = true296+ h.m.noteUnrecorded()297+}298+299+// noteUnrecorded notes in a recording the last undo step, a change to300+// rules the panel made that no command replays, as dialogs are noted.301+func (m *Model) noteUnrecorded() {302+ if r := m.rec; r != nil && r.depth == 0 && r.pending == "" {303+ r.flush(m)304+ r.actions = append(r.actions, macro.Note("Not recorded: "+m.book().UndoLabel()))305+ r.acted = true306+ }307+}308+291309 // SaveValidation adds or replaces a validation rule, refusing one over a292310 // pivot table's results, whose cells take no entries; an added one is293311 // recorded as the command that adds it.@@ -306,6 +324,8 @@ func (h host) SaveValidation(i int, v sheet.Validation) error {
306324 m.changed = true307325 if i < 0 {308326 m.recordRule("data.validation_add", v.JSON())327+ } else {328+ m.noteUnrecorded()309329 }310330 }311331 return err@@ -34,8 +34,9 @@ type Host interface {
3434 // commands macros record do, reporting why they couldn't.3535 SaveFormat(i int, f sheet.CondFormat) error3636 SaveValidation(i int, v sheet.Validation) error37- // Edited marks the file modified after a rule was removed or moved.38- Edited()37+ // Reworked follows a rule removed or moved: the file is modified,38+ // and a macro being recorded notes what it can't replay.39+ Reworked()3940 // Slot is the terminal's color for an ANSI slot, for color scales.4041 Slot(i int) color.Color4142 }@@ -157,7 +158,7 @@ func (e *Editor) Key(k tea.KeyPressMsg) tea.Cmd {
157158 case "delete", "backspace", "x", "-":158159 if e.list.Sel > 0 {159160 e.k.remove(e.h.Sheet(), e.list.Sel-1)160- e.h.Edited()161+ e.h.Reworked()161162 e.list.Sel = min(e.list.Sel, e.k.count(e.h.Sheet()))162163 }163164 case "shift+up", "shift+down":@@ -178,7 +179,7 @@ func (e *Editor) reorder(down bool) {
178179 }179180 if e.k.move(e.h.Sheet(), i, to) {180181 e.list.Sel = to + 1181- e.h.Edited()182+ e.h.Reworked()182183 }183184 }184185 @@ -39,7 +39,7 @@ func (h *fakeHost) Line() *lineedit.Line { return &h.line }
3939 func (h *fakeHost) Close() { h.closed = true }4040 func (h *fakeHost) Sheet() *sheet.Sheet { return h.s }4141 func (h *fakeHost) Selection() sheet.Rect { return h.sel }42-func (h *fakeHost) Edited() { h.edits++ }42+func (h *fakeHost) Reworked() { h.edits++ }4343 func (h *fakeHost) Slot(i int) color.Color { return color.Gray{Y: uint8(i * 16)} }4444 func (h *fakeHost) SaveFormat(i int, f sheet.CondFormat) error {4545 h.saves = append(h.saves, f.JSON())@@ -46,13 +46,16 @@ func TestConditionalFormattingPanel(t *testing.T) {
4646 }4747 // A2 is drawn on the green fill, A1 isn't.4848 sp := rowtext.Span{Text: "150", Owner: 0}49- base, colored, _ := m.ruleSpan(addr("A2"), &sp, m.th.Cell, false, m.slotColor)50- if !colored || base.GetBackground() != m.th.RuleFill[sheet.ColorGreen].GetBackground() {51- t.Errorf("A2 base %v colored %v", base.GetBackground(), colored)49+ _, shade, shaded := m.ruleSpan(addr("A2"), &sp, false, m.slotColor)50+ if !shaded || shade.Style.GetBackground() != m.th.RuleFill[sheet.ColorGreen].GetBackground() {51+ t.Errorf("A2 shade %v shaded %v", shade.Style.GetBackground(), shaded)5252 }53- if _, colored, _ := m.ruleSpan(addr("A1"), &sp, m.th.Cell, false, m.slotColor); colored {53+ if _, _, shaded := m.ruleSpan(addr("A1"), &sp, false, m.slotColor); shaded {5454 t.Error("A1 formatted")5555 }56+ if _, _, shaded := m.ruleSpan(addr("A2"), &sp, true, m.slotColor); shaded {57+ t.Error("the pointer's colors gave way to a rule's")58+ }5659 press(t, m, "<ctrl+z>")5760 if len(m.sheet.CondFormats()) != 0 {5861 t.Error("undo kept the rule")@@ -158,6 +161,7 @@ func TestRuleMacros(t *testing.T) {
158161 press(t, m, "<shift+down>")159162 src := recordRules(t, m)160163 for _, want := range []string{`run("format.conditional_add", answer="{\"ranges\":\"A1:A2\",\"condition\":\"not_empty\",\"fill\":\"green\"}")`,164+ `# Not recorded: remove conditional format A1:A2`,161165 `run("insert.checkbox")`, `run("data.validation_add", answer="{\"ranges\":\"C1:C2\",\"criteria\":\"list\",\"items\":[\"a\",\"b\"]}")`} {162166 if !strings.Contains(src, want) {163167 t.Errorf("script lacks %s:\n%s", want, src)@@ -165,7 +169,7 @@ func TestRuleMacros(t *testing.T) {
165169 }166170 fresh := newModel()167171 script(t, fresh, src)168- if len(fresh.sheet.CondFormats()) != 1 || len(fresh.sheet.Validations()) != 2 {172+ if len(fresh.sheet.CondFormats()) != 2 || len(fresh.sheet.Validations()) != 2 { // the removal is only noted169173 t.Errorf("replay: %+v %+v %q", fresh.sheet.CondFormats(), fresh.sheet.Validations(), fresh.warn)170174 }171175 }@@ -177,6 +181,9 @@ func recordRules(t *testing.T, m *Model) string {
177181 send(m, nil)178182 run(m, m.runCommand("macro.record"))179183 run(m, m.runCommand("format.conditional"))184+ press(t, m, "<enter>", "<enter>") // add the rule the form starts with185+ press(t, m, "<down>", "<delete>", "<esc>") // removed, and noted186+ run(m, m.runCommand("format.conditional"))180187 press(t, m, "<enter>", "<enter>", "<esc>", "<right>")181188 run(m, m.runCommand("insert.checkbox"))182189 press(t, m, "<right>")