fix: Cabrillo contest
This commit is contained in:
@@ -3712,7 +3712,7 @@ type CabrilloResult struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cabrilloHeader fills the Cabrillo header from the active profile (callsign,
|
// cabrilloHeader fills the Cabrillo header from the active profile (callsign,
|
||||||
// operator, grid) plus the contest name the user supplied.
|
// operator, grid) plus the contest name (taken from the QSOs' ADIF CONTEST_ID).
|
||||||
func (a *App) cabrilloHeader(contest string) cabrillo.Header {
|
func (a *App) cabrilloHeader(contest string) cabrillo.Header {
|
||||||
h := cabrillo.Header{Contest: contest}
|
h := cabrillo.Header{Contest: contest}
|
||||||
if a.profiles != nil {
|
if a.profiles != nil {
|
||||||
@@ -3727,8 +3727,9 @@ func (a *App) cabrilloHeader(contest string) cabrillo.Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writeCabrillo collects the QSOs via the given iterator and writes a Cabrillo
|
// writeCabrillo collects the QSOs via the given iterator and writes a Cabrillo
|
||||||
// document to path.
|
// document to path. The contest name is taken from the QSOs' ADIF CONTEST_ID
|
||||||
func (a *App) writeCabrillo(path, contest string, iterate func(func(qso.QSO) error) error) (CabrilloResult, error) {
|
// (the most common one), so no separate prompt is needed.
|
||||||
|
func (a *App) writeCabrillo(path string, iterate func(func(qso.QSO) error) error) (CabrilloResult, error) {
|
||||||
if a.qso == nil {
|
if a.qso == nil {
|
||||||
return CabrilloResult{}, fmt.Errorf("db not initialized")
|
return CabrilloResult{}, fmt.Errorf("db not initialized")
|
||||||
}
|
}
|
||||||
@@ -3736,9 +3737,24 @@ func (a *App) writeCabrillo(path, contest string, iterate func(func(qso.QSO) err
|
|||||||
return CabrilloResult{}, fmt.Errorf("empty path")
|
return CabrilloResult{}, fmt.Errorf("empty path")
|
||||||
}
|
}
|
||||||
var qsos []qso.QSO
|
var qsos []qso.QSO
|
||||||
if err := iterate(func(q qso.QSO) error { qsos = append(qsos, q); return nil }); err != nil {
|
contests := map[string]int{}
|
||||||
|
if err := iterate(func(q qso.QSO) error {
|
||||||
|
qsos = append(qsos, q)
|
||||||
|
if c := strings.TrimSpace(q.ContestID); c != "" {
|
||||||
|
contests[c]++
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
return CabrilloResult{}, err
|
return CabrilloResult{}, err
|
||||||
}
|
}
|
||||||
|
// Pick the most-used CONTEST_ID across the exported QSOs.
|
||||||
|
contest := ""
|
||||||
|
best := 0
|
||||||
|
for c, n := range contests {
|
||||||
|
if n > best {
|
||||||
|
contest, best = c, n
|
||||||
|
}
|
||||||
|
}
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CabrilloResult{}, err
|
return CabrilloResult{}, err
|
||||||
@@ -3752,31 +3768,31 @@ func (a *App) writeCabrillo(path, contest string, iterate func(func(qso.QSO) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ExportCabrillo writes every QSO to a Cabrillo file.
|
// ExportCabrillo writes every QSO to a Cabrillo file.
|
||||||
func (a *App) ExportCabrillo(path, contest string) (CabrilloResult, error) {
|
func (a *App) ExportCabrillo(path string) (CabrilloResult, error) {
|
||||||
return a.writeCabrillo(path, contest, func(fn func(qso.QSO) error) error { return a.qso.IterateAll(a.ctx, fn) })
|
return a.writeCabrillo(path, func(fn func(qso.QSO) error) error { return a.qso.IterateAll(a.ctx, fn) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportCabrilloFiltered writes the QSOs matching the current filter.
|
// ExportCabrilloFiltered writes the QSOs matching the current filter.
|
||||||
func (a *App) ExportCabrilloFiltered(path, contest string, f qso.QueryFilter) (CabrilloResult, error) {
|
func (a *App) ExportCabrilloFiltered(path 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) })
|
return a.writeCabrillo(path, func(fn func(qso.QSO) error) error { return a.qso.IterateFiltered(a.ctx, f, fn) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportCabrilloSelected writes only the highlighted QSOs.
|
// ExportCabrilloSelected writes only the highlighted QSOs.
|
||||||
func (a *App) ExportCabrilloSelected(path, contest string, ids []int64) (CabrilloResult, error) {
|
func (a *App) ExportCabrilloSelected(path string, ids []int64) (CabrilloResult, error) {
|
||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return CabrilloResult{}, fmt.Errorf("no QSOs selected")
|
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) })
|
return a.writeCabrillo(path, 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.
|
// SaveCabrilloFile opens a save dialog for a Cabrillo (.log) file.
|
||||||
func (a *App) SaveCabrilloFile() (string, error) {
|
func (a *App) SaveCabrilloFile() (string, error) {
|
||||||
suggested := "OpsLog_" + time.Now().UTC().Format("20060102_150405") + ".cbr"
|
suggested := "OpsLog_" + time.Now().UTC().Format("20060102_150405") + ".log"
|
||||||
return wruntime.SaveFileDialog(a.ctx, wruntime.SaveDialogOptions{
|
return wruntime.SaveFileDialog(a.ctx, wruntime.SaveDialogOptions{
|
||||||
Title: "Export Cabrillo",
|
Title: "Export Cabrillo",
|
||||||
DefaultFilename: suggested,
|
DefaultFilename: suggested,
|
||||||
Filters: []wruntime.FileFilter{
|
Filters: []wruntime.FileFilter{
|
||||||
{DisplayName: "Cabrillo files (*.cbr, *.log)", Pattern: "*.cbr;*.log"},
|
{DisplayName: "Cabrillo log (*.log, *.cbr)", Pattern: "*.log;*.cbr"},
|
||||||
{DisplayName: "All files (*.*)", Pattern: "*.*"},
|
{DisplayName: "All files (*.*)", Pattern: "*.*"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
+5
-11
@@ -1981,37 +1981,31 @@ export default function App() {
|
|||||||
showToast(`Exported ${r.count} selected QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
showToast(`Exported ${r.count} selected QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
||||||
} catch (e: any) { setError(String(e?.message ?? e)); }
|
} catch (e: any) { setError(String(e?.message ?? e)); }
|
||||||
}
|
}
|
||||||
// Cabrillo (contest log) export — prompts for the contest name, then writes a
|
// Cabrillo (contest log) export → a .log file. The contest name comes from the
|
||||||
// .cbr file. All / filtered / selected variants mirror the ADIF ones.
|
// QSOs' ADIF CONTEST_ID (no prompt). All / filtered / selected mirror the ADIF ones.
|
||||||
async function exportCabrillo() {
|
async function exportCabrillo() {
|
||||||
const contest = window.prompt('Contest name for Cabrillo (e.g. CQ-WW-SSB):', '');
|
|
||||||
if (contest === null) return;
|
|
||||||
try {
|
try {
|
||||||
const path = await SaveCabrilloFile();
|
const path = await SaveCabrilloFile();
|
||||||
if (!path) return;
|
if (!path) return;
|
||||||
const r = await ExportCabrillo(path, contest);
|
const r = await ExportCabrillo(path);
|
||||||
showToast(`Cabrillo: ${r.count} QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
showToast(`Cabrillo: ${r.count} QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
||||||
} catch (e: any) { setError(String(e?.message ?? e)); }
|
} catch (e: any) { setError(String(e?.message ?? e)); }
|
||||||
}
|
}
|
||||||
async function exportFilteredCabrillo() {
|
async function exportFilteredCabrillo() {
|
||||||
const contest = window.prompt('Contest name for Cabrillo (e.g. CQ-WW-SSB):', '');
|
|
||||||
if (contest === null) return;
|
|
||||||
try {
|
try {
|
||||||
const path = await SaveCabrilloFile();
|
const path = await SaveCabrilloFile();
|
||||||
if (!path) return;
|
if (!path) return;
|
||||||
const f = buildActiveFilter();
|
const f = buildActiveFilter();
|
||||||
const r = await ExportCabrilloFiltered(path, contest, { ...f, limit: 0, offset: 0 } as any);
|
const r = await ExportCabrilloFiltered(path, { ...f, limit: 0, offset: 0 } as any);
|
||||||
showToast(`Cabrillo: ${r.count} QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
showToast(`Cabrillo: ${r.count} QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
||||||
} catch (e: any) { setError(String(e?.message ?? e)); }
|
} catch (e: any) { setError(String(e?.message ?? e)); }
|
||||||
}
|
}
|
||||||
async function exportSelectedCabrillo(ids: number[]) {
|
async function exportSelectedCabrillo(ids: number[]) {
|
||||||
if (ids.length === 0) return;
|
if (ids.length === 0) return;
|
||||||
const contest = window.prompt('Contest name for Cabrillo (e.g. CQ-WW-SSB):', '');
|
|
||||||
if (contest === null) return;
|
|
||||||
try {
|
try {
|
||||||
const path = await SaveCabrilloFile();
|
const path = await SaveCabrilloFile();
|
||||||
if (!path) return;
|
if (!path) return;
|
||||||
const r = await ExportCabrilloSelected(path, contest, ids as any);
|
const r = await ExportCabrilloSelected(path, ids as any);
|
||||||
showToast(`Cabrillo: ${r.count} selected QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
showToast(`Cabrillo: ${r.count} selected QSO${r.count > 1 ? 's' : ''} → ${r.path}`);
|
||||||
} catch (e: any) { setError(String(e?.message ?? e)); }
|
} catch (e: any) { setError(String(e?.message ?? e)); }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -131,11 +131,11 @@ export function ExportADIFSelected(arg1:string,arg2:boolean,arg3:Array<number>):
|
|||||||
|
|
||||||
export function ExportAwards():Promise<string>;
|
export function ExportAwards():Promise<string>;
|
||||||
|
|
||||||
export function ExportCabrillo(arg1:string,arg2:string):Promise<main.CabrilloResult>;
|
export function ExportCabrillo(arg1:string):Promise<main.CabrilloResult>;
|
||||||
|
|
||||||
export function ExportCabrilloFiltered(arg1:string,arg2:string,arg3:qso.QueryFilter):Promise<main.CabrilloResult>;
|
export function ExportCabrilloFiltered(arg1:string,arg2:qso.QueryFilter):Promise<main.CabrilloResult>;
|
||||||
|
|
||||||
export function ExportCabrilloSelected(arg1:string,arg2:string,arg3:Array<number>):Promise<main.CabrilloResult>;
|
export function ExportCabrilloSelected(arg1:string,arg2:Array<number>):Promise<main.CabrilloResult>;
|
||||||
|
|
||||||
export function FilterFields():Promise<Array<string>>;
|
export function FilterFields():Promise<Array<string>>;
|
||||||
|
|
||||||
|
|||||||
@@ -226,16 +226,16 @@ export function ExportAwards() {
|
|||||||
return window['go']['main']['App']['ExportAwards']();
|
return window['go']['main']['App']['ExportAwards']();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExportCabrillo(arg1, arg2) {
|
export function ExportCabrillo(arg1) {
|
||||||
return window['go']['main']['App']['ExportCabrillo'](arg1, arg2);
|
return window['go']['main']['App']['ExportCabrillo'](arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExportCabrilloFiltered(arg1, arg2, arg3) {
|
export function ExportCabrilloFiltered(arg1, arg2) {
|
||||||
return window['go']['main']['App']['ExportCabrilloFiltered'](arg1, arg2, arg3);
|
return window['go']['main']['App']['ExportCabrilloFiltered'](arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExportCabrilloSelected(arg1, arg2, arg3) {
|
export function ExportCabrilloSelected(arg1, arg2) {
|
||||||
return window['go']['main']['App']['ExportCabrilloSelected'](arg1, arg2, arg3);
|
return window['go']['main']['App']['ExportCabrilloSelected'](arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FilterFields() {
|
export function FilterFields() {
|
||||||
|
|||||||
Reference in New Issue
Block a user