Two entry windows and an SO2R box
LoggingSession mixed two things: the contest, which one station has one of, and what the operator is typing, which belongs to a radio. It is now ContestSession and RadioPosition. Two positions share one log, one score and one run of serial numbers, so a station worked on radio 1 is a dupe on radio 2. Frequency, mode, split, what is typed and whether you are running belong to each radio on its own. A second radio opens a second entry window. It has no menu of its own: it is another view of the same contest, not another program. Only the window for radio 1 opens the database and the connections. Ctrl+Tab moves the operator to the other radio and the keyboard follows. Ctrl+Shift+Tab puts both radios in the headphones. OtrspBox speaks OTRSP to an SO2R box over a serial port: TX1/TX2 for the key, RX1/RX2 and RX1S for the headphones, AUXnnn for an output line. It follows the active radio, and every message points the box at this radio before keying, so a message cannot go out of the radio the operator has just left. A command that would change nothing is not sent, because the box works relays; N1MM does the same. The box takes a Stream, so what it sends is tested without a serial port. Still missing: alternating CQ, and voice keying on the second radio. Looked at under Xvfb with two fake radios, one of them split: both windows up, radio 1 showing 14008.00 into 14020.0, radio 2 on 14030.00, Ctrl+Tab moving the keyboard between them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,11 +30,11 @@ public sealed partial class EditContactDialog : Window
|
||||
QsoField.CountryPrefix, QsoField.WpxPrefix,
|
||||
];
|
||||
|
||||
private readonly LoggingSession logging;
|
||||
private readonly ContestSession logging;
|
||||
private readonly Dictionary<QsoField, TextBox> boxes = [];
|
||||
private int at;
|
||||
|
||||
public EditContactDialog(LoggingSession logging, string contactId)
|
||||
public EditContactDialog(ContestSession logging, string contactId)
|
||||
{
|
||||
this.logging = logging;
|
||||
InitializeComponent();
|
||||
|
||||
@@ -23,8 +23,11 @@
|
||||
<CheckBox Grid.Row="4" Grid.Column="1" Name="SecondEnabledBox" Content="Follow this radio"
|
||||
Margin="0,2,0,0" />
|
||||
</Grid>
|
||||
<TextBlock Text="SO2R box serial port, or empty for none" FontSize="11" Opacity="0.7"
|
||||
Margin="0,10,0,1" />
|
||||
<TextBox Name="BoxPortBox" />
|
||||
<TextBlock TextWrapping="Wrap" FontSize="11" Opacity="0.75" Margin="0,8,0,0"
|
||||
Text="With a second radio the station is SO2R: both are read and both show on the bandmap, but only the one you are on drives the entry window. Ctrl+Tab moves you to the other." />
|
||||
Text="With a second radio the station is SO2R: both are read and both show on the bandmap, but only the one you are on drives the entry window. Ctrl+Tab moves you to the other, and Ctrl+Shift+Tab puts both in the headphones. An OTRSP box follows, routing the key and the headphones." />
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="6" Margin="0,8,0,0">
|
||||
<Button Content="Cancel" Click="OnCancel" />
|
||||
<Button Content="Save" Click="OnSave" IsDefault="True" />
|
||||
|
||||
@@ -17,6 +17,7 @@ public sealed partial class RadioDialog : Window
|
||||
InitializeComponent();
|
||||
Show(0, HostBox, PortBox, EnabledBox);
|
||||
Show(1, SecondHostBox, SecondPortBox, SecondEnabledBox);
|
||||
BoxPortBox.Text = settings.So2rBoxPort;
|
||||
}
|
||||
|
||||
private void Show(int at, TextBox host, TextBox port, CheckBox enabled)
|
||||
@@ -36,6 +37,7 @@ public sealed partial class RadioDialog : Window
|
||||
Read(HostBox, PortBox, EnabledBox),
|
||||
Read(SecondHostBox, SecondPortBox, SecondEnabledBox),
|
||||
],
|
||||
So2rBoxPort = (BoxPortBox.Text ?? "").Trim(),
|
||||
});
|
||||
|
||||
private static StoredRadio Read(TextBox host, TextBox port, CheckBox enabled) => new()
|
||||
|
||||
Reference in New Issue
Block a user