From f24cab0ae561d396bf3d462a2f96a09c4a848681 Mon Sep 17 00:00:00 2001 From: ericek111 Date: Thu, 10 Sep 2026 20:03:18 +0000 Subject: [PATCH] Work QTC traffic on RTTY the way N1MM does MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QTC window put nothing on the air on RTTY except the lines themselves, so the operator typed the rest into the digital window's transmit pane and copied the lines by hand. N1MM sends a message for each step and fills the lines in from a click. Both are here now, with N1MM's messages, N1MM's defaults and N1MM's settings behind them. The messages, all of them settings in the QTC window's setup area: - RX Ready, `WAERXReadyText`, `{ENTERLF}I AM QRV BK` - All Agn, `WAEAllAgnText`, `{ENTERLF}ALL AGN ALL AGN BK` - Agn n, `WAEAGNText`, `{ENTERLF}AGN QTC: $ $ $ `, where `$` is the line - Save, `WAESaveQTCText`, `{ENTERLF}R R R ALL OK BK` - R U QRV, `WAERUQRVText`, `{ENTERLF}R U QRV BK` - Save, reading traffic out, `WAESSaveQTCText`, `{ENTERLF}GL DE {MYCALL}` Each keys the transmitter, sends the text and drops it again, and an empty one sends nothing. The line spacing default is N1MM's `{ENTERLF}` rather than `{ENTER}`, which was wrong. The buttons: R U QRV and Snd Hdr were hidden while reading traffic out on RTTY, though that is where N1MM starts — R U QRV is the first button pressed. All Agn is new, and so is the S button on each line, which strikes a line through a QTC that arrived too broken to read so the rows after it keep their places; Agn n clears the strike and asks for that line again. Clicking a line in the digital window fills the next row, which is how the series is copied on RTTY: the other station sends the header and all ten lines in one transmission. A click anywhere in a line hands the whole line to the QTC window, which reads the time, the callsign and the serial number out of it by shape and flashes the line to show it was taken. A line that is not a QTC is left to mean what a click always means there. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0157i7PiZyqBkquxS9A6FTdQ --- src/Nonemm.App/AppSession.cs | 8 + src/Nonemm.App/Configuration/Settings.cs | 19 ++ src/Nonemm.App/Dialogs/QtcSetupDialog.axaml | 29 ++- .../Dialogs/QtcSetupDialog.axaml.cs | 12 ++ src/Nonemm.App/Windows/DigitalWindow.Grab.cs | 51 +++++ src/Nonemm.App/Windows/QtcWindow.axaml | 1 + src/Nonemm.App/Windows/QtcWindow.axaml.cs | 175 ++++++++++++++++-- src/Nonemm.Session/QtcMessages.cs | 37 +++- src/Nonemm.Session/QtcTraffic.cs | 54 ++++++ .../Nonemm.Session.Tests/QtcMessagesTests.cs | 29 ++- tests/Nonemm.Session.Tests/QtcTrafficTests.cs | 30 +++ 11 files changed, 418 insertions(+), 27 deletions(-) diff --git a/src/Nonemm.App/AppSession.cs b/src/Nonemm.App/AppSession.cs index 6aca402..9b584ab 100644 --- a/src/Nonemm.App/AppSession.cs +++ b/src/Nonemm.App/AppSession.cs @@ -122,6 +122,14 @@ public sealed class AppSession : IDisposable public CheckWindowSources? Check { get; private set; } + /// Where a line of received text goes while the QTC window is taking + /// traffic down on RTTY. The other station sends the header and the whole + /// series in one transmission, and the operator clicks each line in the + /// digital window rather than typing it, which is how N1MM works. The QTC + /// window sets this while it is open and returns whether the line went + /// into it. + public Func? QtcLines { get; set; } + /// What is spotted and not worked yet. public AvailableStations? Available { get; private set; } diff --git a/src/Nonemm.App/Configuration/Settings.cs b/src/Nonemm.App/Configuration/Settings.cs index 335f900..02593e2 100644 --- a/src/Nonemm.App/Configuration/Settings.cs +++ b/src/Nonemm.App/Configuration/Settings.cs @@ -208,6 +208,25 @@ public sealed record Settings public string QtcRttySendAllEnding { get; init; } = QtcMessages.DefaultSendAllEnding; + /// What goes out when the station reading traffic out closes the window, + /// which is N1MM's `WAESSaveQTCText`. + public string QtcRttySendSave { get; init; } = QtcMessages.DefaultRttySendSave; + + /// What the station reading traffic out asks before it starts, N1MM's + /// `WAERUQRVText`. + public string QtcRttyAreYouReady { get; init; } = QtcMessages.DefaultRttyAreYouReady; + + /// The four messages of the station taking traffic down, N1MM's + /// `WAERXReadyText`, `WAEAllAgnText`, `WAEAGNText` and `WAESaveQTCText`. + /// `$` in the line message stands for the line being asked for. + public string QtcRttyReady { get; init; } = QtcMessages.DefaultRttyReady; + + public string QtcRttyAllAgain { get; init; } = QtcMessages.DefaultRttyAllAgain; + + public string QtcRttyLineAgain { get; init; } = QtcMessages.DefaultRttyLineAgain; + + public string QtcRttySave { get; init; } = QtcMessages.DefaultRttySave; + /// The log window's columns, as `QsoField` names left to right. Empty means /// the set the contest opens with. public IReadOnlyList LogColumns { get; init; } = []; diff --git a/src/Nonemm.App/Dialogs/QtcSetupDialog.axaml b/src/Nonemm.App/Dialogs/QtcSetupDialog.axaml index f83abf7..3301d2f 100644 --- a/src/Nonemm.App/Dialogs/QtcSetupDialog.axaml +++ b/src/Nonemm.App/Dialogs/QtcSetupDialog.axaml @@ -33,19 +33,36 @@ - - - - + + + + + + + + - + + + + + + + + + + + + + Text="N1MM's SSB recordings are left out: playing those needs a voice keyer, and this program has none." />