diff --git a/src/Nonemm.App/AppSession.QsySpot.cs b/src/Nonemm.App/AppSession.QsySpot.cs index 7b0bac1..9ce940d 100644 --- a/src/Nonemm.App/AppSession.QsySpot.cs +++ b/src/Nonemm.App/AppSession.QsySpot.cs @@ -79,7 +79,10 @@ public sealed partial class AppSession DateTime.UtcNow, SpotSource.Operator, position.Me.Callsign, - $"Local spot by {Settings.CurrentOperator}"); + $"Local spot by {Settings.CurrentOperator}") + { + Computer = ComputerName, + }; heardAt.Remove(position); Bandmap.Add(spot); SendSpots([spot]); @@ -113,6 +116,7 @@ public sealed partial class AppSession shared.Comment) { Qsx = shared.Qsx, + Computer = shared.Computer, }); } } diff --git a/src/Nonemm.App/Windows/BandmapView.cs b/src/Nonemm.App/Windows/BandmapView.cs index a1f3d01..caebb4d 100644 --- a/src/Nonemm.App/Windows/BandmapView.cs +++ b/src/Nonemm.App/Windows/BandmapView.cs @@ -49,6 +49,7 @@ public sealed class BandmapView : Control private static readonly IBrush OutsideBrush = new SolidColorBrush(Color.FromRgb(0xC0, 0x39, 0x2B), 0.13); private readonly Typeface typeface = new(Fonts.Mono); + private readonly Typeface boldTypeface = new(Fonts.Mono, FontStyle.Normal, FontWeight.Bold); private IReadOnlyList placed = []; private BandmapScale scale = new(Bands.Band20M.Low, Bands.Band20M.High, 1); @@ -176,7 +177,7 @@ public sealed class BandmapView : Control new Point(ScaleX + 2, label.MarkY), new Point(LabelX - 2, label.LabelY + (LabelHeight / 2))); context.DrawText( - Text(label.Spot.Call.Text, colour, TextSize), + Text(label.Spot.Call.Text, colour, TextSize, label.Spot.IsLocal), new Point(LabelX, label.LabelY + (LabelPadding / 2))); } @@ -216,8 +217,8 @@ public sealed class BandmapView : Control FrequencyPicked?.Invoke(this, scale.At(at.Y - Inset)); } - private FormattedText Text(string text, IBrush brush, double size) => - new(text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, size, brush); + private FormattedText Text(string text, IBrush brush, double size, bool bold = false) => + new(text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, bold ? boldTypeface : typeface, size, brush); /// The form's text colour, which the theme sets in both light and dark. private IBrush Foreground() => diff --git a/src/Nonemm.App/Windows/EntryWindow.Macros.cs b/src/Nonemm.App/Windows/EntryWindow.Macros.cs index 76212ad..292666c 100644 --- a/src/Nonemm.App/Windows/EntryWindow.Macros.cs +++ b/src/Nonemm.App/Windows/EntryWindow.Macros.cs @@ -499,7 +499,7 @@ public sealed partial class EntryWindow string comment = MessageExpander.Expand( session.Settings.SpotComment, Logging, session.Other(Logging)); _ = cluster.SendSpotAsync(Logging.Frequency, me, comment); - session.Bandmap.Add(new Spot(me, Logging.Frequency, DateTime.UtcNow, SpotSource.Operator)); + session.Bandmap.Add(new Spot(me, Logging.Frequency, DateTime.UtcNow, SpotSource.Operator) { Computer = session.ComputerName }); Status($"spotted {me.Text} on {Logging.Frequency.Kilohertz:0.0}"); } diff --git a/src/Nonemm.App/Windows/EntryWindow.Menu.cs b/src/Nonemm.App/Windows/EntryWindow.Menu.cs index 6d9981f..83cd72a 100644 --- a/src/Nonemm.App/Windows/EntryWindow.Menu.cs +++ b/src/Nonemm.App/Windows/EntryWindow.Menu.cs @@ -385,7 +385,7 @@ public sealed partial class EntryWindow return; } await cluster.SendSpotAsync(where, call, MessageExpander.Expand(session.Settings.SpotComment, Logging, session.Other(Logging))); - session.Bandmap.Add(new Spot(call, where, DateTime.UtcNow, SpotSource.Operator)); + session.Bandmap.Add(new Spot(call, where, DateTime.UtcNow, SpotSource.Operator) { Computer = session.ComputerName }); Status($"{call.Text} spotted on {where.Kilohertz:0.0}"); } @@ -428,7 +428,10 @@ public sealed partial class EntryWindow DateTime.UtcNow, SpotSource.Operator, session.Settings.Station.Callsign, - "Local spot")); + "Local spot") + { + Computer = session.ComputerName, + }); Status($"{call.Text} stored on {Logging.Frequency.Kilohertz:0.0}"); boxes[0].Focus(); } diff --git a/src/Nonemm.App/Windows/EntryWindow.axaml.cs b/src/Nonemm.App/Windows/EntryWindow.axaml.cs index d2b2dde..91e9481 100644 --- a/src/Nonemm.App/Windows/EntryWindow.axaml.cs +++ b/src/Nonemm.App/Windows/EntryWindow.axaml.cs @@ -1295,7 +1295,10 @@ public sealed partial class EntryWindow : Window Logging.Frequency, DateTime.UtcNow, Nonemm.Spotting.SpotSource.Operator, - Logging.Me.Callsign)); + Logging.Me.Callsign) + { + Computer = session.ComputerName, + }); Status($"{Logging.Entry.Call.Trim()} put on the bandmap"); } } diff --git a/src/Nonemm.Network/SharedSpot.cs b/src/Nonemm.Network/SharedSpot.cs index 7afd782..da29b20 100644 --- a/src/Nonemm.Network/SharedSpot.cs +++ b/src/Nonemm.Network/SharedSpot.cs @@ -11,4 +11,5 @@ public sealed record SharedSpot( string Comment, Frequency Qsx, string Spotter, - bool IsWorked); + bool IsWorked, + string Computer = ""); diff --git a/src/Nonemm.Network/StationMessages.cs b/src/Nonemm.Network/StationMessages.cs index eb5dd40..2ae65b1 100644 --- a/src/Nonemm.Network/StationMessages.cs +++ b/src/Nonemm.Network/StationMessages.cs @@ -372,7 +372,8 @@ public static class StationMessages record.Field(3), Frequency.FromKilohertz(record.Decimal(4) / 100), record.Field(5), - record.Flag(6)); + record.Flag(6), + record.ComputerName); /// What a message that has arrived means, or null for one this program does /// nothing with. diff --git a/src/Nonemm.Spotting/Spot.cs b/src/Nonemm.Spotting/Spot.cs index 41f3822..c1d5ad3 100644 --- a/src/Nonemm.Spotting/Spot.cs +++ b/src/Nonemm.Spotting/Spot.cs @@ -35,6 +35,14 @@ public sealed record Spot( IsStation = false, }; + /// The computer on the network that put the spot on the bandmap, or empty + /// for a spot that came from the cluster. + public string Computer { get; init; } = ""; + + /// A spot an operator put on a bandmap, here or on another computer, as + /// opposed to one from the cluster. + public bool IsLocal => Source == SpotSource.Operator && IsStation; + public bool IsSplit => Qsx.Hertz > 0; public Band? Band => Bands.ForFrequency(Frequency); diff --git a/src/Nonemm.Spotting/SpotDescription.cs b/src/Nonemm.Spotting/SpotDescription.cs index 462ef7d..6b91edd 100644 --- a/src/Nonemm.Spotting/SpotDescription.cs +++ b/src/Nonemm.Spotting/SpotDescription.cs @@ -11,8 +11,9 @@ public static class SpotDescription { string age = Age((nowUtc ?? DateTime.UtcNow) - spot.AtUtc); string kilohertz = spot.Frequency.Kilohertz.ToString("0.0", CultureInfo.InvariantCulture); - string first = spot.Spotter.Length > 0 - ? $"{kilohertz} by {spot.Spotter}, {age}" + string who = spot.IsLocal && spot.Computer.Length > 0 ? spot.Computer : spot.Spotter; + string first = who.Length > 0 + ? $"{kilohertz} by {who}, {age}" : $"{kilohertz}, {age}"; string comment = Comment(spot.Comment); return comment.Length > 0 ? $"{first}\n{comment}" : first; diff --git a/tests/Nonemm.Spotting.Tests/SpotDescriptionTests.cs b/tests/Nonemm.Spotting.Tests/SpotDescriptionTests.cs index caef7e3..111144a 100644 --- a/tests/Nonemm.Spotting.Tests/SpotDescriptionTests.cs +++ b/tests/Nonemm.Spotting.Tests/SpotDescriptionTests.cs @@ -59,4 +59,17 @@ public class SpotDescriptionTests Assert.Equal(expected, SpotDescription.Of(spot, At.AddSeconds(seconds))); } + + [Fact] + public void ALocalSpotNamesTheComputerInsteadOfTheSpotter() + { + Spot spot = new( + Callsign.Parse("JA1XYZ"), Frequency.FromKilohertz(14_025), At, SpotSource.Operator, + "OK1ABC") + { + Computer = "SHACK-2", + }; + + Assert.Equal("14025.0 by SHACK-2, 41m ago", SpotDescription.Of(spot, Now)); + } }