fix(autocall): the QSO in progress outranks the ladder

Six faults from an evening on 60 m, all in the same family: the engine
judging a station by what the log wants from it and forgetting what is
already under way.

- An exchange was abandoned mid-QSO. The reply lands in the same period
  the ladder is re-read, and that period was judged before the reply was
  taken into account, so a better-ranked caller took the slot from a
  station that had just come back to us. The answer is settled first now,
  and our own report counts as being inside the exchange too — which also
  protects a QSO the operator started by hand.
- A station just picked started with misses against it. Its transmit slot
  was unknown until a second decode, and with the parity unknown every
  period counted, including the one spent transmitting to it.
- The freed slot after "it is working somebody else" was thrown away: the
  period's decodes are in hand, so the next station is picked from them
  rather than fifteen seconds later. Never mid-over.
- Auto-call is never armed from a stored setting — not at launch, not on
  a profile switch. It is the one feature that puts the station on the
  air by itself and OpsLog starts with Windows.
- It says what it is waiting for: a wanted station in a QSO with somebody
  else now shows beside the Auto button instead of looking idle.
- Switching profile left the previous logbook's verdicts on screen. The
  worked-index, chase-new and the frontend's cached verdicts are dropped
  when the logbook changes.

FT decodes: distance column, a message addressed to you set whole in
green (the station you are calling keeps a tint — most of what it sends
goes to other people), badge order L / Wkd / WL, list cleared when the
RIG changes band.

Rotor: new world-map compass from EC1KD's design, with the Ultrabeam boom
and second lobe restored and the compact form preserved; the classic dial
is kept and Settings → Rotator chooses between them. Stop no longer
flickers on a rotor standing still — movement was inferred from a degree,
less than the jitter a controller reports at rest.
This commit is contained in:
2026-09-05 23:02:31 +02:00
parent 8dbc4b7e62
commit 23323c91e0
14 changed files with 1752 additions and 389 deletions
+19 -3
View File
@@ -2603,7 +2603,20 @@ func (a *App) switchLogbook(p profile.Profile) error {
_ = old.Close()
}
applog.Printf("logbook switched to %s for profile %q", backend, p.Name)
// EVERY worked/new verdict belonged to the OLD logbook.
//
// The award matrices above are only half of it: the in-memory worked-index
// the alert engine reads, the chase-new list, and the frontend's own cache of
// resolved spot verdicts all still hold the previous log's answers. An
// operator switching to an empty profile and back found every decode on the
// screen badged NEW — the empty log's verdicts, cached under the full one,
// and nothing short of a restart cleared them.
if a.chaseNew != nil {
a.chaseNew.clear()
}
go a.rebuildWorkedIndex()
if a.ctx != nil {
wruntime.EventsEmit(a.ctx, "spotstatus:invalidate")
wruntime.EventsEmit(a.ctx, "logbook:changed")
}
return nil
@@ -16704,10 +16717,13 @@ func (a *App) reloadAfterProfileSwitch() {
// Auto-call is per profile — attempts, the "call only" callsign, whether it
// is on at all — and it TRANSMITS. A switch that left the previous profile's
// settings running would have the wrong station calling on the wrong log.
//
// Off, exactly as at launch: a switch changes the callsign, the log and
// usually the antenna, and none of that is a state in which a transmitter
// should resume by itself because this profile's stored setting said on.
// Re-applied rather than restarted: the loop is one goroutine for the life
// of the process, and applyAutoCall clears the target when the feature is
// off in the profile just activated.
a.applyAutoCall()
// of the process.
a.disarmAutoCall("profile switch")
a.autoCallEngine().Reset()
}