github.com/wrgl/wrgl@v0.14.0/pkg/widgets/merge_row.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright © 2022 Wrangle Ltd 3 4 package widgets 5 6 import ( 7 "github.com/gdamore/tcell/v2" 8 "github.com/wrgl/wrgl/pkg/diff" 9 "github.com/wrgl/wrgl/pkg/merge" 10 ) 11 12 var ( 13 resolvedCell = NewTableCell("resolved").SetStyle(boldGreenStyle) 14 unresolvedCell = NewTableCell("unresolved").SetStyle(boldStyle) 15 ) 16 17 type MergeRow struct { 18 cd *diff.ColDiff 19 Cells [][]*TableCell 20 baseRow []string 21 buf *diff.BlockBuffer 22 } 23 24 func NewMergeRow(buf *diff.BlockBuffer, cd *diff.ColDiff, names []string) *MergeRow { 25 l := cd.Layers() + 1 26 n := cd.Len() + 1 27 numPK := len(cd.OtherPK[0]) 28 c := &MergeRow{ 29 buf: buf, 30 cd: cd, 31 Cells: make([][]*TableCell, l), 32 } 33 for i := 0; i < l; i++ { 34 c.Cells[i] = make([]*TableCell, n) 35 for j := 0; j < n; j++ { 36 c.Cells[i][j] = NewTableCell("") 37 if j == 0 && i < l-1 { 38 c.Cells[i][j].SetText(names[i]).SetStyle(boldStyle) 39 } else if j < numPK+1 { 40 c.Cells[i][j].SetStyle(primaryKeyStyle) 41 } else { 42 c.Cells[i][j].SetStyle(cellStyle) 43 } 44 } 45 } 46 return c 47 } 48 49 func (c *MergeRow) DisplayMerge(m *merge.Merge) error { 50 baseInd := len(c.Cells) - 1 51 if m.Resolved { 52 c.Cells[baseInd][0] = resolvedCell 53 } else { 54 c.Cells[baseInd][0] = unresolvedCell 55 } 56 if m.Base != nil { 57 c.baseRow = make([]string, c.cd.Len()) 58 blk, off := diff.RowToBlockAndOffset(m.BaseOffset) 59 row, err := c.buf.GetRow(0, blk, off) 60 if err != nil { 61 return err 62 } 63 row = c.cd.RearrangeBaseRow(row) 64 for i, s := range row { 65 c.baseRow[i] = s 66 } 67 } else { 68 c.baseRow = nil 69 } 70 numPK := len(c.cd.OtherPK[0]) 71 for i, sum := range m.Others { 72 cell := c.Cells[i][0] 73 if sum == nil { 74 cell.SetStyle(boldRedStyle) 75 for j := 0; j < c.cd.Len(); j++ { 76 cell := c.Cells[i][j+1] 77 cell.SetText("") 78 if j >= numPK { 79 cell.SetStyle(cellStyle) 80 } 81 } 82 continue 83 } else if m.Base == nil { 84 cell.SetStyle(boldGreenStyle) 85 } else if string(sum) == string(m.Base) { 86 cell.SetStyle(boldStyle) 87 } else { 88 cell.SetStyle(boldYellowStyle) 89 } 90 91 blk, off := diff.RowToBlockAndOffset(m.OtherOffsets[i]) 92 row, err := c.buf.GetRow(byte(i+1), blk, off) 93 if err != nil { 94 return err 95 } 96 row = c.cd.RearrangeRow(i, row) 97 for j, s := range row { 98 cell := c.Cells[i][j+1] 99 cell.SetText(s) 100 if j >= len(c.cd.OtherPK[0]) { 101 if c.baseRow == nil { 102 cell.SetStyle(greenStyle) 103 } else { 104 baseTxt := c.baseRow[j] 105 if _, ok := c.cd.Removed[i][uint32(j)]; ok { 106 cell.SetStyle(redStyle) 107 } else if _, ok := c.cd.Added[i][uint32(j)]; ok { 108 cell.SetStyle(greenStyle) 109 } else if baseTxt != cell.Text { 110 cell.SetStyle(yellowStyle) 111 } else { 112 cell.SetStyle(cellStyle) 113 } 114 } 115 } 116 } 117 } 118 if m.ResolvedRow != nil { 119 for i, s := range m.ResolvedRow { 120 _, ok := m.UnresolvedCols[uint32(i)] 121 if m.Resolved { 122 ok = false 123 } 124 c.SetCell(i, s, ok) 125 } 126 } else if c.baseRow != nil { 127 for i, s := range c.baseRow { 128 c.SetCell(i, s, !m.Resolved) 129 } 130 } 131 return nil 132 } 133 134 func (c *MergeRow) SetCell(col int, s string, unresolved bool) { 135 cell := c.Cells[c.cd.Layers()][col+1] 136 cell.SetText(s) 137 for i, m := range c.cd.Added { 138 if _, ok := m[uint32(col)]; ok && c.Cells[i][col+1].Text == s { 139 cell.SetStyle(greenStyle) 140 return 141 } 142 } 143 if col < len(c.cd.OtherPK[0]) { 144 cell.SetStyle(primaryKeyStyle) 145 return 146 } else if c.baseRow == nil { 147 cell.SetStyle(greenStyle) 148 } else if s != c.baseRow[col] { 149 cell.SetStyle(yellowStyle) 150 } else { 151 cell.SetStyle(cellStyle) 152 } 153 if unresolved { 154 cell.SetBackgroundColor(tcell.ColorDarkRed).DisableTransparency(true) 155 } else { 156 cell.SetBackgroundColor(tcell.ColorBlack).DisableTransparency(false).SetTransparency(true) 157 } 158 } 159 160 type MergeRowPool struct { 161 blkBuf *diff.BlockBuffer 162 cd *diff.ColDiff 163 names []string 164 buf []*MergeRow 165 rowMap map[int]int 166 merges []*merge.Merge 167 minInd int 168 maxInd int 169 } 170 171 func NewMergeRowPool(blkBuf *diff.BlockBuffer, cd *diff.ColDiff, names []string, merges []*merge.Merge) *MergeRowPool { 172 return &MergeRowPool{ 173 blkBuf: blkBuf, 174 cd: cd, 175 names: names, 176 merges: merges, 177 rowMap: map[int]int{}, 178 } 179 } 180 181 func (p *MergeRowPool) rowFromBuf(ind int) (*MergeRow, error) { 182 n := len(p.buf) 183 if c := cap(p.buf); n >= c { 184 p.buf = append(p.buf, nil) 185 } else { 186 p.buf = p.buf[:n+1] 187 } 188 if p.buf[n] == nil { 189 p.buf[n] = NewMergeRow(p.blkBuf, p.cd, p.names) 190 } 191 err := p.buf[n].DisplayMerge(p.merges[ind]) 192 if err != nil { 193 return nil, err 194 } 195 if ind > p.maxInd { 196 p.maxInd = ind 197 } else if ind < p.minInd { 198 p.minInd = ind 199 } 200 p.rowMap[ind] = n 201 return p.buf[n], nil 202 } 203 204 func (p *MergeRowPool) getRow(ind int) (*MergeRow, error) { 205 if ind < 0 || ind > len(p.merges) { 206 return nil, nil 207 } 208 if v, ok := p.rowMap[ind]; ok { 209 return p.buf[v], nil 210 } 211 if ind < p.minInd-200 || ind > p.maxInd+200 { 212 p.rowMap = map[int]int{} 213 p.buf = p.buf[:0] 214 p.minInd = ind 215 p.maxInd = ind 216 } 217 return p.rowFromBuf(ind) 218 } 219 220 func (p *MergeRowPool) SetCell(row, col int, s string, unresolved bool) { 221 r, err := p.getRow(row) 222 if err != nil { 223 panic(err) 224 } 225 r.SetCell(col, s, unresolved) 226 } 227 228 func (p *MergeRowPool) IsTextAtCellDifferentFromBase(row, col, layer int) bool { 229 r, err := p.getRow(row) 230 if err != nil { 231 panic(err) 232 } 233 return r.Cells[layer][col].Text != r.Cells[p.cd.Layers()][col].Text 234 } 235 236 func (p *MergeRowPool) GetCell(row, col, subrow int) *TableCell { 237 r, err := p.getRow(row) 238 if err != nil { 239 panic(err) 240 } 241 return r.Cells[subrow][col] 242 } 243 244 func (p *MergeRowPool) RefreshRow(row int) { 245 r, err := p.getRow(row) 246 if err != nil { 247 return 248 } 249 r.DisplayMerge(p.merges[row]) 250 }