2025-02-19 02:48:37 -06:00
|
|
|
// Although most code from WIT.COM Inc is under the GPL
|
|
|
|
// This code is more generic because it must be able
|
|
|
|
// to be used in any GUI plugin
|
|
|
|
|
|
|
|
package tree
|
|
|
|
|
|
|
|
import (
|
2025-02-19 14:08:22 -06:00
|
|
|
"fmt"
|
2025-02-20 03:15:24 -06:00
|
|
|
"time"
|
2025-02-19 14:08:22 -06:00
|
|
|
|
2025-02-20 03:15:24 -06:00
|
|
|
"go.wit.com/lib/gui/shell"
|
2025-02-19 02:48:37 -06:00
|
|
|
"go.wit.com/lib/protobuf/guipb"
|
|
|
|
"go.wit.com/log"
|
|
|
|
"go.wit.com/widget"
|
2025-02-20 03:15:24 -06:00
|
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
"google.golang.org/protobuf/types/known/anypb"
|
|
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
2025-02-19 02:48:37 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// repeated string order = 1;
|
|
|
|
//
|
|
|
|
// repeated StringRow StringRows = 2;
|
|
|
|
// repeated IntRow IntRows = 3;
|
|
|
|
// repeated TimeRow TimeRows = 4;
|
|
|
|
// repeated BoolRow BoolRows = 5;
|
|
|
|
func (me *TreeInfo) doTable(a widget.Action) {
|
|
|
|
if a.TablePB == nil {
|
|
|
|
log.Log(TREE, "tree: action didn't have a Table PB")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
pb := guipb.NewTables()
|
|
|
|
if err := pb.Unmarshal(a.TablePB); err != nil {
|
|
|
|
log.Info("unmarshal error", err, "data len =", len(a.TablePB))
|
|
|
|
return
|
|
|
|
}
|
2025-02-19 14:08:22 -06:00
|
|
|
log.Info("tree.doTables() start. # of tables:", len(pb.Tables))
|
2025-02-19 02:48:37 -06:00
|
|
|
all := pb.All()
|
|
|
|
for all.Scan() {
|
|
|
|
t := all.Next()
|
2025-02-19 14:08:22 -06:00
|
|
|
// for i, o := range t.Order {
|
|
|
|
// log.Info("got order:", t.Title, i, o)
|
|
|
|
// }
|
|
|
|
// dumpTable(t)
|
|
|
|
// me.ShowTable(t)
|
2025-02-23 12:59:19 -06:00
|
|
|
// log.Info("TREE FOUND TABLE UUID", t.Uuid)
|
2025-02-23 05:23:21 -06:00
|
|
|
for i, ot := range me.currentTables {
|
2025-02-23 12:59:19 -06:00
|
|
|
// log.Info("TREE already has UUID", i, ot.Uuid)
|
2025-02-23 05:23:21 -06:00
|
|
|
if t.Uuid == ot.Uuid {
|
|
|
|
log.Info("TREE found UUID! update table here", i, ot.Uuid)
|
2025-03-04 20:29:27 -06:00
|
|
|
if ot.Grid == nil {
|
|
|
|
log.Info("TREE found UUID! ot.grid.Id = nil. need to find grid id here")
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
log.Info("TREE found UUID! grid.Id =", ot.Grid.Id)
|
|
|
|
t.Grid = ot.Grid
|
|
|
|
}
|
|
|
|
if t.Grid == nil {
|
|
|
|
log.Info("TREE found UUID! grid.Id = nil. need to find grid id here")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Info("TREE found UUID! update table here", i, ot.Uuid, "grid.Id =", t.Grid.Id)
|
2025-02-23 12:36:29 -06:00
|
|
|
me.updateTable(t)
|
2025-02-23 05:23:21 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
me.currentTables = append(me.currentTables, t)
|
2025-03-04 20:29:27 -06:00
|
|
|
if t.Grid == nil {
|
|
|
|
log.Info("NEW TREE ERROR: grid.Id = nil need to set grid id here")
|
|
|
|
} else {
|
|
|
|
log.Info("NEW TREE: grid.Id =", t.Grid.Id)
|
|
|
|
}
|
2025-02-19 06:54:54 -06:00
|
|
|
me.makeTable(t)
|
2025-02-19 02:48:37 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-19 14:08:22 -06:00
|
|
|
func (grid *Node) makeGridLabel(pb *guipb.Widget, w int, h int) *Node {
|
|
|
|
a := new(widget.Action)
|
|
|
|
a.WidgetType = widget.Label
|
|
|
|
a.WidgetId = int(pb.Id)
|
|
|
|
a.ParentId = grid.WidgetId
|
|
|
|
a.State.Enable = true
|
|
|
|
a.State.Label = pb.Name
|
|
|
|
a.State.AtW = w
|
|
|
|
a.State.AtH = h
|
2025-02-21 13:57:29 -06:00
|
|
|
a.State.GridOffset.X = w
|
|
|
|
a.State.GridOffset.Y = h
|
2025-02-21 16:55:43 -06:00
|
|
|
// log.Info("makeGridLabel()", a.State)
|
2025-02-19 14:08:22 -06:00
|
|
|
return AddNode(a)
|
|
|
|
}
|
|
|
|
|
2025-02-23 12:36:29 -06:00
|
|
|
func (me *TreeInfo) updateTable(t *guipb.Table) {
|
2025-03-04 20:29:27 -06:00
|
|
|
grid := FindWidgetId(int(t.Grid.Id))
|
|
|
|
if grid == nil {
|
|
|
|
log.Info("tree: updateTable() failed to make grid")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// delete the existing table
|
|
|
|
me.DeleteNode(grid)
|
|
|
|
|
|
|
|
// remake the table
|
|
|
|
me.Add(grid)
|
|
|
|
var h int = 0
|
|
|
|
var w int = 0
|
2025-02-23 12:36:29 -06:00
|
|
|
for _, name := range t.Order {
|
2025-03-04 20:29:27 -06:00
|
|
|
// log.Info("got order:", t.Title, name)
|
|
|
|
if me.addTableRow(t, grid, name, w) {
|
|
|
|
// log.Info("tree:row() COLUMN GOOD", t.Title, name, w, h)
|
|
|
|
} else {
|
|
|
|
log.Info("tree:row() COLOMN FAIL", t.Title, name, w, h)
|
|
|
|
}
|
|
|
|
|
|
|
|
w += 1
|
2025-02-23 12:36:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (me *TreeInfo) updateRow(t *guipb.Table, name string) {
|
|
|
|
for _, r := range t.StringRows {
|
|
|
|
if name == r.Header.Name {
|
2025-02-23 12:59:19 -06:00
|
|
|
// debugging code
|
|
|
|
// id := r.Header.Id
|
|
|
|
// n := treeRoot.FindWidgetId(int(id))
|
|
|
|
// if n == nil {
|
|
|
|
// log.Info("could not find widget id", id)
|
|
|
|
// }
|
2025-03-03 12:00:04 -06:00
|
|
|
log.Info("tree.updateRow(string)", r.Header, "len =", len(r.Widgets))
|
2025-02-23 12:36:29 -06:00
|
|
|
// if r.Header.Name == "Hostname" {
|
|
|
|
// }
|
|
|
|
// log.Info("tree.updateRow() found Hostnames", r.Vals)
|
|
|
|
for i, v := range r.Vals {
|
|
|
|
// log.Info("tree: Hostname Widget", i, v, w.Name)
|
|
|
|
w := r.Widgets[i]
|
|
|
|
if v != w.Name {
|
|
|
|
log.Info("tree: need to update:", i, v, "vs", w.Name, w.Id)
|
|
|
|
n := treeRoot.FindWidgetId(int(w.Id))
|
|
|
|
if n == nil {
|
|
|
|
log.Info("tree.TableUpdate() err n == nil ", w.Id, w.Name)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
me.SetText(n, v)
|
|
|
|
}
|
2025-03-03 12:00:04 -06:00
|
|
|
if r.Header.Name == "CurrentBranchName" {
|
|
|
|
log.Info("tree: check:", i, v, "vs", w.Name, w.Id)
|
|
|
|
}
|
2025-02-23 12:36:29 -06:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2025-02-23 12:59:19 -06:00
|
|
|
|
|
|
|
for _, r := range t.TimeRows {
|
|
|
|
if name != r.Header.Name {
|
|
|
|
continue
|
|
|
|
}
|
2025-03-03 12:00:04 -06:00
|
|
|
log.Info("tree.updateRow(time)", r.Header, "len =", len(r.Widgets))
|
2025-02-23 12:59:19 -06:00
|
|
|
for i, _ := range r.Vals {
|
|
|
|
// log.Info("tree: Hostname Widget", i, v, w.Name)
|
|
|
|
w := r.Widgets[i]
|
|
|
|
n := treeRoot.FindWidgetId(int(w.Id))
|
|
|
|
if n == nil {
|
|
|
|
log.Info("tree.TableUpdate() err n == nil ", w.Id, w.Name)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
msg, err := anypb.UnmarshalNew(w.Val, proto.UnmarshalOptions{})
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to unmarshal: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
switch v := msg.(type) {
|
|
|
|
case *timestamppb.Timestamp:
|
|
|
|
me.SetText(n, shell.FormatDuration(time.Since(v.AsTime())))
|
|
|
|
default:
|
|
|
|
me.SetText(n, fmt.Sprintf("%v", v))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2025-02-23 12:36:29 -06:00
|
|
|
}
|
|
|
|
|
2025-02-19 06:54:54 -06:00
|
|
|
func (me *TreeInfo) makeTable(t *guipb.Table) {
|
2025-02-21 15:50:46 -06:00
|
|
|
var grid *Node
|
|
|
|
if t.Parent != nil {
|
|
|
|
a := new(widget.Action)
|
|
|
|
a.WidgetType = widget.Grid
|
|
|
|
a.WidgetId = int(t.Grid.Id)
|
|
|
|
a.ParentId = int(t.Parent.Id)
|
|
|
|
a.State.Enable = true
|
|
|
|
grid = AddNode(a)
|
|
|
|
}
|
|
|
|
if grid == nil {
|
|
|
|
log.Info("tree: makeTable() failed to make grid")
|
|
|
|
return
|
|
|
|
}
|
2025-02-19 06:54:54 -06:00
|
|
|
me.Add(grid)
|
|
|
|
log.Info("tree: makeTable() finished add win & grid")
|
2025-02-19 14:08:22 -06:00
|
|
|
var h int = 0
|
|
|
|
var w int = 0
|
|
|
|
for _, name := range t.Order {
|
|
|
|
// log.Info("got order:", t.Title, name)
|
|
|
|
if me.addTableRow(t, grid, name, w) {
|
2025-02-21 16:55:43 -06:00
|
|
|
// log.Info("tree:row() COLUMN GOOD", t.Title, name, w, h)
|
2025-02-19 14:08:22 -06:00
|
|
|
} else {
|
|
|
|
log.Info("tree:row() COLOMN FAIL", t.Title, name, w, h)
|
|
|
|
}
|
2025-02-19 06:54:54 -06:00
|
|
|
|
2025-02-19 14:08:22 -06:00
|
|
|
w += 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (me *TreeInfo) addTableRow(t *guipb.Table, grid *Node, name string, w int) bool {
|
|
|
|
var h int = 0
|
|
|
|
for _, r := range t.StringRows {
|
|
|
|
if name != r.Header.Name {
|
|
|
|
// log.Info("skip string row:", r.Header.Name, "!=", name)
|
|
|
|
continue
|
|
|
|
}
|
2025-02-21 16:55:43 -06:00
|
|
|
// log.Info("tree: Add()ing to grid here", r.Header.Id, r.Header.Name, w, h)
|
2025-02-19 14:08:22 -06:00
|
|
|
head := grid.makeGridLabel(r.Header, w, h)
|
|
|
|
me.Add(head)
|
|
|
|
h += 1
|
2025-02-19 06:54:54 -06:00
|
|
|
for _, v := range r.Widgets {
|
2025-02-21 05:42:18 -06:00
|
|
|
// log.Info("tree: Add()ing to grid here", v.Id, v.Name, w, h)
|
2025-02-19 14:08:22 -06:00
|
|
|
lab := grid.makeGridLabel(v, w, h)
|
|
|
|
me.Add(lab)
|
|
|
|
h += 1
|
2025-02-19 06:54:54 -06:00
|
|
|
}
|
2025-02-19 14:08:22 -06:00
|
|
|
return true
|
2025-02-19 06:54:54 -06:00
|
|
|
}
|
2025-02-19 14:08:22 -06:00
|
|
|
|
|
|
|
for _, r := range t.IntRows {
|
|
|
|
if name != r.Header.Name {
|
|
|
|
// log.Info("skip sint row:", r.Header.Name, "!=", name)
|
|
|
|
continue
|
|
|
|
}
|
2025-02-21 16:55:43 -06:00
|
|
|
// log.Info("tree: Add()ing to grid here", r.Header.Id, r.Header.Name, w, h)
|
2025-02-19 14:08:22 -06:00
|
|
|
head := grid.makeGridLabel(r.Header, w, h)
|
|
|
|
me.Add(head)
|
|
|
|
h += 1
|
|
|
|
for _, v := range r.Widgets {
|
|
|
|
v.Name = fmt.Sprintf("%d", v.Size)
|
2025-02-21 05:42:18 -06:00
|
|
|
// log.Info("tree: Add()ing to grid here", v.Id, v.Name, w, h)
|
2025-02-19 14:08:22 -06:00
|
|
|
lab := grid.makeGridLabel(v, w, h)
|
|
|
|
me.Add(lab)
|
|
|
|
h += 1
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2025-02-20 03:15:24 -06:00
|
|
|
for _, r := range t.TimeRows {
|
|
|
|
if name != r.Header.Name {
|
|
|
|
// log.Info("skip sint row:", r.Header.Name, "!=", name)
|
|
|
|
continue
|
|
|
|
}
|
2025-02-21 16:55:43 -06:00
|
|
|
// log.Info("tree: Add()ing to grid here", r.Header.Id, r.Header.Name, w, h)
|
2025-02-20 03:15:24 -06:00
|
|
|
head := grid.makeGridLabel(r.Header, w, h)
|
|
|
|
me.Add(head)
|
|
|
|
h += 1
|
|
|
|
for _, widg := range r.Widgets {
|
|
|
|
msg, err := anypb.UnmarshalNew(widg.Val, proto.UnmarshalOptions{})
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to unmarshal: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
switch v := msg.(type) {
|
|
|
|
case *timestamppb.Timestamp:
|
2025-02-21 18:49:52 -06:00
|
|
|
// fmt.Println("Unpacked Timestamp:", shell.FormatDuration(time.Since(v.AsTime())))
|
2025-02-20 03:15:24 -06:00
|
|
|
widg.Name = shell.FormatDuration(time.Since(v.AsTime()))
|
|
|
|
default:
|
|
|
|
fmt.Println("Unknown type:", v)
|
|
|
|
widg.Name = fmt.Sprintf("%v", v)
|
|
|
|
}
|
|
|
|
|
2025-02-21 05:42:18 -06:00
|
|
|
// log.Info("tree: Add()ing to grid here", widg.Id, widg.Name, w, h)
|
2025-02-20 03:15:24 -06:00
|
|
|
lab := grid.makeGridLabel(widg, w, h)
|
|
|
|
me.Add(lab)
|
|
|
|
h += 1
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2025-02-19 14:08:22 -06:00
|
|
|
return false
|
2025-02-19 03:23:09 -06:00
|
|
|
}
|
|
|
|
|
2025-02-19 02:48:37 -06:00
|
|
|
func dumpTable(t *guipb.Table) {
|
|
|
|
for i, o := range t.Order {
|
|
|
|
log.Info("got order:", t.Title, i, o)
|
|
|
|
}
|
|
|
|
for i, r := range t.StringRows {
|
2025-02-19 14:08:22 -06:00
|
|
|
log.Info("got string row:", t.Title, i, r.Header.Name, r.Vals)
|
2025-02-19 03:23:09 -06:00
|
|
|
for _, v := range r.Widgets {
|
2025-02-19 02:48:37 -06:00
|
|
|
log.Info("tree: got string widget:", v.Id, v.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for i, r := range t.IntRows {
|
2025-02-19 14:08:22 -06:00
|
|
|
log.Info("got int row:", t.Title, i, r.Header.Name, r.Vals)
|
2025-02-19 02:48:37 -06:00
|
|
|
for _, v := range r.Widgets {
|
2025-02-19 03:23:09 -06:00
|
|
|
log.Info("tree: got int widget:", v.Id, v.Size)
|
2025-02-19 02:48:37 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type TreeTable struct {
|
|
|
|
PB *guipb.Table
|
|
|
|
/*
|
|
|
|
hostnames []string
|
|
|
|
columns []*gui.NodeColumn
|
|
|
|
order []*gui.NodeColumn
|
|
|
|
*/
|
|
|
|
}
|