HamBook – Rev 59
?pathlinks?
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using HamBook.Properties;
using HamBook.Radios;
using HamBook.Radios.Generic;
using HamBook.Utilities;
using HamBook.Utilities.Controls;
using HamBook.Utilities.Serialization;
using NetSparkleUpdater;
using NetSparkleUpdater.Enums;
using NetSparkleUpdater.SignatureVerifiers;
using NetSparkleUpdater.UI.WinForms;
using RJCP.IO.Ports;
using Serilog;
using PowerState = HamBook.Radios.Generic.PowerState;
namespace HamBook
{
public partial class Form1 : Form
{
private readonly CancellationToken _cancellationToken;
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly ScheduledContinuation _changedConfigurationContinuation;
private readonly ConcurrentDictionary<string, MemoryChannel> _memoryChannelStore =
new ConcurrentDictionary<string, MemoryChannel>();
private readonly LogMemorySink _memorySink;
private readonly SparkleUpdater _sparkle;
private readonly ScheduledContinuation _squelchScheduledContinuation;
private AboutForm _aboutForm;
private BandScan _bandScan;
private CatAssemblies _catAssemblies;
private MemoryBanks _memoryBanks;
private MemoryOrganizerForm _memoryOrganizerForm;
private MemoryTune _memoryTune;
private MenuForm _menuForm;
private ScheduledContinuation _powerScheduledContinuation;
private SerialPortStream _serialPort;
private SettingsForm _settingsForm;
private SpectrogramForm _spectrogramForm;
private string _storedMemoryChannelLocation;
private string _storedMemoryChannelTagText;
private CancellationToken _tagTickerCancellationToken;
private CancellationTokenSource _tagTickerCancellationTokenSource;
private Task _tickerTask;
private volatile bool _tickerTaskRunning;
private MemoryChannel _tickerTextMemoryChannel;
private ViewLogsForm _viewLogsForm;
private Form1()
{
_cancellationTokenSource = new CancellationTokenSource();
_cancellationToken = _cancellationTokenSource.Token;
_changedConfigurationContinuation = new ScheduledContinuation();
_squelchScheduledContinuation = new ScheduledContinuation();
_powerScheduledContinuation = new ScheduledContinuation();
}
public Form1(Mutex mutex) : this()
{
InitializeComponent();
_memorySink = new LogMemorySink();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Conditional(condition => MemorySinkEnabled, configureSink => configureSink.Sink(_memorySink))
.WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
rollingInterval: RollingInterval.Day)
.CreateLogger();
// Start application update.
var manifestModuleName = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName;
var icon = Icon.ExtractAssociatedIcon(manifestModuleName);
_sparkle = new SparkleUpdater("https://hambook.grimore.org/update/appcast.xml",
new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY="))
{
UIFactory = new UIFactory(icon),
RelaunchAfterUpdate = true,
SecurityProtocolType = SecurityProtocolType.Tls12
};
_sparkle.StartLoop(true, true);
}
private Configuration.Configuration Configuration { get; set; }
public bool MemorySinkEnabled { get; set; }
private async void Form1_Load(object sender, EventArgs e)
{
Configuration = await LoadConfiguration();
_memoryBanks = MemoryBanks.Create(Configuration.Radio);
_serialPort = InitializeSerialPort(Configuration);
_catAssemblies = InitializeAssemblies(_serialPort);
// Initialize power state.
try
{
switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
{
case PowerState.ON:
Log.Information(Resources.Attempting_to_initialize_radio);
if (!await InitializeRadio()) return;
Log.Information(Resources.Initializing_GUI);
break;
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_power_state);
}
// Initialize memory banks.
var memoryBankQueue = new ConcurrentQueue<string>();
var memoryBankTaskCompletionSource = new TaskCompletionSource<bool>();
async void IdleHandler(object idleHandlerSender, EventArgs idleHandlerArgs)
{
await memoryBankTaskCompletionSource.Task;
try
{
if (!memoryBankQueue.TryDequeue(out var memoryBank))
{
Application.Idle -= IdleHandler;
return;
}
scrollableToolStripComboBox12.Items.Add(memoryBank);
var memoryChannel = MemoryChannel.Create(Configuration.Radio);
try
{
memoryChannel = await _catAssemblies.CatReadAsync<MemoryChannel>("MT",
new object[] { memoryBank }, _cancellationToken);
scrollableToolStripComboBox5.Items.Add(memoryBank);
}
catch (Exception exception)
{
Log.Warning(exception, Resources.Could_not_read_memory_bank);
return;
}
_memoryChannelStore.TryAdd(memoryBank, memoryChannel);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Could_not_update_data_grid_view);
}
}
Application.Idle += IdleHandler;
try
{
foreach (var memoryBank in _memoryBanks.GetMemoryBanks()) memoryBankQueue.Enqueue(memoryBank);
memoryBankTaskCompletionSource.TrySetResult(true);
}
catch (Exception exception)
{
Application.Idle -= IdleHandler;
Log.Error(exception, Resources.Unable_to_read_memory_banks);
}
// Initialize lock state.
try
{
var lockState =
await _catAssemblies.CatReadAsync<LockState>("LK", new object[] { }, _cancellationToken);
switch (lockState)
{
case LockState.OFF:
lockToolStripMenuItem.Checked = false;
break;
case LockState.ON:
lockToolStripMenuItem.Checked = true;
break;
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_lock_state);
}
}
private async void quitToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_bandScan != null)
{
_bandScan.Stop();
_bandScan = null;
}
if (_memoryTune != null)
{
_memoryTune.Stop();
_memoryTune = null;
}
// Save configuration on quit.
await SaveConfiguration();
Close();
}
private void viewLogsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_viewLogsForm != null) return;
_viewLogsForm = new ViewLogsForm(this, _memorySink, _cancellationToken);
_viewLogsForm.Closing += ViewLogsForm_Closing;
_viewLogsForm.Show();
}
private void ViewLogsForm_Closing(object sender, CancelEventArgs e)
{
if (_viewLogsForm == null) return;
_viewLogsForm.Closing -= ViewLogsForm_Closing;
_viewLogsForm.Close();
_viewLogsForm = null;
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_aboutForm != null) return;
_aboutForm = new AboutForm();
_aboutForm.Closing += AboutForm_Closing;
_aboutForm.Show();
}
private void AboutForm_Closing(object sender, CancelEventArgs e)
{
if (_aboutForm == null) return;
_aboutForm.Dispose();
_aboutForm = null;
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_settingsForm != null) return;
_settingsForm = new SettingsForm(Configuration, _cancellationToken);
_settingsForm.Closing += SettingsForm_Closing;
_settingsForm.Show();
}
private void SettingsForm_Closing(object sender, CancelEventArgs e)
{
if (_settingsForm == null) return;
if (_settingsForm.SaveOnClose)
// Commit the configuration.
_changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
async () =>
{
await SaveConfiguration();
if (_bandScan != null)
{
_bandScan.Stop();
_bandScan = null;
}
if (_memoryTune != null)
{
_memoryTune.Stop();
_memoryTune = null;
}
_memoryBanks = MemoryBanks.Create(Configuration.Radio);
Miscellaneous.LaunchOnBootSet(Configuration.LaunchOnBoot);
_serialPort = InitializeSerialPort(Configuration);
_catAssemblies = InitializeAssemblies(_serialPort);
try
{
if (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { },
_cancellationToken) == PowerState.ON)
{
Log.Information(Resources.Attempting_to_initialize_radio);
if (!await InitializeRadio()) return;
Log.Information(Resources.Initializing_GUI);
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_power_state);
}
}, _cancellationToken);
_settingsForm.Closing -= SettingsForm_Closing;
_settingsForm.Dispose();
_settingsForm = null;
}
public async Task SaveConfiguration()
{
if (!Directory.Exists(Constants.UserApplicationDirectory))
Directory.CreateDirectory(Constants.UserApplicationDirectory);
switch (await Serialization.Serialize(Configuration, Constants.ConfigurationFile, "Configuration",
"<!ATTLIST Configuration xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
CancellationToken.None))
{
case SerializationSuccess<Configuration.Configuration> configuration:
Log.Information(Resources.Configuration_serialized_successfully);
break;
case SerializationFailure serializationFailure:
Log.Warning(serializationFailure.Exception.Message, Resources.Configuration_failed_to_serialize);
break;
}
}
public static async Task<Configuration.Configuration> LoadConfiguration()
{
if (!Directory.Exists(Constants.UserApplicationDirectory))
Directory.CreateDirectory(Constants.UserApplicationDirectory);
var deserializationResult =
await Serialization.Deserialize<Configuration.Configuration>(Constants.ConfigurationFile,
Constants.ConfigurationNamespace, Constants.ConfigurationXsd, CancellationToken.None);
switch (deserializationResult)
{
case SerializationSuccess<Configuration.Configuration> serializationSuccess:
return serializationSuccess.Result;
case SerializationFailure serializationFailure:
Log.Warning(serializationFailure.Exception, Resources.Configuration_failed_to_deserialize);
return new Configuration.Configuration();
default:
return new Configuration.Configuration();
}
}
private async Task<bool> InitializeRadio()
{
try
{
await _catAssemblies.CatWriteAsync<InformationState>("AI", new object[] { InformationState.OFF },
_cancellationToken);
return await _catAssemblies.CatReadAsync<bool>("ID", new object[] { }, _cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Unable_to_initialize_radio);
return false;
}
}
private CatAssemblies InitializeAssemblies(SerialPortStream serialPort)
{
if (_catAssemblies != null)
{
_catAssemblies.Dispose();
_catAssemblies = null;
}
return new CatAssemblies(serialPort, Configuration.Radio);
}
private SerialPortStream InitializeSerialPort(Configuration.Configuration configuration)
{
if (_serialPort != null)
{
if (_serialPort.IsOpen) _serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
// Set up serial connection.
var serialPort = new SerialPortStream(configuration.Port, configuration.Speed, configuration.DataBits,
configuration.Parity, configuration.StopBits);
serialPort.ReadTimeout = configuration.SerialPortTimeout.Read;
serialPort.WriteTimeout = configuration.SerialPortTimeout.Write;
serialPort.Handshake = configuration.Handshake;
serialPort.Encoding = Encoding.ASCII;
Log.Information(
$"{Resources.Initialized_serial_port} {configuration.Port} {configuration.Speed} {configuration.Parity} {configuration.DataBits} {configuration.StopBits}");
return serialPort;
}
private async void updateToolStripMenuItem_Click(object sender, EventArgs e)
{
// Manually check for updates, this will not show a ui
var result = await _sparkle.CheckForUpdatesQuietly();
if (result.Status == UpdateStatus.UpdateAvailable)
{
// if update(s) are found, then we have to trigger the UI to show it gracefully
_sparkle.ShowUpdateNeededUI();
return;
}
MessageBox.Show(Resources.No_updates_available_at_this_time, Resources.HamBook, MessageBoxButtons.OK,
MessageBoxIcon.Asterisk,
MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, false);
}
private async void onToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
await _catAssemblies.CatSetAsync<PowerState, bool>("PS", new object[] { PowerState.ON },
_cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_power_state);
}
}
private async void offToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
await _catAssemblies.CatSetAsync<PowerState, bool>("PS", new object[] { PowerState.OFF },
_cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_power_state);
}
}
private async void scrollableToolStripComboBox2_MouseWheel(object sender, MouseEventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (int.TryParse(toolStripComboBox.Text, out var frequency))
{
switch (Math.Sign(e.Delta))
{
case -1:
frequency = frequency - Configuration.Navigation.FrequencyStep;
break;
case 1:
frequency = frequency + Configuration.Navigation.FrequencyStep;
break;
}
try
{
using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("HamBook.Effects.pot.wav")))
{
if (!await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency },
_cancellationToken))
return;
toolStripComboBox.Text = $"{frequency}";
if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
}
}
}
private async void scrollableToolStripComboBox2_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
case (char)Keys.Enter:
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (int.TryParse(toolStripComboBox.Text, out var frequency))
try
{
using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("HamBook.Effects.pot.wav")))
{
if (await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency },
_cancellationToken))
{
e.Handled = true;
if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
}
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
}
break;
}
}
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
if (_bandScan == null) return;
_bandScan.Stop();
_bandScan = null;
}
private void toolStripMenuItem38_Click(object sender, EventArgs e)
{
if (_memoryTune != null)
{
_memoryTune.Stop();
_memoryTune = null;
}
_memoryTune = new MemoryTune(_catAssemblies, _serialPort, Configuration);
_memoryTune.Start();
}
private void stopToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_memoryTune == null) return;
_memoryTune.Stop();
_memoryTune = null;
}
private void scanToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!(sender is ToolStripMenuItem toolStripMenuItem) ||
!int.TryParse(toolStripMenuItem.Tag.ToString(), out var meters))
return;
if (!int.TryParse(scrollableToolStripComboBox3.Text, out var pause)) pause = 5;
if (!int.TryParse(scrollableToolStripComboBox4.Text, out var step)) step = 5000;
if (!int.TryParse(scrollableToolStripComboBox6.Text, out var scanDetectPause)) scanDetectPause = 10;
if (!Configuration.Definitions.TryGetBand(meters, out var band)) return;
if (_bandScan != null)
{
_bandScan.Stop();
_bandScan = null;
}
_bandScan = new BandScan(_catAssemblies, (int)band.Min, (int)band.Max, _serialPort, Configuration);
if (toolStripMenuItem14.Checked)
{
_bandScan.Start(step, pause, scanDetectPause, toolStripMenuItem16.Checked);
return;
}
_bandScan.Start(step, pause, 0, toolStripMenuItem16.Checked);
}
private async void modeToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
{
try
{
var mode = await _catAssemblies.CatReadAsync<RadioMode>("MD", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip => { toolStripComboBox1.Text = mode.Name; });
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_radio_mode);
}
try
{
var fa = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
scrollableToolStripComboBox1.Text = $"{fa}";
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_VFO_A);
}
try
{
var fb = await _catAssemblies.CatReadAsync<int>("FB", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
scrollableToolStripComboBox2.Text = $"{fb}";
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_VFO_B);
}
try
{
var mc = await _catAssemblies.CatReadAsync<string>("MC", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
scrollableToolStripComboBox5.Text = mc;
if (_memoryChannelStore.TryGetValue(mc, out var memoryChannel))
toolStripMenuItem27.Text = memoryChannel.Text;
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_memory_channel);
}
try
{
var pc = await _catAssemblies.CatReadAsync<int>("PC", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
scrollableToolStripComboBox7.Text = $"{pc}";
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_power_state);
}
try
{
var sq = await _catAssemblies.CatReadAsync<int>("SQ", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
scrollableToolStripComboBox11.Text = $"{sq}";
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_squelch);
}
try
{
var st = await _catAssemblies.CatReadAsync<SplitState>("ST", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
scrollableToolStripComboBox8.Text = $"{(string)st}";
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_split_state);
}
try
{
var lockState =
await _catAssemblies.CatReadAsync<LockState>("LK", new object[] { }, _cancellationToken);
switch (lockState)
{
case LockState.OFF:
lockToolStripMenuItem.Checked = false;
break;
case LockState.ON:
lockToolStripMenuItem.Checked = true;
break;
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_lock_state);
}
}
private void spectrogramToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_spectrogramForm != null) return;
_spectrogramForm = new SpectrogramForm(Configuration, _cancellationToken);
_spectrogramForm.Closing += SpectrogramForm_Closing;
_spectrogramForm.Show();
}
private void SpectrogramForm_Closing(object sender, CancelEventArgs e)
{
if (_spectrogramForm == null) return;
_spectrogramForm.Dispose();
_spectrogramForm = null;
// Commit the configuration.
_changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
async () => { await SaveConfiguration(); }, _cancellationToken);
}
private void toolStripMenuItem3_Click(object sender, EventArgs e)
{
if (_memoryOrganizerForm != null) return;
_memoryOrganizerForm = new MemoryOrganizerForm(Configuration, _catAssemblies, _cancellationToken);
_memoryOrganizerForm.Closing += MemoryOrganizerForm_Closing;
_memoryOrganizerForm.Show();
}
private void MemoryOrganizerForm_Closing(object sender, CancelEventArgs e)
{
if (_memoryOrganizerForm == null) return;
_memoryOrganizerForm.Dispose();
_memoryOrganizerForm = null;
}
private async void toolStripMenuItem4_Click(object sender, EventArgs e)
{
if (_tickerTaskRunning) return;
var toolStripTextBox = toolStripTextBox6;
try
{
var result =
await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { "001" }, _cancellationToken);
_tickerTextMemoryChannel = await _catAssemblies.CatReadAsync<MemoryChannel>("MT",
new object[] { $"{result.CurrentLocation}" }, _cancellationToken);
_storedMemoryChannelTagText = _tickerTextMemoryChannel.Text;
_storedMemoryChannelLocation = _tickerTextMemoryChannel.CurrentLocation;
}
catch (Exception exception)
{
Log.Error(exception, Resources.Could_not_read_memory_bank);
}
var tickerText = $"{toolStripTextBox.Text,-12}";
_tagTickerCancellationTokenSource = new CancellationTokenSource();
_tagTickerCancellationToken = _tagTickerCancellationTokenSource.Token;
var characterQueue = new Queue<char>(12);
foreach (var i in Enumerable.Range(0, 12))
{
var x = tickerText.ElementAtOrDefault(i);
if (x == default)
{
characterQueue.Enqueue(' ');
continue;
}
characterQueue.Enqueue(x);
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
_tickerTask = Task.Run(() => CycleText(characterQueue), _cancellationToken);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
private async void toolStripMenuItem5_Click(object sender, EventArgs e)
{
if (!_tickerTaskRunning) return;
_tagTickerCancellationTokenSource.Cancel();
if (_tickerTask != null)
{
await _tickerTask;
_tickerTask = null;
}
try
{
_tickerTextMemoryChannel.CurrentLocation = $"{_storedMemoryChannelLocation:000}";
_tickerTextMemoryChannel.Text = $"{_storedMemoryChannelTagText,-12}";
var success = await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT",
new object[] { _tickerTextMemoryChannel }, _cancellationToken);
if (!success) Log.Error(Resources.Error_while_restoring_memory_text);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Error_while_restoring_memory_text);
}
finally
{
_tickerTaskRunning = false;
}
}
private async Task CycleText(Queue<char> characterQueue)
{
_tickerTaskRunning = true;
try
{
do
{
var text = string.Join("", characterQueue.OfType<char>());
_tickerTextMemoryChannel.Text = text;
await _catAssemblies.CatWriteAsync<MemoryChannel>("MT", new object[] { _tickerTextMemoryChannel },
_cancellationToken);
var x = characterQueue.Dequeue();
characterQueue.Enqueue(x);
await Task.Delay(250);
} while (!_tagTickerCancellationToken.IsCancellationRequested);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Error_while_cycling_text);
}
}
private async void scrollableToolStripComboBox5_SelectedIndexChanged(object sender, EventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
var channel = toolStripComboBox.Text;
if (!string.IsNullOrEmpty(channel))
if (_memoryChannelStore.TryGetValue(channel, out var memoryChannel))
try
{
using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("HamBook.Effects.pot.wav")))
{
await _catAssemblies.CatWriteAsync<string>("MC", new object[] { channel },
_cancellationToken);
scrollableToolStripComboBox1.Text = $"{memoryChannel.Frequency}";
toolStripMenuItem27.Text = memoryChannel.Text;
soundPlayer.Play();
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_memory_channel);
}
}
private async void powerToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
{
var toolStripMenuItem = toolStripMenuItem11;
try
{
switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
{
case PowerState.ON:
toolStripMenuItem.Text = Resources.On;
break;
case PowerState.OFF:
toolStripMenuItem.Text = Resources.Off;
break;
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_power_state);
}
}
private async void toolStripMenuItem17_Click(object sender, EventArgs e)
{
try
{
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
_cancellationToken);
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START },
_cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_tuning_current_frequency);
}
}
private async void toolStripMenuItem22_CheckStateChanged(object sender, EventArgs e)
{
var toolStripMenuItem = (ToolStripMenuItem)sender;
try
{
if (toolStripMenuItem.Checked)
{
await _catAssemblies.CatWriteAsync<IpoState>("PA", new object[] { IpoState.IPO },
_cancellationToken);
return;
}
await _catAssemblies.CatWriteAsync<IpoState>("PA", new object[] { IpoState.AMP }, _cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_setting_IPO);
}
}
private async void toolStripMenuItem23_CheckStateChanged(object sender, EventArgs e)
{
var toolStripMenuItem = (ToolStripMenuItem)sender;
try
{
if (toolStripMenuItem.Checked)
{
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
_cancellationToken);
return;
}
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_OFF },
_cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_setting_the_tuner_state);
}
}
private async void toolStripMenuItem24_Click(object sender, EventArgs e)
{
try
{
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
_cancellationToken);
do
{
await Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken);
try
{
var tuneState =
await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _cancellationToken);
if (tuneState == TunerState.TUNER_ON) break;
}
catch (Exception)
{
// retry
}
} while (!_cancellationToken.IsCancellationRequested);
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START },
_cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Could_not_start_tuning);
}
}
private void toolStripMenuItem21_DropDownOpening(object sender, EventArgs e)
{
Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken).ContinueWith(async task =>
{
try
{
var ac = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
switch (ac)
{
case TunerState.TUNING_START:
case TunerState.TUNER_ON:
toolStripMenuItem23.Checked = true;
break;
case TunerState.TUNER_OFF:
toolStripMenuItem23.Checked = false;
break;
}
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_the_tuner_state);
}
try
{
var pa = await _catAssemblies.CatReadAsync<IpoState>("PA", new object[] { }, _cancellationToken);
contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
{
switch (pa)
{
case IpoState.AMP:
toolStripMenuItem22.Checked = false;
break;
case IpoState.IPO:
toolStripMenuItem22.Checked = true;
break;
}
});
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_IPO);
}
}, _cancellationToken);
}
private async void scrollableToolStripComboBox1_MouseWheel(object sender, MouseEventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (int.TryParse(toolStripComboBox.Text, out var frequency))
{
switch (Math.Sign(e.Delta))
{
case -1:
frequency = frequency - Configuration.Navigation.FrequencyStep;
break;
case 1:
frequency = frequency + Configuration.Navigation.FrequencyStep;
break;
}
try
{
using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("HamBook.Effects.pot.wav")))
{
if (!await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency },
_cancellationToken))
return;
toolStripComboBox.Text = $"{frequency}";
if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
}
}
}
private async void scrollableToolStripComboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
case (char)Keys.Enter:
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (!int.TryParse(toolStripComboBox.Text, out var frequency)) break;
try
{
using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("HamBook.Effects.pot.wav")))
{
if (await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency },
_cancellationToken))
{
e.Handled = true;
if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
}
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
}
break;
}
}
private void scrollableToolStripComboBox11_SelectedIndexChanged(object sender, EventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
_squelchScheduledContinuation.Schedule(TimeSpan.FromSeconds(1), () =>
{
contextMenuStrip1.InvokeIfRequired(async contextMenuStrip1 =>
{
if (!int.TryParse(toolStripComboBox.Text, out var squelch)) return;
try
{
await _catAssemblies.CatWriteAsync<int>("SQ", new object[] { squelch }, _cancellationToken);
toolStripComboBox.Text = $"{squelch}";
Log.Information($"{Resources.Squelch_set} {squelch}");
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_squelch);
}
});
}, _cancellationToken);
}
private async void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var toolStripComboBox = (ToolStripComboBox)sender;
var radioMode = RadioMode.Create(Configuration.Radio, toolStripComboBox.Text);
try
{
await _catAssemblies.CatSetAsync<RadioMode, bool>("MD", new object[] { radioMode }, _cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_radio_mode, radioMode);
}
}
private async void scrollableToolStripComboBox7_SelectedIndexChanged(object sender, EventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (int.TryParse(toolStripComboBox.Text, out var amplification))
try
{
if (await _catAssemblies.CatSetAsync<int, bool>("PC", new object[] { amplification },
_cancellationToken))
{
toolStripComboBox.Text = $"{amplification}";
Log.Information($"{Resources.Amplification_set} {amplification}W");
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_amplification);
}
}
private async void scrollableToolStripComboBox7_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
case (char)Keys.Enter:
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (int.TryParse(toolStripComboBox.Text, out var amplification))
try
{
if (await _catAssemblies.CatSetAsync<int, bool>("PC", new object[] { amplification },
_cancellationToken))
{
toolStripComboBox.Text = $"{amplification}";
Log.Information($"{Resources.Amplification_set} {amplification}W");
e.Handled = true;
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_amplification);
}
break;
}
}
private void toolStripMenuItem30_Click(object sender, EventArgs e)
{
if (!int.TryParse(scrollableToolStripComboBox9.Text, out var start)
|| !int.TryParse(scrollableToolStripComboBox10.Text, out var stop))
return;
if (!int.TryParse(scrollableToolStripComboBox3.Text, out var pause)) pause = 5;
if (!int.TryParse(scrollableToolStripComboBox4.Text, out var step)) step = 5000;
if (!int.TryParse(scrollableToolStripComboBox6.Text, out var scanDetectPause)) scanDetectPause = 10;
if (_bandScan != null)
{
_bandScan.Stop();
_bandScan = null;
}
_bandScan = new BandScan(_catAssemblies, start, stop, _serialPort, Configuration);
if (toolStripMenuItem14.Checked)
{
_bandScan.Start(step, pause, scanDetectPause, toolStripMenuItem16.Checked);
return;
}
_bandScan.Start(step, pause, 0, toolStripMenuItem16.Checked);
}
private async void toolStripMenuItem32_Click(object sender, EventArgs e)
{
var toolStripMenuItem = toolStripMenuItem31;
try
{
if (await _catAssemblies.CatSetAsync<TxState, bool>("TX", new object[] { TxState.ON },
_cancellationToken))
toolStripMenuItem.Text = Resources.On;
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_PTT_state);
}
}
private async void toolStripMenuItem33_Click(object sender, EventArgs e)
{
var toolStripMenuItem = toolStripMenuItem31;
try
{
if (await _catAssemblies.CatSetAsync<TxState, bool>("TX", new object[] { TxState.OFF },
_cancellationToken))
toolStripMenuItem.Text = Resources.Off;
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_PTT_state);
}
}
private async void toolStripMenuItem26_DropDownOpening(object sender, EventArgs e)
{
var toolStripMenuItem = toolStripMenuItem31;
try
{
switch (await _catAssemblies.CatReadAsync<TxState>("TX", new object[] { }, _cancellationToken))
{
case TxState.ON:
toolStripMenuItem.Text = Resources.On;
break;
case TxState.OFF:
toolStripMenuItem.Text = Resources.Off;
break;
}
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_PTT_state);
}
}
private async void scrollableToolStripComboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
if (!SplitState.TryParse(toolStripComboBox.Text, out var splitState)) return;
try
{
if (await _catAssemblies.CatSetAsync<int, bool>("ST", new object[] { splitState },
_cancellationToken)) Log.Information($"{Resources.Split_state_set} {splitState}W");
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_set_split_state);
}
}
private async void toolStripMenuItem35_Click(object sender, EventArgs e)
{
var scrollableToolStripComboBox = scrollableToolStripComboBox12;
var channel = scrollableToolStripComboBox.Text;
if (!string.IsNullOrEmpty(channel))
{
if (!_memoryChannelStore.TryGetValue(channel, out var memoryChannel))
{
memoryChannel = MemoryChannel.Create(Configuration.Radio);
memoryChannel.CurrentLocation = channel;
memoryChannel.MemoryRadioMode =
MemoryRadioMode.Create(Configuration.Radio, toolStripComboBox1.Text);
}
if (memoryChannel.Tag = !string.IsNullOrEmpty(toolStripTextBox1.Text))
memoryChannel.Text = $"{toolStripTextBox1.Text,-12}";
if (int.TryParse(scrollableToolStripComboBox1.Text, out var frequency))
{
memoryChannel.Frequency = frequency;
try
{
if (await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT", new object[] { memoryChannel },
_cancellationToken)) Log.Information(Resources.Stored_VFO_A_to_memory);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_save_VFO_A_to_memory);
}
}
}
}
private void scrollableToolStripComboBox12_SelectedIndexChanged(object sender, EventArgs e)
{
var toolStripComboBox = (ScrollableToolStripComboBox)sender;
var channel = toolStripComboBox.Text;
if (!string.IsNullOrEmpty(channel))
{
if (_memoryChannelStore.TryGetValue(channel, out var memoryChannel))
{
toolStripTextBox1.Text = memoryChannel.Text;
return;
}
toolStripTextBox1.Text = string.Empty;
}
}
private async void toolStripMenuItem20_Click(object sender, EventArgs e)
{
try
{
var frequency = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
await _catAssemblies.CatWriteAsync<int>("FA", new object[] { frequency }, _cancellationToken);
await _catAssemblies.CatWriteAsync("SV", new object[] { }, _cancellationToken);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Unable_to_swap_VFO_A_and_VFO_B);
}
}
private async void lockToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
{
var toolStripMenuItem = (ToolStripMenuItem)sender;
try
{
LockState state;
switch (toolStripMenuItem.Checked)
{
case true:
state = LockState.ON;
break;
default:
state = LockState.OFF;
break;
}
if (!await _catAssemblies.CatSetAsync<LockState, bool>("LK", new object[] { state },
_cancellationToken)) Log.Error(Resources.Failed_to_set_lock_state);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Failed_to_read_lock_state);
}
}
private void menuToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_menuForm != null) return;
_menuForm = new MenuForm(Configuration, _catAssemblies, _cancellationToken);
_menuForm.Closing += MenuForm_Closing;
_menuForm.Show();
}
private void MenuForm_Closing(object sender, CancelEventArgs e)
{
if (_menuForm == null) return;
_menuForm.Dispose();
_menuForm = null;
}
}
}
Generated by GNU Enscript 1.6.5.90.