Stack the calls that answer a CQ, the way N1MM does

A CQ is answered by more than one station. N1MM lets the operator put the
others on a stack and work them one after another; this is that, with N1MM's
keys and macros.

Ctrl+Alt+G and {STACKANOTHER} put the call being typed on the stack and clear
the boxes. Alt+G brings the top call back. Alt+D drops it. {SOCALLSTACK} both
stacks and unstacks in one key: it swaps the typed call for the top one, stacks
it when the stack is empty, and takes the top call when the boxes are.
{LOGTHENPOP} and {LOGTHENNEXT} log the contact and bring the next caller in.
{CLRSTACK} empties it.

The rules are N1MM's, and CallStack and the entry actions hold them without a
window, so they are unit-tested: stacking only while running, nothing shorter
than two characters, no dupe, no frequency typed into the callsign box, a call
already on the stack moved rather than repeated, and a multiplier to the front.
{SOCALLSTACK} takes the stacked call off before it puts the typed one on, so a
multiplier just typed cannot come straight back.

Two places differ. N1MM refuses your own call only while the stack is empty;
it is never a station to work, so it is refused either way here. And the order
is multipliers first in every mode: N1MM's digital window offers first-in and
last-in as well, and there is no digital window here.

The stack window opens by itself with the first call and closes with the last,
or Window > Call Stack opens it. It does not take the keyboard when it opens,
because the operator is typing the next call. The next call out is ringed and
each is coloured by what working it would bring, as in every other window.

OperatingPosition.JudgeCall now answers what a call alone is worth, which the
stack window and the check window both need; it was private to the check
window before.

Driven under Xvfb: four calls stacked with Ctrl+Alt+G and listed in the window,
Alt+G bringing the top one into the boxes, Alt+D dropping the next.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
This commit is contained in:
2026-08-30 22:23:30 +00:00
co-authored by Claude Opus 5
parent bb35848e11
commit ec8cdb88d7
16 changed files with 757 additions and 26 deletions
+17 -2
View File
@@ -1,8 +1,8 @@
namespace Nonemm.Session;
/// What an action macro in a function key message does. N1MM's action macros
/// that this program has nothing to do — the CAT families, audio, rotators,
/// call stacking — are not here; they are read and passed over.
/// that this program has nothing to do — the CAT families, audio, rotators —
/// are not here; they are read and passed over.
public enum MessageCommand
{
/// Clears the entry boxes, as Escape and N1MM's `{WIPE}` do.
@@ -51,4 +51,19 @@ public enum MessageCommand
/// Sends its argument to the SO2R box.
Otrsp,
/// Puts the call being typed on the call stack and clears the entry, so
/// the next caller can be copied.
StackAnother,
/// Swaps the call being typed for the one on top of the call stack, or
/// stacks it when the stack is empty, or takes the top call when the box
/// is.
SwapWithStack,
/// Logs the contact and takes the next call off the stack.
LogThenPop,
/// Empties the call stack.
ClearStack,
}