Both put something on our own bandmap and nothing on the cluster, which is what separates them from Spot It. Mark, Alt+M, leaves a mark where the radio is to say the frequency is busy. The label is N1MM's, Busy@ and the time. It is not a station, so Spot carries IsStation: nothing judges it, the check window does not offer it as a call, available mults and Qs leaves it out, space does not take it into the callsign box, and the bandmap paints it like a station already worked, which is how N1MM marks it. The station count under the bandmap counts stations. Store, Alt+O, puts the call being typed on the bandmap at this frequency so it can be worked later. N1MM writes "Local spot" in the comment and this does the same. The action row now holds the eight buttons N1MM has, in N1MM's order and at N1MM's widths: 23 per cent to Esc: Stop and 11 to each of the rest. Left out of Store: N1MM also adds the call to what the check window's Master column offers for the rest of the session. The call is on the bandmap, which the check window already reads, so it is offered either way. Driven under Xvfb: Alt+M leaving BUSY@22:32:27 on 14000, Alt+O storing SP9XYZ there, and both drawn on the bandmap in the worked colour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
93 lines
3.1 KiB
C#
93 lines
3.1 KiB
C#
using Nonemm.Contests;
|
|
using Nonemm.Core;
|
|
using Nonemm.Session;
|
|
using Nonemm.Spotting;
|
|
|
|
namespace Nonemm.App.Windows;
|
|
|
|
/// The line above the callsign box. N1MM calls it the call frame: it says which
|
|
/// spotted station the radio is sitting on, coloured the way the bandmap
|
|
/// colours it, or that this is the frequency we are calling CQ on. Space with
|
|
/// an empty callsign box takes the station out of the frame and into the box,
|
|
/// which is how a station is worked without typing its call.
|
|
public sealed partial class EntryWindow
|
|
{
|
|
/// Where we last called CQ, so the frame can say so when the radio comes
|
|
/// back to it.
|
|
private Frequency cqFrequency;
|
|
|
|
/// What the frame holds, when it holds a callsign. `CQ-Frequency` is not
|
|
/// one, and neither is nothing.
|
|
private string framedCall = "";
|
|
|
|
/// How close counts as sitting on a spot, which is a different number for
|
|
/// each mode: a phone signal is wide and a CW one is not.
|
|
private Frequency TuningTolerance =>
|
|
Frequency.FromHertz(Math.Max(
|
|
0,
|
|
session.Settings.TuningToleranceFor(Logging?.Mode.Category ?? ModeCategory.Cw)));
|
|
|
|
private void ShowCallFrame()
|
|
{
|
|
framedCall = "";
|
|
if (Logging is null)
|
|
{
|
|
CallFrameText.Text = "";
|
|
return;
|
|
}
|
|
if (cqFrequency.Hertz > 0
|
|
&& Math.Abs(Logging.Frequency.Hertz - cqFrequency.Hertz) <= TuningTolerance.Hertz)
|
|
{
|
|
CallFrameText.Text = "CQ-Frequency";
|
|
CallFrameText.Foreground = Verdicts.Cq;
|
|
return;
|
|
}
|
|
if (session.Bandmap.Near(Logging.Frequency, TuningTolerance) is not { } spot)
|
|
{
|
|
CallFrameText.Text = "";
|
|
return;
|
|
}
|
|
// a mark saying the frequency is busy is shown but never taken into the
|
|
// callsign box, because it is not a station
|
|
framedCall = spot.IsStation ? spot.Call.Text : "";
|
|
CallFrameText.Text = spot.IsSplit
|
|
? $"{spot.Call.Text} — listening on {spot.Qsx.Kilohertz:0.0}"
|
|
: spot.Call.Text;
|
|
CallFrameText.Foreground = spot.IsStation
|
|
? Verdicts.Colour(VerdictFor(spot))
|
|
: Verdicts.Dupe;
|
|
}
|
|
|
|
private Verdict? VerdictFor(Spot spot) => Logging?.Log.Judge(new Qso
|
|
{
|
|
Id = "",
|
|
TimestampUtc = DateTime.UtcNow,
|
|
Call = spot.Call,
|
|
Frequency = spot.Frequency,
|
|
Mode = Logging.Mode,
|
|
ContestName = Logging.Contest.Name,
|
|
});
|
|
|
|
/// N1MM only takes the call out of the frame while searching: a running
|
|
/// station is answering callers, not chasing the one it is sitting on.
|
|
private bool TakeFramedCall()
|
|
{
|
|
if (Logging is null || Logging.IsRunning || framedCall.Length == 0
|
|
|| Logging.Entry.Call.Trim().Length > 0)
|
|
{
|
|
return false;
|
|
}
|
|
Logging.Entry.Call = framedCall;
|
|
return true;
|
|
}
|
|
|
|
/// The frequency a CQ went out on is the one the frame calls ours.
|
|
private void RememberCqFrequency()
|
|
{
|
|
if (Logging is not null)
|
|
{
|
|
cqFrequency = Logging.Frequency;
|
|
}
|
|
}
|
|
}
|