// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main // this is the "main" patch window. The first one // then you can dig down and examine the patchsets and the files import ( "fmt" "strconv" "go.wit.com/lib/gadgets" "go.wit.com/lib/protobuf/forgepb" "go.wit.com/log" "go.wit.com/gui" ) type patchesWindow struct { win *gadgets.BasicWindow // the patches window stack *gui.Node // the top box set as vertical grid *gui.Node // the list of available patches reason *gadgets.BasicEntry // the name of the patchset submitB *gui.Node // the submit patchet button psetgrid *gui.Node // the list of each patchset totalOL *gadgets.OneLiner dirtyOL *gadgets.OneLiner readonlyOL *gadgets.OneLiner rw *gadgets.OneLiner // checkB *gui.Node } func (r *patchesWindow) Hidden() bool { return r.win.Hidden() } func (r *patchesWindow) Toggle() { if r.Hidden() { r.Show() } else { r.Hide() } } func (r *patchesWindow) Show() { r.win.Show() } func (r *patchesWindow) Hide() { r.win.Hide() } // you can only have one of these func (r *patchesWindow) initWindow() { r.win = gadgets.RawBasicWindow("Forge Patchesets") r.win.Make() r.stack = r.win.Box().NewBox("bw vbox", false) // me.reposwin.Draw() r.win.Custom = func() { log.Warn("Patchset Window close. setting hidden=true") // sets the hidden flag to false so Toggle() works r.win.Hide() } r.grid = r.stack.RawGrid() r.submitPatchesBox() // update the stats about the repos and patches r.Update() } func (r *patchesWindow) submitPatchesBox() { // s := new(patchSummary) group1 := r.stack.NewGroup("Repo Summary") grid := group1.RawGrid() // make the header table for repo stats r.totalOL = gadgets.NewOneLiner(grid, "Total") grid.NextRow() r.dirtyOL = gadgets.NewOneLiner(grid, "dirty") grid.NextRow() r.readonlyOL = gadgets.NewOneLiner(grid, "read-only") grid.NextRow() r.rw = gadgets.NewOneLiner(grid, "r/w") grid.NextRow() // now, make the 'widget group' and the buttons at the bottom of the window group1 = r.stack.NewGroup("Patchset Create") grid = group1.RawGrid() grid.NewButton("show current patches", func() { r.Update() pset, err := me.forge.MakeDevelPatchSet("current patches") if err != nil { log.Info("patchset creation failed", err) return } if pset == nil { log.Info("you have no current patches") return } win := makePatchWindow(pset) win.Show() }) r.reason = gadgets.NewBasicEntry(grid, "Patchset name:") r.reason.Custom = func() { if r.reason.String() != "" { log.Info("Forge: enable submit") r.submitB.Enable() } else { log.Info("Forge: disable submit") r.submitB.Disable() } } r.submitB = grid.NewButton("Submit", func() { if r.submitB.IsEnabled() { log.Info("submit button is enabled") } else { log.Info("submit button is disabled. BAD GUI TOOLKIT ERROR") return } pset, err := me.forge.SubmitDevelPatchSet(r.reason.String()) if err != nil { log.Info(err) return } r.addPatchsetNew(pset) }) psets, err := openPatchsets() if err != nil { log.Info("Open Patchsets failed", err) } grid.NewButton("Update Patchset List", func() { psets, err = me.forge.GetPatchesets() if err != nil { log.Info("Get Patchsets failed", err) return } savePatchsets(psets) log.Info("got psets len", len(psets.Patchsets)) all := psets.SortByName() for all.Scan() { pset := all.Next() r.addPatchsetNew(pset) } }) // disables the submit button until the user enters a name r.submitB.Disable() grid.NextRow() g := r.stack.NewGroup("Patchset List") // add the grid r.psetgrid = g.RawGrid() // will look in ~/.config/forge for an existing patchset file // attempt to read in patchsets saved on disk if psets != nil { log.Info("got psets len", len(psets.Patchsets)) all := psets.SortByName() for all.Scan() { pset := all.Next() // log.Info("pset name =", pset.Name) r.addPatchsetNew(pset) } } } func (r *patchesWindow) addPatchsetNew(pset *forgepb.Patchset) { var win *patchWindow r.psetgrid.NewButton("View", func() { // has the window already been created? if win != nil { win.Toggle() return } win = makePatchWindow(pset) win.Show() }) r.psetgrid.NewLabel(pset.Name) r.psetgrid.NewLabel(pset.Comment) r.psetgrid.NewLabel(pset.GitAuthorName) r.psetgrid.NewLabel(pset.Uuid) ctime := pset.Ctime.AsTime() stime := ctime.UTC().Format("2006-01-02_15:04:05_UTC") r.psetgrid.NewLabel(stime) if pset.State == "BROKEN" { r.psetgrid.NewLabel("Bad") } else { r.psetgrid.NewLabel("Good") } r.psetgrid.NextRow() } // will update this from the current state of the protobuf func (r *patchesWindow) Update() { var total, dirty, readonly, rw int // figure out the totals all := me.forge.Repos.SortByFullPath() for all.Scan() { repo := all.Next() total += 1 if repo.IsDirty() { dirty += 1 } if me.forge.Config.IsReadOnly(repo.GetGoPath()) { readonly += 1 } else { rw += 1 } } // send the values to the GUI toolkit r.totalOL.SetText(strconv.Itoa(total) + " repos") r.dirtyOL.SetText(strconv.Itoa(dirty) + " repos") r.readonlyOL.SetText(strconv.Itoa(readonly) + " repos") r.rw.SetText(fmt.Sprintf("%d repos", rw)) }