feat(cat): MY_RIG follows the radio that is connected
With one rig, MY_RIG belonged in Operating conditions and nowhere else. With several, that becomes the wrong place: operating conditions describe a PLAN — 'on 20 m I use the beam and the 7300' — while the question a logged QSO asks is which radio was keying. So each saved radio carries its own MY_RIG, consulted BEFORE the per-band station. When the two disagree — a second rig borrowed for one evening on 20 m — the one that is transmitting is the true answer. Left empty it changes nothing at all: the old chain (band default, then the profile's rig) answers exactly as it did, which is what every single-radio station will keep doing without touching a setting.
This commit is contained in:
@@ -3338,6 +3338,10 @@ func (a *App) applyStationDefaults(q *qso.QSO, includeIdentity bool) {
|
|||||||
// Per-band rig/antenna from Operating conditions (the antenna ticked as
|
// Per-band rig/antenna from Operating conditions (the antenna ticked as
|
||||||
// DEFAULT for this band) — the same auto-fill the entry strip does, applied
|
// DEFAULT for this band) — the same auto-fill the entry strip does, applied
|
||||||
// here so imported QSOs get MY_RIG / MY_ANTENNA from the band defaults.
|
// here so imported QSOs get MY_RIG / MY_ANTENNA from the band defaults.
|
||||||
|
// The radio that is CONNECTED names itself first — see activeRadioMyRig.
|
||||||
|
if q.MyRig == "" {
|
||||||
|
q.MyRig = a.activeRadioMyRig()
|
||||||
|
}
|
||||||
if a.operating != nil && q.Band != "" && (q.MyRig == "" || q.MyAntenna == "") {
|
if a.operating != nil && q.Band != "" && (q.MyRig == "" || q.MyAntenna == "") {
|
||||||
if d, ok, _ := a.operating.BandDefault(a.ctx, p.ID, q.Band); ok {
|
if d, ok, _ := a.operating.BandDefault(a.ctx, p.ID, q.Band); ok {
|
||||||
if q.MyRig == "" {
|
if q.MyRig == "" {
|
||||||
@@ -13401,7 +13405,12 @@ func (a *App) LogUDPLoggedADIF(adifText string) (int64, error) {
|
|||||||
|
|
||||||
// ── Operating-conditions stamp ──
|
// ── Operating-conditions stamp ──
|
||||||
// Pre-fill MY_RIG / MY_ANTENNA / TX_PWR from the default antenna for
|
// Pre-fill MY_RIG / MY_ANTENNA / TX_PWR from the default antenna for
|
||||||
// this band (if the user has configured Operating conditions).
|
// this band (if the user has configured Operating conditions) — after the
|
||||||
|
// connected radio has had its say, since it knows which rig is keying and
|
||||||
|
// the band default only knows which one was planned.
|
||||||
|
if q.MyRig == "" {
|
||||||
|
q.MyRig = a.activeRadioMyRig()
|
||||||
|
}
|
||||||
if a.operating != nil && a.profiles != nil {
|
if a.operating != nil && a.profiles != nil {
|
||||||
if p, err := a.profiles.Active(a.ctx); err == nil {
|
if p, err := a.profiles.Active(a.ctx); err == nil {
|
||||||
if d, ok2, _ := a.operating.BandDefault(a.ctx, p.ID, q.Band); ok2 {
|
if d, ok2, _ := a.operating.BandDefault(a.ctx, p.ID, q.Band); ok2 {
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ type RadioConfig struct {
|
|||||||
// the CAT panel has always edited, so a saved radio is exactly "what the
|
// the CAT panel has always edited, so a saved radio is exactly "what the
|
||||||
// settings said the day it was saved".
|
// settings said the day it was saved".
|
||||||
Settings CATSettings `json:"settings"`
|
Settings CATSettings `json:"settings"`
|
||||||
|
// MyRig is what goes into MY_RIG on a QSO made with this radio.
|
||||||
|
//
|
||||||
|
// It belongs here rather than in Operating conditions once there is more
|
||||||
|
// than one rig: the operating conditions describe a PLAN — "on 20 m I use
|
||||||
|
// the beam and the 7300" — while this is the fact of which radio is keying.
|
||||||
|
// Left empty, nothing changes: the old chain (band default, then the
|
||||||
|
// profile's rig) answers exactly as it did.
|
||||||
|
MyRig string `json:"my_rig"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// radioLabel is what the status bar shows when the operator never named one.
|
// radioLabel is what the status bar shows when the operator never named one.
|
||||||
@@ -204,3 +212,26 @@ func (a *App) syncActiveRadio(s CATSettings) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// activeRadioMyRig is the MY_RIG of the radio currently connected, or "".
|
||||||
|
//
|
||||||
|
// Consulted BEFORE the per-band default, and deliberately: the band default is
|
||||||
|
// what the operator planned to use on that band, this is which radio is
|
||||||
|
// actually on the air. When they disagree — a second rig borrowed for one
|
||||||
|
// evening on 20 m — the one that is transmitting is the true answer.
|
||||||
|
func (a *App) activeRadioMyRig() string {
|
||||||
|
if a.settings == nil || strings.TrimSpace(a.settingOr(keyRadiosList, "")) == "" {
|
||||||
|
return "" // no list was ever made: nothing to say, nothing changes
|
||||||
|
}
|
||||||
|
list, err := a.GetRadios()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
id := a.ActiveRadioID()
|
||||||
|
for _, r := range list {
|
||||||
|
if r.ID == id {
|
||||||
|
return strings.TrimSpace(r.MyRig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
@@ -3266,7 +3266,19 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
|||||||
<Trash2 className="size-3.5" />
|
<Trash2 className="size-3.5" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
{/* MY_RIG follows the radio, not the profile.
|
||||||
|
Operating conditions describe a PLAN — "on 20 m I use the beam
|
||||||
|
and the 7300" — while this is the fact of which rig is keying.
|
||||||
|
Empty leaves the old chain alone. */}
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Label className="shrink-0 w-24">{t('cat.radioMyRig')}</Label>
|
||||||
|
<Input className="h-9 flex-1" placeholder={t('cat.radioMyRigPh')}
|
||||||
|
value={(radios.find((r: any) => r.id === activeRadio)?.my_rig) ?? ''}
|
||||||
|
onChange={(e) => setRadios((l) => l.map((r: any) => r.id === activeRadio ? { ...r, my_rig: e.target.value } : r))}
|
||||||
|
onBlur={() => { SaveRadios(radios as any).catch(() => {}); }} />
|
||||||
|
</div>
|
||||||
<p className="text-[11px] text-muted-foreground">{t('cat.radioHint')}</p>
|
<p className="text-[11px] text-muted-foreground">{t('cat.radioHint')}</p>
|
||||||
|
<p className="text-[11px] text-muted-foreground">{t('cat.radioMyRigHint')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label className="flex items-center gap-2 text-sm cursor-pointer">
|
<label className="flex items-center gap-2 text-sm cursor-pointer">
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -3573,6 +3573,7 @@ export namespace main {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
settings: CATSettings;
|
settings: CATSettings;
|
||||||
|
my_rig: string;
|
||||||
|
|
||||||
static createFrom(source: any = {}) {
|
static createFrom(source: any = {}) {
|
||||||
return new RadioConfig(source);
|
return new RadioConfig(source);
|
||||||
@@ -3583,6 +3584,7 @@ export namespace main {
|
|||||||
this.id = source["id"];
|
this.id = source["id"];
|
||||||
this.name = source["name"];
|
this.name = source["name"];
|
||||||
this.settings = this.convertValues(source["settings"], CATSettings);
|
this.settings = this.convertValues(source["settings"], CATSettings);
|
||||||
|
this.my_rig = source["my_rig"];
|
||||||
}
|
}
|
||||||
|
|
||||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||||
|
|||||||
Reference in New Issue
Block a user