package main import ( "fmt" "os" "path/filepath" "unsafe" "yvbolt/debconf" "github.com/ying32/govcl/vcl" ) type debconfLoadedDatabase struct { displayName string db *debconf.Database nav *vcl.TTreeNode arena []*navData // keepalive } func (ld *debconfLoadedDatabase) DisplayName() string { return ld.displayName } func (ld *debconfLoadedDatabase) DriverName() string { return "debconf" } func (ld *debconfLoadedDatabase) RootElement() *vcl.TTreeNode { return ld.nav } func (ld *debconfLoadedDatabase) Keepalive(ndata *navData) { ld.arena = append(ld.arena, ndata) } func (ld *debconfLoadedDatabase) RenderForNav(f *TMainForm, ndata *navData) error { // Load properties content := fmt.Sprintf("Entries: %d\nUnique attributes: %d\n", len(ld.db.Entries), len(ld.db.AllColumnNames)) f.propertiesBox.SetText(content) // Load data indexes := make(map[string]int) for i, cname := range ld.db.AllColumnNames { indexes[cname] = i col := f.contentBox.Columns().Add() col.Title().SetCaption(cname) } for _, entry := range ld.db.Entries { rpos := f.contentBox.RowCount() f.contentBox.SetRowCount(rpos + 1) f.contentBox.SetCells(0, rpos, entry.Name) for _, proppair := range entry.Properties { f.contentBox.SetCells(int32(indexes[proppair[0]]), rpos, proppair[1]) } } // Valid vcl_stringgrid_columnwidths(f.contentBox) f.contentBox.SetEnabled(true) return nil } func (ld *debconfLoadedDatabase) NavChildren(ndata *navData) ([]string, error) { // In the debconf implementation, there is only one child: "Data" if len(ndata.bucketPath) == 0 { return []string{"Data"}, nil } else { // No children deeper than that return []string{}, nil } } func (ld *debconfLoadedDatabase) NavContext(ndata *navData) ([]contextAction, error) { return nil, nil // No special actions are supported } func (ld *debconfLoadedDatabase) Close() { ld.arena = nil } var _ loadedDatabase = &debconfLoadedDatabase{} // interface assertion // func (f *TMainForm) debconfAddDatabaseFrom(path string) { // TODO load in background thread to stop blocking the UI fh, err := os.OpenFile(path, os.O_RDONLY, 0400) if err != nil { vcl.ShowMessage(fmt.Sprintf("Failed to load database: %s", err.Error())) return } defer fh.Close() db, err := debconf.Parse(fh) if err != nil { vcl.ShowMessage(fmt.Sprintf("Failed to load database: %s", err.Error())) return } ld := &debconfLoadedDatabase{ db: db, displayName: filepath.Base(path), } ld.nav = f.Buckets.Items().Add(nil, ld.displayName) ld.nav.SetHasChildren(true) // dynamically populate in OnNavExpanding ld.nav.SetImageIndex(imgDatabase) ld.nav.SetSelectedIndex(imgDatabase) navData := &navData{ ld: ld, childrenLoaded: false, // will be loaded dynamically bucketPath: []string{}, // empty = root } ld.nav.SetData(unsafe.Pointer(navData)) f.dbs = append(f.dbs, ld) f.Buckets.SetSelected(ld.nav) // Select new element ld.Keepalive(navData) }