yvbolt/db_debconf.go

143 lines
3.2 KiB
Go
Raw Permalink Normal View History

2024-06-30 02:14:41 +00:00
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) {
// 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
f.contentBox.SetEnabled(false)
f.contentBox.Clear()
// debconf always uses Key + Value as the columns
indexes := make(map[string]int)
f.contentBox.Columns().Clear()
for i, cname := range ld.db.AllColumnNames {
indexes[cname] = i
col := f.contentBox.Columns().Add()
col.SetCaption(cname)
col.SetWidth(MY_WIDTH)
}
for _, entry := range ld.db.Entries {
cell := f.contentBox.Items().Add()
cell.SetCaption(entry.Name)
texts := make([]string, len(ld.db.AllColumnNames))
for _, proppair := range entry.Properties {
texts[indexes[proppair[0]]-1 /* compensate for 'Name' always being first */] = proppair[1]
}
cell.SubItems().AddStrings2(texts)
}
// Valid
f.contentBox.SetEnabled(true)
}
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) ExecQuery(query string, resultArea *vcl.TListView) {
vcl.ShowMessage("debconf doesn't support querying")
}
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)
}