Replace the Networked stations window with Options tab fields

Station Number, Port and Version to claim are now on the Options tab of
Network Status and save when a box loses focus. The other settings
(station name, listen port, peers, link on/off) are in a Stations
Configuration window opened from a button on the same tab. The explanation
texts and the Config menu item are removed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 10:43:23 +00:00
co-authored by Claude Sonnet 5.5
parent 209c557112
commit 71c11a9316
8 changed files with 64 additions and 78 deletions
+4 -2
View File
@@ -1037,8 +1037,10 @@ at the node as well, because that is less traffic on the wire.
### Networked stations ### Networked stations
**Config → Edit Networked-Computer Names** names this station and sets the The **Stations Configuration** button on the Options tab of Network Status
port it listens on. **Config → Configure Broadcast Data** is N1MM's Broadcast names this station, sets the port it listens on and lists the stations to
reach by address. The station number, link
port and version to claim are on the Options tab of Network Status. **Config → Configure Broadcast Data** is N1MM's Broadcast
Data tab: seven kinds of data, each with an on/off box and a list of Data tab: seven kinds of data, each with an on/off box and a list of
`address:port` pairs separated by spaces. An empty list sends to `127.0.0.1` on `address:port` pairs separated by spaces. An empty list sends to `127.0.0.1` on
N1MM's port for that kind: 12060, except the score on 12050 and the rotor on N1MM's port for that kind: 12060, except the score on 12050 and the rotor on
@@ -1,36 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Nonemm.App.Dialogs.NetworkDialog"
Title="Networked stations" Width="440" SizeToContent="Height"
WindowStartupLocation="CenterOwner" CanResize="False">
<StackPanel Margin="14" Spacing="6">
<TextBlock TextWrapping="Wrap" FontSize="11" Opacity="0.75"
Text="This computer's name on the network and the port it listens on for contacts. Where contacts are sent is set in Config ▸ Configure Broadcast Data." />
<Grid ColumnDefinitions="*,8,110" RowDefinitions="Auto,Auto">
<TextBlock Text="This station's name" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="NameBox" Grid.Row="1" />
<TextBlock Grid.Column="2" Text="Port" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="PortBox" Grid.Row="1" Grid.Column="2" />
</Grid>
<TextBlock Text="The other logging computers" FontWeight="Bold" Margin="0,12,0,0" />
<TextBlock TextWrapping="Wrap" FontSize="11" Opacity="0.75"
Text="This is N1MM's own link between the computers of one entry, on port 12070: contacts, edits, deletes and chat, over a connection to each station. Stations are found by broadcast, so nothing has to be listed." />
<Grid ColumnDefinitions="90,8,110,8,*" RowDefinitions="Auto,Auto">
<TextBlock Text="Station number" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="StationNumberBox" Grid.Row="1" />
<TextBlock Grid.Column="2" Text="Port" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="LinkPortBox" Grid.Row="1" Grid.Column="2" />
<TextBlock Grid.Column="4" Text="Version to claim" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="VersionBox" Grid.Row="1" Grid.Column="4" />
</Grid>
<TextBlock TextWrapping="Wrap" FontSize="11" Opacity="0.75"
Text="N1MM turns away a station whose version is not its own, so this has to be the version the N1MM copies beside it are running. Help ▸ About in N1MM says which." />
<TextBlock Text="Stations to reach by address, one per line, as NAME@address" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="LinkPeersBox" AcceptsReturn="True" Height="60" PlaceholderText="RUN-PC@192.168.1.11" />
<CheckBox Name="LinkEnabledBox" Content="Share contacts with the other logging computers (port 12070)" Margin="0,6,0,0" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="6" Margin="0,8,0,0">
<Button Content="Cancel" Click="OnCancel" />
<Button Content="Save" Click="OnSave" IsDefault="True" />
</StackPanel>
</StackPanel>
</Window>
@@ -0,0 +1,21 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Nonemm.App.Dialogs.StationsConfigDialog"
Title="Stations Configuration" Width="440" SizeToContent="Height"
WindowStartupLocation="CenterOwner" CanResize="False">
<StackPanel Margin="14" Spacing="6">
<Grid ColumnDefinitions="*,8,110" RowDefinitions="Auto,Auto">
<TextBlock Text="This station's name" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="NameBox" Grid.Row="1" />
<TextBlock Grid.Column="2" Text="Port" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="PortBox" Grid.Row="1" Grid.Column="2" />
</Grid>
<TextBlock Text="Stations to reach by address, one per line, as NAME@address" FontSize="11" Opacity="0.7" Margin="0,6,0,1" />
<TextBox Name="LinkPeersBox" AcceptsReturn="True" Height="60" PlaceholderText="RUN-PC@192.168.1.11" />
<CheckBox Name="LinkEnabledBox" Content="Share contacts with the other logging computers" Margin="0,6,0,0" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="6" Margin="0,8,0,0">
<Button Content="Cancel" Click="OnCancel" />
<Button Content="Save" Click="OnSave" IsDefault="True" />
</StackPanel>
</StackPanel>
</Window>
@@ -4,11 +4,11 @@ using Nonemm.App.Configuration;
namespace Nonemm.App.Dialogs; namespace Nonemm.App.Dialogs;
public sealed partial class NetworkDialog : Window public sealed partial class StationsConfigDialog : Window
{ {
private readonly Settings settings; private readonly Settings settings;
public NetworkDialog(Settings settings) public StationsConfigDialog(Settings settings)
{ {
this.settings = settings; this.settings = settings;
InitializeComponent(); InitializeComponent();
@@ -16,25 +16,14 @@ public sealed partial class NetworkDialog : Window
? settings.NetworkStationName ? settings.NetworkStationName
: Environment.MachineName; : Environment.MachineName;
PortBox.Text = settings.NetworkPort.ToString(); PortBox.Text = settings.NetworkPort.ToString();
StationNumberBox.Text = settings.StationNumber.ToString();
LinkPortBox.Text = settings.StationLinkPort.ToString();
VersionBox.Text = settings.StationLinkVersion;
LinkPeersBox.Text = string.Join("\n", settings.StationLinkPeers); LinkPeersBox.Text = string.Join("\n", settings.StationLinkPeers);
LinkEnabledBox.IsChecked = settings.StationLinkEnabled; LinkEnabledBox.IsChecked = settings.StationLinkEnabled;
} }
private void OnSave(object? sender, RoutedEventArgs e) => Close(settings with private void OnSave(object? sender, RoutedEventArgs e) => Close(settings with
{ {
NetworkStationName = (NameBox.Text ?? "").Trim(), NetworkStationName = (NameBox.Text ?? "").Trim(),
NetworkPort = int.TryParse(PortBox.Text, out int port) ? port : 12060, NetworkPort = int.TryParse(PortBox.Text, out int port) ? port : 12060,
StationNumber = int.TryParse(StationNumberBox.Text, out int number)
? Math.Clamp(number, 1, 99)
: settings.StationNumber,
StationLinkPort = int.TryParse(LinkPortBox.Text, out int linkPort)
? linkPort
: settings.StationLinkPort,
StationLinkVersion = (VersionBox.Text ?? "").Trim(),
StationLinkPeers = Lines(LinkPeersBox.Text), StationLinkPeers = Lines(LinkPeersBox.Text),
StationLinkEnabled = LinkEnabledBox.IsChecked == true, StationLinkEnabled = LinkEnabledBox.IsChecked == true,
}); });
@@ -559,19 +559,6 @@ public sealed partial class EntryWindow
Refresh(); Refresh();
} }
private async void OnNetworkSettings(object? sender, RoutedEventArgs e)
{
NetworkDialog dialog = new(session.Settings);
Settings? updated = await dialog.ShowDialog<Settings?>(this);
if (updated is not null)
{
session.Save(updated);
session.ApplyNetworkSettings();
session.ApplyStationLinkSettings();
Status(Networking(updated));
}
}
private async void OnBandmapSettings(object? sender, RoutedEventArgs e) private async void OnBandmapSettings(object? sender, RoutedEventArgs e)
{ {
BandmapDialog dialog = new(session.Settings); BandmapDialog dialog = new(session.Settings);
@@ -596,16 +583,6 @@ public sealed partial class EntryWindow
} }
} }
/// What the two networks are now doing, for the status line.
private static string Networking(Settings settings) =>
(settings.NetworkEnabled, settings.StationLinkEnabled) switch
{
(true, true) => "broadcasting contacts and linked to the other computers",
(true, false) => "broadcasting contacts to other programs",
(false, true) => "linked to the other logging computers",
_ => "networking off",
};
private async void OnKeyerSettings(object? sender, RoutedEventArgs e) private async void OnKeyerSettings(object? sender, RoutedEventArgs e)
{ {
KeyerDialog dialog = new(session.Settings); KeyerDialog dialog = new(session.Settings);
-1
View File
@@ -114,7 +114,6 @@
</MenuItem> </MenuItem>
<MenuItem Header="Change Band Plan…" Click="OnSubBandSettings" /> <MenuItem Header="Change Band Plan…" Click="OnSubBandSettings" />
<MenuItem Header="Manage Skins, Colors and Fonts…" Click="OnThemeSettings" /> <MenuItem Header="Manage Skins, Colors and Fonts…" Click="OnThemeSettings" />
<MenuItem Header="Edit Networked-Computer Names…" Click="OnNetworkSettings" />
<MenuItem Header="Configure Broadcast Data…" Click="OnBroadcastSettings" /> <MenuItem Header="Configure Broadcast Data…" Click="OnBroadcastSettings" />
<MenuItem Header="WAE"> <MenuItem Header="WAE">
<MenuItem Header="Open QTC Window setup area" Click="OnQtcSetup" /> <MenuItem Header="Open QTC Window setup area" Click="OnQtcSetup" />
@@ -114,8 +114,15 @@
<RadioButton Name="Run2Button" GroupName="RunPosition" Content="Run2/Mult" <RadioButton Name="Run2Button" GroupName="RunPosition" Content="Run2/Mult"
IsCheckedChanged="OnRunPositionChanged" /> IsCheckedChanged="OnRunPositionChanged" />
</StackPanel> </StackPanel>
<TextBlock TextWrapping="Wrap" FontSize="11" Opacity="0.75" <Grid ColumnDefinitions="90,8,110,8,140" RowDefinitions="Auto,Auto">
Text="N1MM's transmit interlocks are not here: this program does not block a transmitter, so a station that claims it does would be waited on for nothing." /> <TextBlock Text="Station Number" FontSize="11" Opacity="0.7" />
<TextBox Name="StationNumberBox" Grid.Row="1" LostFocus="OnLinkIdentityChanged" />
<TextBlock Grid.Column="2" Text="Port" FontSize="11" Opacity="0.7" />
<TextBox Name="LinkPortBox" Grid.Row="1" Grid.Column="2" LostFocus="OnLinkIdentityChanged" />
<TextBlock Grid.Column="4" Text="Version to claim" FontSize="11" Opacity="0.7" />
<TextBox Name="VersionBox" Grid.Row="1" Grid.Column="4" LostFocus="OnLinkIdentityChanged" />
</Grid>
<Button Content="Stations Configuration" Click="OnSetup" HorizontalAlignment="Left" />
</StackPanel> </StackPanel>
</TabItem> </TabItem>
@@ -57,6 +57,9 @@ public sealed partial class NetworkStatusWindow : RefreshableWindow
LogEverywhereBox.IsChecked = session.Settings.LogQsosAtAllStations; LogEverywhereBox.IsChecked = session.Settings.LogQsosAtAllStations;
Run1Button.IsChecked = !session.IsRun2; Run1Button.IsChecked = !session.IsRun2;
Run2Button.IsChecked = session.IsRun2; Run2Button.IsChecked = session.IsRun2;
StationNumberBox.Text = session.Settings.StationNumber.ToString();
LinkPortBox.Text = session.Settings.StationLinkPort.ToString();
VersionBox.Text = session.Settings.StationLinkVersion;
Attach(); Attach();
// the Receive column is a countdown, so it has to redraw with nothing // the Receive column is a countdown, so it has to redraw with nothing
// arriving // arriving
@@ -400,6 +403,30 @@ public sealed partial class NetworkStatusWindow : RefreshableWindow
} }
} }
/// Saves the station number, port and version when a box loses focus, and
/// reconnects the link with them.
private void OnLinkIdentityChanged(object? sender, RoutedEventArgs e)
{
Settings current = session.Settings;
Settings updated = current with
{
StationNumber = int.TryParse(StationNumberBox.Text, out int number)
? Math.Clamp(number, 1, 99)
: current.StationNumber,
StationLinkPort = int.TryParse(LinkPortBox.Text, out int port) ? port : current.StationLinkPort,
StationLinkVersion = (VersionBox.Text ?? "").Trim(),
};
StationNumberBox.Text = updated.StationNumber.ToString();
LinkPortBox.Text = updated.StationLinkPort.ToString();
if (updated == current)
{
return;
}
session.Save(updated);
session.ApplyStationLinkSettings();
Refresh();
}
private void OnRunPositionChanged(object? sender, RoutedEventArgs e) private void OnRunPositionChanged(object? sender, RoutedEventArgs e)
{ {
if (Run2Button.IsChecked == true != session.IsRun2) if (Run2Button.IsChecked == true != session.IsRun2)
@@ -507,7 +534,7 @@ public sealed partial class NetworkStatusWindow : RefreshableWindow
private async void OnSetup(object? sender, RoutedEventArgs e) private async void OnSetup(object? sender, RoutedEventArgs e)
{ {
NetworkDialog dialog = new(session.Settings); StationsConfigDialog dialog = new(session.Settings);
if (await dialog.ShowDialog<Settings?>(this) is { } updated) if (await dialog.ShowDialog<Settings?>(this) is { } updated)
{ {
session.Save(updated); session.Save(updated);