feat: added Cabrillo export
This commit is contained in:
@@ -25,6 +25,7 @@ import (
|
||||
"hamlog/internal/award"
|
||||
"hamlog/internal/awardref"
|
||||
"hamlog/internal/backup"
|
||||
"hamlog/internal/cabrillo"
|
||||
"hamlog/internal/cat"
|
||||
"hamlog/internal/clublog"
|
||||
"hamlog/internal/cluster"
|
||||
@@ -3704,6 +3705,83 @@ func (a *App) ExportADIFSelected(path string, includeAppFields bool, ids []int64
|
||||
return ex.ExportFileByIDs(a.ctx, path, ids)
|
||||
}
|
||||
|
||||
// CabrilloResult reports how many QSOs a Cabrillo export wrote and where.
|
||||
type CabrilloResult struct {
|
||||
Count int `json:"count"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// cabrilloHeader fills the Cabrillo header from the active profile (callsign,
|
||||
// operator, grid) plus the contest name the user supplied.
|
||||
func (a *App) cabrilloHeader(contest string) cabrillo.Header {
|
||||
h := cabrillo.Header{Contest: contest}
|
||||
if a.profiles != nil {
|
||||
if p, err := a.profiles.Active(a.ctx); err == nil {
|
||||
h.Callsign = p.Callsign
|
||||
h.Operators = p.Callsign
|
||||
h.GridLocator = p.MyGrid
|
||||
h.Name = p.OpName
|
||||
}
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// writeCabrillo collects the QSOs via the given iterator and writes a Cabrillo
|
||||
// document to path.
|
||||
func (a *App) writeCabrillo(path, contest string, iterate func(func(qso.QSO) error) error) (CabrilloResult, error) {
|
||||
if a.qso == nil {
|
||||
return CabrilloResult{}, fmt.Errorf("db not initialized")
|
||||
}
|
||||
if path == "" {
|
||||
return CabrilloResult{}, fmt.Errorf("empty path")
|
||||
}
|
||||
var qsos []qso.QSO
|
||||
if err := iterate(func(q qso.QSO) error { qsos = append(qsos, q); return nil }); err != nil {
|
||||
return CabrilloResult{}, err
|
||||
}
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return CabrilloResult{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
n, err := cabrillo.Generate(f, a.cabrilloHeader(contest), qsos)
|
||||
if err != nil {
|
||||
return CabrilloResult{}, err
|
||||
}
|
||||
return CabrilloResult{Count: n, Path: path}, nil
|
||||
}
|
||||
|
||||
// ExportCabrillo writes every QSO to a Cabrillo file.
|
||||
func (a *App) ExportCabrillo(path, contest string) (CabrilloResult, error) {
|
||||
return a.writeCabrillo(path, contest, func(fn func(qso.QSO) error) error { return a.qso.IterateAll(a.ctx, fn) })
|
||||
}
|
||||
|
||||
// ExportCabrilloFiltered writes the QSOs matching the current filter.
|
||||
func (a *App) ExportCabrilloFiltered(path, contest string, f qso.QueryFilter) (CabrilloResult, error) {
|
||||
return a.writeCabrillo(path, contest, func(fn func(qso.QSO) error) error { return a.qso.IterateFiltered(a.ctx, f, fn) })
|
||||
}
|
||||
|
||||
// ExportCabrilloSelected writes only the highlighted QSOs.
|
||||
func (a *App) ExportCabrilloSelected(path, contest string, ids []int64) (CabrilloResult, error) {
|
||||
if len(ids) == 0 {
|
||||
return CabrilloResult{}, fmt.Errorf("no QSOs selected")
|
||||
}
|
||||
return a.writeCabrillo(path, contest, func(fn func(qso.QSO) error) error { return a.qso.IterateByIDs(a.ctx, ids, fn) })
|
||||
}
|
||||
|
||||
// SaveCabrilloFile opens a save dialog for a Cabrillo (.cbr / .log) file.
|
||||
func (a *App) SaveCabrilloFile() (string, error) {
|
||||
suggested := "OpsLog_" + time.Now().UTC().Format("20060102_150405") + ".cbr"
|
||||
return wruntime.SaveFileDialog(a.ctx, wruntime.SaveDialogOptions{
|
||||
Title: "Export Cabrillo",
|
||||
DefaultFilename: suggested,
|
||||
Filters: []wruntime.FileFilter{
|
||||
{DisplayName: "Cabrillo files (*.cbr, *.log)", Pattern: "*.cbr;*.log"},
|
||||
{DisplayName: "All files (*.*)", Pattern: "*.*"},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// --- Lookup bindings ---
|
||||
|
||||
// LookupCallsign returns the cached or freshly-fetched info for a callsign.
|
||||
|
||||
Reference in New Issue
Block a user