HamBook – Blame information for rev 59

Subversion Repositories:
Rev:
Rev Author Line No. Line
54 office 1 using System;
2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
1 office 4 using System.ComponentModel;
5 using System.Drawing;
6 using System.IO;
54 office 7 using System.Linq;
8 using System.Media;
57 office 9 using System.Net;
1 office 10 using System.Reflection;
54 office 11 using System.Text;
1 office 12 using System.Threading;
13 using System.Threading.Tasks;
14 using System.Windows.Forms;
15 using HamBook.Properties;
54 office 16 using HamBook.Radios;
1 office 17 using HamBook.Radios.Generic;
54 office 18 using HamBook.Utilities;
7 office 19 using HamBook.Utilities.Controls;
54 office 20 using HamBook.Utilities.Serialization;
21 using NetSparkleUpdater;
22 using NetSparkleUpdater.Enums;
23 using NetSparkleUpdater.SignatureVerifiers;
24 using NetSparkleUpdater.UI.WinForms;
9 office 25 using RJCP.IO.Ports;
54 office 26 using Serilog;
27 using PowerState = HamBook.Radios.Generic.PowerState;
1 office 28  
29 namespace HamBook
30 {
31 public partial class Form1 : Form
32 {
54 office 33 private readonly CancellationToken _cancellationToken;
34 private readonly CancellationTokenSource _cancellationTokenSource;
35 private readonly ScheduledContinuation _changedConfigurationContinuation;
36  
37 private readonly ConcurrentDictionary<string, MemoryChannel> _memoryChannelStore =
38 new ConcurrentDictionary<string, MemoryChannel>();
39  
40 private readonly LogMemorySink _memorySink;
41 private readonly SparkleUpdater _sparkle;
42 private readonly ScheduledContinuation _squelchScheduledContinuation;
43 private AboutForm _aboutForm;
44 private BandScan _bandScan;
45 private CatAssemblies _catAssemblies;
46 private MemoryBanks _memoryBanks;
47 private MemoryOrganizerForm _memoryOrganizerForm;
48 private MemoryTune _memoryTune;
49 private MenuForm _menuForm;
25 office 50 private ScheduledContinuation _powerScheduledContinuation;
9 office 51 private SerialPortStream _serialPort;
1 office 52 private SettingsForm _settingsForm;
10 office 53 private SpectrogramForm _spectrogramForm;
54 office 54 private string _storedMemoryChannelLocation;
55 private string _storedMemoryChannelTagText;
56 private CancellationToken _tagTickerCancellationToken;
1 office 57  
15 office 58 private CancellationTokenSource _tagTickerCancellationTokenSource;
59 private Task _tickerTask;
60 private volatile bool _tickerTaskRunning;
54 office 61 private MemoryChannel _tickerTextMemoryChannel;
62 private ViewLogsForm _viewLogsForm;
15 office 63  
1 office 64 private Form1()
65 {
66 _cancellationTokenSource = new CancellationTokenSource();
67 _cancellationToken = _cancellationTokenSource.Token;
68  
69 _changedConfigurationContinuation = new ScheduledContinuation();
3 office 70  
25 office 71 _squelchScheduledContinuation = new ScheduledContinuation();
72 _powerScheduledContinuation = new ScheduledContinuation();
1 office 73 }
74  
75 public Form1(Mutex mutex) : this()
76 {
77 InitializeComponent();
78  
79 _memorySink = new LogMemorySink();
80  
81 Log.Logger = new LoggerConfiguration()
82 .MinimumLevel.Debug()
83 .WriteTo.Conditional(condition => MemorySinkEnabled, configureSink => configureSink.Sink(_memorySink))
84 .WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
85 rollingInterval: RollingInterval.Day)
86 .CreateLogger();
87  
88 // Start application update.
89 var manifestModuleName = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName;
90 var icon = Icon.ExtractAssociatedIcon(manifestModuleName);
91  
92 _sparkle = new SparkleUpdater("https://hambook.grimore.org/update/appcast.xml",
93 new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY="))
94 {
95 UIFactory = new UIFactory(icon),
57 office 96 RelaunchAfterUpdate = true,
97 SecurityProtocolType = SecurityProtocolType.Tls12
1 office 98 };
57 office 99 _sparkle.StartLoop(true, true);
1 office 100 }
101  
54 office 102 private Configuration.Configuration Configuration { get; set; }
103  
104 public bool MemorySinkEnabled { get; set; }
105  
1 office 106 private async void Form1_Load(object sender, EventArgs e)
107 {
108 Configuration = await LoadConfiguration();
109  
50 office 110 _memoryBanks = MemoryBanks.Create(Configuration.Radio);
45 office 111  
7 office 112 _serialPort = InitializeSerialPort(Configuration);
1 office 113  
7 office 114 _catAssemblies = InitializeAssemblies(_serialPort);
1 office 115  
50 office 116 // Initialize power state.
1 office 117 try
118 {
9 office 119 switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
1 office 120 {
121 case PowerState.ON:
7 office 122 Log.Information(Resources.Attempting_to_initialize_radio);
54 office 123 if (!await InitializeRadio()) return;
7 office 124  
125 Log.Information(Resources.Initializing_GUI);
1 office 126 break;
127 }
128 }
54 office 129 catch (Exception exception)
1 office 130 {
131 Log.Error(exception, Resources.Failed_to_read_power_state);
132 }
26 office 133  
50 office 134 // Initialize memory banks.
41 office 135 var memoryBankQueue = new ConcurrentQueue<string>();
26 office 136 var memoryBankTaskCompletionSource = new TaskCompletionSource<bool>();
137  
138 async void IdleHandler(object idleHandlerSender, EventArgs idleHandlerArgs)
139 {
140 await memoryBankTaskCompletionSource.Task;
141  
142 try
143 {
144 if (!memoryBankQueue.TryDequeue(out var memoryBank))
145 {
54 office 146 Application.Idle -= IdleHandler;
26 office 147  
148 return;
149 }
150  
41 office 151 scrollableToolStripComboBox12.Items.Add(memoryBank);
26 office 152  
54 office 153 var memoryChannel = MemoryChannel.Create(Configuration.Radio);
26 office 154  
155 try
156 {
54 office 157 memoryChannel = await _catAssemblies.CatReadAsync<MemoryChannel>("MT",
158 new object[] { memoryBank }, _cancellationToken);
159  
41 office 160 scrollableToolStripComboBox5.Items.Add(memoryBank);
26 office 161 }
54 office 162 catch (Exception exception)
26 office 163 {
164 Log.Warning(exception, Resources.Could_not_read_memory_bank);
165  
166 return;
167 }
168  
169 _memoryChannelStore.TryAdd(memoryBank, memoryChannel);
170 }
171 catch (Exception exception)
172 {
173 Log.Error(exception, Resources.Could_not_update_data_grid_view);
174 }
175 }
176  
54 office 177 Application.Idle += IdleHandler;
26 office 178 try
179 {
54 office 180 foreach (var memoryBank in _memoryBanks.GetMemoryBanks()) memoryBankQueue.Enqueue(memoryBank);
26 office 181  
182 memoryBankTaskCompletionSource.TrySetResult(true);
183 }
184 catch (Exception exception)
185 {
54 office 186 Application.Idle -= IdleHandler;
26 office 187  
38 office 188 Log.Error(exception, Resources.Unable_to_read_memory_banks);
26 office 189 }
50 office 190  
191 // Initialize lock state.
192 try
193 {
54 office 194 var lockState =
195 await _catAssemblies.CatReadAsync<LockState>("LK", new object[] { }, _cancellationToken);
196 switch (lockState)
50 office 197 {
198 case LockState.OFF:
199 lockToolStripMenuItem.Checked = false;
200 break;
201 case LockState.ON:
202 lockToolStripMenuItem.Checked = true;
203 break;
204 }
205 }
206 catch (Exception exception)
207 {
208 Log.Error(exception, Resources.Failed_to_read_lock_state);
209 }
1 office 210 }
211  
9 office 212 private async void quitToolStripMenuItem_Click(object sender, EventArgs e)
1 office 213 {
54 office 214 if (_bandScan != null)
9 office 215 {
39 office 216 _bandScan.Stop();
9 office 217 _bandScan = null;
218 }
219  
39 office 220 if (_memoryTune != null)
221 {
222 _memoryTune.Stop();
223 _memoryTune = null;
224 }
225  
14 office 226 // Save configuration on quit.
227 await SaveConfiguration();
228  
1 office 229 Close();
230 }
231  
232 private void viewLogsToolStripMenuItem_Click(object sender, EventArgs e)
233 {
54 office 234 if (_viewLogsForm != null) return;
1 office 235  
236 _viewLogsForm = new ViewLogsForm(this, _memorySink, _cancellationToken);
237 _viewLogsForm.Closing += ViewLogsForm_Closing;
238 _viewLogsForm.Show();
239 }
240  
241 private void ViewLogsForm_Closing(object sender, CancelEventArgs e)
242 {
54 office 243 if (_viewLogsForm == null) return;
1 office 244  
245 _viewLogsForm.Closing -= ViewLogsForm_Closing;
246 _viewLogsForm.Close();
247 _viewLogsForm = null;
248 }
249  
250 private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
251 {
54 office 252 if (_aboutForm != null) return;
1 office 253  
58 office 254 _aboutForm = new AboutForm();
1 office 255 _aboutForm.Closing += AboutForm_Closing;
256 _aboutForm.Show();
257 }
258  
259 private void AboutForm_Closing(object sender, CancelEventArgs e)
260 {
54 office 261 if (_aboutForm == null) return;
1 office 262  
263 _aboutForm.Dispose();
264 _aboutForm = null;
265 }
266  
267 private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
268 {
54 office 269 if (_settingsForm != null) return;
1 office 270  
271 _settingsForm = new SettingsForm(Configuration, _cancellationToken);
272 _settingsForm.Closing += SettingsForm_Closing;
273 _settingsForm.Show();
274 }
275  
276 private void SettingsForm_Closing(object sender, CancelEventArgs e)
277 {
54 office 278 if (_settingsForm == null) return;
1 office 279  
54 office 280 if (_settingsForm.SaveOnClose)
1 office 281 // Commit the configuration.
282 _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
54 office 283 async () =>
284 {
1 office 285 await SaveConfiguration();
286  
54 office 287 if (_bandScan != null)
11 office 288 {
39 office 289 _bandScan.Stop();
11 office 290 _bandScan = null;
291 }
292  
39 office 293 if (_memoryTune != null)
294 {
295 _memoryTune.Stop();
296 _memoryTune = null;
297 }
11 office 298  
54 office 299 _memoryBanks = MemoryBanks.Create(Configuration.Radio);
45 office 300  
1 office 301 Miscellaneous.LaunchOnBootSet(Configuration.LaunchOnBoot);
302  
7 office 303 _serialPort = InitializeSerialPort(Configuration);
1 office 304  
7 office 305 _catAssemblies = InitializeAssemblies(_serialPort);
306  
307 try
308 {
58 office 309 if (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { },
310 _cancellationToken) == PowerState.ON)
7 office 311 {
58 office 312 Log.Information(Resources.Attempting_to_initialize_radio);
313 if (!await InitializeRadio()) return;
314 Log.Information(Resources.Initializing_GUI);
7 office 315 }
316 }
317 catch (Exception exception)
318 {
319 Log.Error(exception, Resources.Failed_to_read_power_state);
320 }
1 office 321 }, _cancellationToken);
322  
59 office 323 _settingsForm.Closing -= SettingsForm_Closing;
1 office 324 _settingsForm.Dispose();
325 _settingsForm = null;
326 }
327  
328 public async Task SaveConfiguration()
329 {
330 if (!Directory.Exists(Constants.UserApplicationDirectory))
331 Directory.CreateDirectory(Constants.UserApplicationDirectory);
332  
333 switch (await Serialization.Serialize(Configuration, Constants.ConfigurationFile, "Configuration",
334 "<!ATTLIST Configuration xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
335 CancellationToken.None))
336 {
3 office 337 case SerializationSuccess<Configuration.Configuration> configuration:
16 office 338 Log.Information(Resources.Configuration_serialized_successfully);
1 office 339 break;
340 case SerializationFailure serializationFailure:
16 office 341 Log.Warning(serializationFailure.Exception.Message, Resources.Configuration_failed_to_serialize);
1 office 342 break;
343 }
344 }
345  
346 public static async Task<Configuration.Configuration> LoadConfiguration()
347 {
348 if (!Directory.Exists(Constants.UserApplicationDirectory))
349 Directory.CreateDirectory(Constants.UserApplicationDirectory);
350  
351 var deserializationResult =
352 await Serialization.Deserialize<Configuration.Configuration>(Constants.ConfigurationFile,
353 Constants.ConfigurationNamespace, Constants.ConfigurationXsd, CancellationToken.None);
354  
355 switch (deserializationResult)
356 {
357 case SerializationSuccess<Configuration.Configuration> serializationSuccess:
358 return serializationSuccess.Result;
359 case SerializationFailure serializationFailure:
16 office 360 Log.Warning(serializationFailure.Exception, Resources.Configuration_failed_to_deserialize);
1 office 361 return new Configuration.Configuration();
362 default:
363 return new Configuration.Configuration();
364 }
365 }
366  
9 office 367 private async Task<bool> InitializeRadio()
1 office 368 {
369 try
370 {
54 office 371 await _catAssemblies.CatWriteAsync<InformationState>("AI", new object[] { InformationState.OFF },
372 _cancellationToken);
9 office 373  
11 office 374 return await _catAssemblies.CatReadAsync<bool>("ID", new object[] { }, _cancellationToken);
1 office 375 }
54 office 376 catch (Exception exception)
1 office 377 {
7 office 378 Log.Error(exception, Resources.Unable_to_initialize_radio);
11 office 379  
7 office 380 return false;
1 office 381 }
7 office 382 }
383  
9 office 384 private CatAssemblies InitializeAssemblies(SerialPortStream serialPort)
7 office 385 {
54 office 386 if (_catAssemblies != null)
1 office 387 {
7 office 388 _catAssemblies.Dispose();
389 _catAssemblies = null;
1 office 390 }
391  
7 office 392 return new CatAssemblies(serialPort, Configuration.Radio);
393 }
394  
9 office 395 private SerialPortStream InitializeSerialPort(Configuration.Configuration configuration)
7 office 396 {
397 if (_serialPort != null)
1 office 398 {
54 office 399 if (_serialPort.IsOpen) _serialPort.Close();
26 office 400  
7 office 401 _serialPort.Dispose();
402 _serialPort = null;
1 office 403 }
404  
7 office 405 // Set up serial connection.
54 office 406 var serialPort = new SerialPortStream(configuration.Port, configuration.Speed, configuration.DataBits,
407 configuration.Parity, configuration.StopBits);
7 office 408 serialPort.ReadTimeout = configuration.SerialPortTimeout.Read;
409 serialPort.WriteTimeout = configuration.SerialPortTimeout.Write;
410 serialPort.Handshake = configuration.Handshake;
9 office 411 serialPort.Encoding = Encoding.ASCII;
1 office 412  
54 office 413 Log.Information(
414 $"{Resources.Initialized_serial_port} {configuration.Port} {configuration.Speed} {configuration.Parity} {configuration.DataBits} {configuration.StopBits}");
7 office 415  
416 return serialPort;
1 office 417 }
418  
419 private async void updateToolStripMenuItem_Click(object sender, EventArgs e)
420 {
421 // Manually check for updates, this will not show a ui
422 var result = await _sparkle.CheckForUpdatesQuietly();
54 office 423 if (result.Status == UpdateStatus.UpdateAvailable)
1 office 424 {
425 // if update(s) are found, then we have to trigger the UI to show it gracefully
426 _sparkle.ShowUpdateNeededUI();
427 return;
428 }
429  
430 MessageBox.Show(Resources.No_updates_available_at_this_time, Resources.HamBook, MessageBoxButtons.OK,
431 MessageBoxIcon.Asterisk,
432 MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, false);
433 }
434  
435 private async void onToolStripMenuItem_Click(object sender, EventArgs e)
436 {
437 try
438 {
54 office 439 await _catAssemblies.CatSetAsync<PowerState, bool>("PS", new object[] { PowerState.ON },
440 _cancellationToken);
441 }
442 catch (Exception exception)
1 office 443 {
444 Log.Error(exception, Resources.Failed_to_set_power_state);
445 }
446 }
447  
448 private async void offToolStripMenuItem_Click(object sender, EventArgs e)
449 {
450 try
451 {
54 office 452 await _catAssemblies.CatSetAsync<PowerState, bool>("PS", new object[] { PowerState.OFF },
453 _cancellationToken);
454 }
455 catch (Exception exception)
1 office 456 {
457 Log.Error(exception, Resources.Failed_to_set_power_state);
458 }
459 }
460  
29 office 461 private async void scrollableToolStripComboBox2_MouseWheel(object sender, MouseEventArgs e)
1 office 462 {
27 office 463 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
464 if (int.TryParse(toolStripComboBox.Text, out var frequency))
1 office 465 {
27 office 466 switch (Math.Sign(e.Delta))
3 office 467 {
27 office 468 case -1:
469 frequency = frequency - Configuration.Navigation.FrequencyStep;
470 break;
471 case 1:
472 frequency = frequency + Configuration.Navigation.FrequencyStep;
473 break;
474 }
5 office 475  
27 office 476 try
3 office 477 {
54 office 478 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
479 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
27 office 480 {
56 office 481 if (!await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency },
54 office 482 _cancellationToken))
56 office 483 return;
484 toolStripComboBox.Text = $"{frequency}";
27 office 485  
56 office 486 if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
27 office 487 }
3 office 488 }
489 catch (Exception exception)
490 {
27 office 491 Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
3 office 492 }
1 office 493 }
494 }
495  
29 office 496 private async void scrollableToolStripComboBox2_KeyPress(object sender, KeyPressEventArgs e)
1 office 497 {
29 office 498 switch (e.KeyChar)
1 office 499 {
29 office 500 case (char)Keys.Enter:
501 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
27 office 502  
29 office 503 if (int.TryParse(toolStripComboBox.Text, out var frequency))
504 try
505 {
54 office 506 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
507 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
29 office 508 {
54 office 509 if (await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency },
510 _cancellationToken))
29 office 511 {
512 e.Handled = true;
27 office 513  
54 office 514 if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
29 office 515 }
516 }
517 }
518 catch (Exception exception)
519 {
520 Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
521 }
54 office 522  
29 office 523 break;
27 office 524 }
3 office 525 }
526  
39 office 527 private void toolStripMenuItem1_Click(object sender, EventArgs e)
3 office 528 {
54 office 529 if (_bandScan == null) return;
1 office 530  
39 office 531 _bandScan.Stop();
3 office 532 _bandScan = null;
1 office 533 }
3 office 534  
39 office 535 private void toolStripMenuItem38_Click(object sender, EventArgs e)
3 office 536 {
39 office 537 if (_memoryTune != null)
538 {
539 _memoryTune.Stop();
540 _memoryTune = null;
541 }
542  
543 _memoryTune = new MemoryTune(_catAssemblies, _serialPort, Configuration);
544 _memoryTune.Start();
545 }
546  
547 private void stopToolStripMenuItem_Click(object sender, EventArgs e)
548 {
54 office 549 if (_memoryTune == null) return;
39 office 550  
551 _memoryTune.Stop();
552 _memoryTune = null;
553 }
554  
555 private void scanToolStripMenuItem_Click(object sender, EventArgs e)
556 {
5 office 557 if (!(sender is ToolStripMenuItem toolStripMenuItem) ||
558 !int.TryParse(toolStripMenuItem.Tag.ToString(), out var meters))
559 return;
3 office 560  
54 office 561 if (!int.TryParse(scrollableToolStripComboBox3.Text, out var pause)) pause = 5;
3 office 562  
54 office 563 if (!int.TryParse(scrollableToolStripComboBox4.Text, out var step)) step = 5000;
3 office 564  
54 office 565 if (!int.TryParse(scrollableToolStripComboBox6.Text, out var scanDetectPause)) scanDetectPause = 10;
21 office 566  
54 office 567 if (!Configuration.Definitions.TryGetBand(meters, out var band)) return;
3 office 568  
569 if (_bandScan != null)
570 {
39 office 571 _bandScan.Stop();
9 office 572 _bandScan = null;
3 office 573 }
574  
21 office 575 _bandScan = new BandScan(_catAssemblies, (int)band.Min, (int)band.Max, _serialPort, Configuration);
9 office 576  
21 office 577 if (toolStripMenuItem14.Checked)
578 {
23 office 579 _bandScan.Start(step, pause, scanDetectPause, toolStripMenuItem16.Checked);
21 office 580  
581 return;
582 }
583  
36 office 584 _bandScan.Start(step, pause, 0, toolStripMenuItem16.Checked);
3 office 585 }
586  
36 office 587 private async void modeToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
3 office 588 {
36 office 589 try
7 office 590 {
36 office 591 var mode = await _catAssemblies.CatReadAsync<RadioMode>("MD", new object[] { }, _cancellationToken);
7 office 592  
54 office 593 contextMenuStrip1.InvokeIfRequired(contextMenuStrip => { toolStripComboBox1.Text = mode.Name; });
36 office 594 }
595 catch (Exception exception)
596 {
597 Log.Error(exception, Resources.Failed_to_read_radio_mode);
598 }
7 office 599  
36 office 600 try
601 {
602 var fa = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
603  
604 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
11 office 605 {
36 office 606 scrollableToolStripComboBox1.Text = $"{fa}";
607 });
608 }
609 catch (Exception exception)
610 {
611 Log.Error(exception, Resources.Failed_to_read_VFO_A);
612 }
11 office 613  
36 office 614 try
615 {
616 var fb = await _catAssemblies.CatReadAsync<int>("FB", new object[] { }, _cancellationToken);
617  
618 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
11 office 619 {
36 office 620 scrollableToolStripComboBox2.Text = $"{fb}";
621 });
622 }
623 catch (Exception exception)
624 {
625 Log.Error(exception, Resources.Failed_to_read_VFO_B);
626 }
11 office 627  
36 office 628 try
629 {
41 office 630 var mc = await _catAssemblies.CatReadAsync<string>("MC", new object[] { }, _cancellationToken);
19 office 631  
36 office 632 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
19 office 633 {
41 office 634 scrollableToolStripComboBox5.Text = mc;
19 office 635  
36 office 636 if (_memoryChannelStore.TryGetValue(mc, out var memoryChannel))
637 toolStripMenuItem27.Text = memoryChannel.Text;
638 });
639 }
640 catch (Exception exception)
641 {
642 Log.Error(exception, Resources.Failed_to_read_memory_channel);
643 }
26 office 644  
36 office 645 try
646 {
647 var pc = await _catAssemblies.CatReadAsync<int>("PC", new object[] { }, _cancellationToken);
24 office 648  
36 office 649 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
24 office 650 {
36 office 651 scrollableToolStripComboBox7.Text = $"{pc}";
652 });
653 }
654 catch (Exception exception)
655 {
656 Log.Error(exception, Resources.Failed_to_read_power_state);
657 }
24 office 658  
36 office 659 try
660 {
661 var sq = await _catAssemblies.CatReadAsync<int>("SQ", new object[] { }, _cancellationToken);
35 office 662  
36 office 663 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
35 office 664 {
36 office 665 scrollableToolStripComboBox11.Text = $"{sq}";
666 });
667 }
668 catch (Exception exception)
669 {
670 Log.Error(exception, Resources.Failed_to_read_squelch);
671 }
37 office 672  
673 try
674 {
675 var st = await _catAssemblies.CatReadAsync<SplitState>("ST", new object[] { }, _cancellationToken);
676  
677 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
678 {
679 scrollableToolStripComboBox8.Text = $"{(string)st}";
680 });
681 }
682 catch (Exception exception)
683 {
684 Log.Error(exception, Resources.Failed_to_read_split_state);
685 }
50 office 686  
687 try
688 {
54 office 689 var lockState =
690 await _catAssemblies.CatReadAsync<LockState>("LK", new object[] { }, _cancellationToken);
50 office 691 switch (lockState)
692 {
693 case LockState.OFF:
694 lockToolStripMenuItem.Checked = false;
695 break;
696 case LockState.ON:
697 lockToolStripMenuItem.Checked = true;
698 break;
699 }
700 }
701 catch (Exception exception)
702 {
703 Log.Error(exception, Resources.Failed_to_read_lock_state);
704 }
3 office 705 }
10 office 706  
707 private void spectrogramToolStripMenuItem_Click(object sender, EventArgs e)
708 {
54 office 709 if (_spectrogramForm != null) return;
10 office 710  
711 _spectrogramForm = new SpectrogramForm(Configuration, _cancellationToken);
712 _spectrogramForm.Closing += SpectrogramForm_Closing;
713 _spectrogramForm.Show();
714 }
715  
716 private void SpectrogramForm_Closing(object sender, CancelEventArgs e)
717 {
54 office 718 if (_spectrogramForm == null) return;
10 office 719  
720 _spectrogramForm.Dispose();
721 _spectrogramForm = null;
14 office 722  
723 // Commit the configuration.
724 _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
54 office 725 async () => { await SaveConfiguration(); }, _cancellationToken);
10 office 726 }
15 office 727  
728 private void toolStripMenuItem3_Click(object sender, EventArgs e)
729 {
54 office 730 if (_memoryOrganizerForm != null) return;
15 office 731  
732 _memoryOrganizerForm = new MemoryOrganizerForm(Configuration, _catAssemblies, _cancellationToken);
733 _memoryOrganizerForm.Closing += MemoryOrganizerForm_Closing;
734 _memoryOrganizerForm.Show();
735 }
736  
737 private void MemoryOrganizerForm_Closing(object sender, CancelEventArgs e)
738 {
54 office 739 if (_memoryOrganizerForm == null) return;
15 office 740  
741 _memoryOrganizerForm.Dispose();
742 _memoryOrganizerForm = null;
743 }
744  
745 private async void toolStripMenuItem4_Click(object sender, EventArgs e)
746 {
54 office 747 if (_tickerTaskRunning) return;
15 office 748  
54 office 749 var toolStripTextBox = toolStripTextBox6;
15 office 750  
751 try
752 {
54 office 753 var result =
754 await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { "001" }, _cancellationToken);
15 office 755  
54 office 756 _tickerTextMemoryChannel = await _catAssemblies.CatReadAsync<MemoryChannel>("MT",
757 new object[] { $"{result.CurrentLocation}" }, _cancellationToken);
15 office 758  
759 _storedMemoryChannelTagText = _tickerTextMemoryChannel.Text;
760 _storedMemoryChannelLocation = _tickerTextMemoryChannel.CurrentLocation;
761 }
54 office 762 catch (Exception exception)
15 office 763 {
764 Log.Error(exception, Resources.Could_not_read_memory_bank);
765 }
766  
767 var tickerText = $"{toolStripTextBox.Text,-12}";
768  
769 _tagTickerCancellationTokenSource = new CancellationTokenSource();
770 _tagTickerCancellationToken = _tagTickerCancellationTokenSource.Token;
771  
772 var characterQueue = new Queue<char>(12);
54 office 773 foreach (var i in Enumerable.Range(0, 12))
15 office 774 {
775 var x = tickerText.ElementAtOrDefault(i);
776  
54 office 777 if (x == default)
15 office 778 {
779 characterQueue.Enqueue(' ');
780 continue;
781 }
782  
783 characterQueue.Enqueue(x);
784 }
54 office 785  
15 office 786 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
787 _tickerTask = Task.Run(() => CycleText(characterQueue), _cancellationToken);
788 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
789 }
790  
791 private async void toolStripMenuItem5_Click(object sender, EventArgs e)
792 {
54 office 793 if (!_tickerTaskRunning) return;
15 office 794  
795 _tagTickerCancellationTokenSource.Cancel();
796 if (_tickerTask != null)
797 {
798 await _tickerTask;
799 _tickerTask = null;
800 }
801  
802 try
803 {
804 _tickerTextMemoryChannel.CurrentLocation = $"{_storedMemoryChannelLocation:000}";
54 office 805 _tickerTextMemoryChannel.Text = $"{_storedMemoryChannelTagText,-12}";
15 office 806  
54 office 807 var success = await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT",
808 new object[] { _tickerTextMemoryChannel }, _cancellationToken);
56 office 809 if (!success) Log.Error(Resources.Error_while_restoring_memory_text);
15 office 810 }
54 office 811 catch (Exception exception)
15 office 812 {
813 Log.Error(exception, Resources.Error_while_restoring_memory_text);
814 }
17 office 815 finally
816 {
817 _tickerTaskRunning = false;
818 }
15 office 819 }
820  
821 private async Task CycleText(Queue<char> characterQueue)
822 {
823 _tickerTaskRunning = true;
824 try
825 {
826 do
827 {
828 var text = string.Join("", characterQueue.OfType<char>());
829  
830 _tickerTextMemoryChannel.Text = text;
831  
54 office 832 await _catAssemblies.CatWriteAsync<MemoryChannel>("MT", new object[] { _tickerTextMemoryChannel },
833 _cancellationToken);
15 office 834  
835 var x = characterQueue.Dequeue();
836 characterQueue.Enqueue(x);
837  
838 await Task.Delay(250);
839 } while (!_tagTickerCancellationToken.IsCancellationRequested);
54 office 840 }
841 catch (Exception exception)
15 office 842 {
843 Log.Error(exception, Resources.Error_while_cycling_text);
844 }
845 }
19 office 846  
27 office 847 private async void scrollableToolStripComboBox5_SelectedIndexChanged(object sender, EventArgs e)
19 office 848 {
38 office 849 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
850  
41 office 851 var channel = toolStripComboBox.Text;
852  
853 if (!string.IsNullOrEmpty(channel))
38 office 854 if (_memoryChannelStore.TryGetValue(channel, out var memoryChannel))
855 try
27 office 856 {
54 office 857 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
858 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
27 office 859 {
54 office 860 await _catAssemblies.CatWriteAsync<string>("MC", new object[] { channel },
861 _cancellationToken);
19 office 862  
27 office 863 scrollableToolStripComboBox1.Text = $"{memoryChannel.Frequency}";
24 office 864  
27 office 865 toolStripMenuItem27.Text = memoryChannel.Text;
24 office 866  
27 office 867 soundPlayer.Play();
868 }
26 office 869 }
38 office 870 catch (Exception exception)
871 {
872 Log.Error(exception, Resources.Failed_to_set_memory_channel);
873 }
19 office 874 }
20 office 875  
35 office 876 private async void powerToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
20 office 877 {
878 var toolStripMenuItem = toolStripMenuItem11;
879  
880 try
881 {
882 switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
883 {
884 case PowerState.ON:
885 toolStripMenuItem.Text = Resources.On;
886 break;
887 case PowerState.OFF:
888 toolStripMenuItem.Text = Resources.Off;
889 break;
890 }
891 }
892 catch (Exception exception)
893 {
894 Log.Error(exception, Resources.Failed_to_read_power_state);
895 }
896 }
23 office 897  
898 private async void toolStripMenuItem17_Click(object sender, EventArgs e)
899 {
900 try
901 {
54 office 902 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
903 _cancellationToken);
23 office 904  
54 office 905 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START },
906 _cancellationToken);
23 office 907 }
908 catch (Exception exception)
909 {
910 Log.Error(exception, Resources.Failed_tuning_current_frequency);
911 }
912 }
24 office 913  
914 private async void toolStripMenuItem22_CheckStateChanged(object sender, EventArgs e)
915 {
916 var toolStripMenuItem = (ToolStripMenuItem)sender;
917 try
918 {
919 if (toolStripMenuItem.Checked)
920 {
54 office 921 await _catAssemblies.CatWriteAsync<IpoState>("PA", new object[] { IpoState.IPO },
922 _cancellationToken);
24 office 923 return;
924 }
925  
926 await _catAssemblies.CatWriteAsync<IpoState>("PA", new object[] { IpoState.AMP }, _cancellationToken);
927 }
928 catch (Exception exception)
929 {
930 Log.Error(exception, Resources.Failed_setting_IPO);
931 }
932 }
933  
934 private async void toolStripMenuItem23_CheckStateChanged(object sender, EventArgs e)
935 {
936 var toolStripMenuItem = (ToolStripMenuItem)sender;
937  
938 try
939 {
940 if (toolStripMenuItem.Checked)
941 {
54 office 942 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
943 _cancellationToken);
24 office 944  
945 return;
946 }
947  
54 office 948 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_OFF },
949 _cancellationToken);
24 office 950 }
951 catch (Exception exception)
952 {
953 Log.Error(exception, Resources.Failed_setting_the_tuner_state);
954 }
955 }
956  
957 private async void toolStripMenuItem24_Click(object sender, EventArgs e)
958 {
959 try
960 {
54 office 961 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
962 _cancellationToken);
39 office 963  
964 do
965 {
966 await Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken);
967  
968 try
969 {
54 office 970 var tuneState =
971 await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _cancellationToken);
39 office 972  
54 office 973 if (tuneState == TunerState.TUNER_ON) break;
39 office 974 }
975 catch (Exception)
976 {
977 // retry
978 }
979 } while (!_cancellationToken.IsCancellationRequested);
980  
54 office 981 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START },
982 _cancellationToken);
24 office 983 }
54 office 984 catch (Exception exception)
24 office 985 {
39 office 986 Log.Error(exception, Resources.Could_not_start_tuning);
24 office 987 }
988 }
25 office 989  
35 office 990 private void toolStripMenuItem21_DropDownOpening(object sender, EventArgs e)
25 office 991 {
992 Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken).ContinueWith(async task =>
993 {
994 try
995 {
996 var ac = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _cancellationToken);
997  
998 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
999 {
1000 switch (ac)
1001 {
1002 case TunerState.TUNING_START:
1003 case TunerState.TUNER_ON:
1004 toolStripMenuItem23.Checked = true;
1005 break;
1006 case TunerState.TUNER_OFF:
1007 toolStripMenuItem23.Checked = false;
1008 break;
1009 }
1010 });
1011 }
1012 catch (Exception exception)
1013 {
1014 Log.Error(exception, Resources.Failed_to_read_the_tuner_state);
1015 }
1016  
1017 try
1018 {
1019 var pa = await _catAssemblies.CatReadAsync<IpoState>("PA", new object[] { }, _cancellationToken);
1020  
1021 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
1022 {
1023 switch (pa)
1024 {
1025 case IpoState.AMP:
1026 toolStripMenuItem22.Checked = false;
1027 break;
1028 case IpoState.IPO:
1029 toolStripMenuItem22.Checked = true;
1030 break;
1031 }
1032 });
1033 }
1034 catch (Exception exception)
1035 {
1036 Log.Error(exception, Resources.Failed_to_read_IPO);
1037 }
1038 }, _cancellationToken);
1039 }
1040  
29 office 1041 private async void scrollableToolStripComboBox1_MouseWheel(object sender, MouseEventArgs e)
25 office 1042 {
1043 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
27 office 1044 if (int.TryParse(toolStripComboBox.Text, out var frequency))
1045 {
1046 switch (Math.Sign(e.Delta))
1047 {
1048 case -1:
1049 frequency = frequency - Configuration.Navigation.FrequencyStep;
1050 break;
1051 case 1:
1052 frequency = frequency + Configuration.Navigation.FrequencyStep;
1053 break;
1054 }
25 office 1055  
27 office 1056 try
1057 {
54 office 1058 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
1059 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
25 office 1060 {
56 office 1061 if (!await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency },
54 office 1062 _cancellationToken))
56 office 1063 return;
25 office 1064  
56 office 1065 toolStripComboBox.Text = $"{frequency}";
1066  
1067 if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
25 office 1068 }
27 office 1069 }
1070 catch (Exception exception)
1071 {
1072 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
1073 }
1074 }
1075 }
25 office 1076  
29 office 1077 private async void scrollableToolStripComboBox1_KeyPress(object sender, KeyPressEventArgs e)
27 office 1078 {
29 office 1079 switch (e.KeyChar)
27 office 1080 {
29 office 1081 case (char)Keys.Enter:
25 office 1082  
54 office 1083  
29 office 1084 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
27 office 1085  
56 office 1086 if (!int.TryParse(toolStripComboBox.Text, out var frequency)) break;
1087  
1088 try
1089 {
1090 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
1091 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
29 office 1092 {
56 office 1093 if (await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency },
1094 _cancellationToken))
29 office 1095 {
56 office 1096 e.Handled = true;
32 office 1097  
56 office 1098 if (Configuration.Navigation.MouseScrollSound) soundPlayer.Play();
29 office 1099 }
1100 }
56 office 1101 }
1102 catch (Exception exception)
1103 {
1104 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
1105 }
54 office 1106  
29 office 1107 break;
27 office 1108 }
25 office 1109 }
1110  
37 office 1111 private void scrollableToolStripComboBox11_SelectedIndexChanged(object sender, EventArgs e)
25 office 1112 {
1113 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
1114  
1115 _squelchScheduledContinuation.Schedule(TimeSpan.FromSeconds(1), () =>
1116 {
1117 contextMenuStrip1.InvokeIfRequired(async contextMenuStrip1 =>
1118 {
56 office 1119 if (!int.TryParse(toolStripComboBox.Text, out var squelch)) return;
25 office 1120  
56 office 1121 try
1122 {
1123 await _catAssemblies.CatWriteAsync<int>("SQ", new object[] { squelch }, _cancellationToken);
25 office 1124  
56 office 1125 toolStripComboBox.Text = $"{squelch}";
1126  
1127 Log.Information($"{Resources.Squelch_set} {squelch}");
1128 }
1129 catch (Exception exception)
1130 {
1131 Log.Error(exception, Resources.Failed_to_set_squelch);
1132 }
25 office 1133 });
1134 }, _cancellationToken);
1135 }
27 office 1136  
1137 private async void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
1138 {
1139 var toolStripComboBox = (ToolStripComboBox)sender;
43 office 1140  
1141 var radioMode = RadioMode.Create(Configuration.Radio, toolStripComboBox.Text);
1142  
1143 try
27 office 1144 {
43 office 1145 await _catAssemblies.CatSetAsync<RadioMode, bool>("MD", new object[] { radioMode }, _cancellationToken);
27 office 1146 }
43 office 1147 catch (Exception exception)
1148 {
1149 Log.Error(exception, Resources.Failed_to_set_radio_mode, radioMode);
1150 }
27 office 1151 }
1152  
34 office 1153 private async void scrollableToolStripComboBox7_SelectedIndexChanged(object sender, EventArgs e)
27 office 1154 {
1155 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
1156  
34 office 1157 if (int.TryParse(toolStripComboBox.Text, out var amplification))
1158 try
27 office 1159 {
54 office 1160 if (await _catAssemblies.CatSetAsync<int, bool>("PC", new object[] { amplification },
1161 _cancellationToken))
34 office 1162 {
1163 toolStripComboBox.Text = $"{amplification}";
1164  
1165 Log.Information($"{Resources.Amplification_set} {amplification}W");
1166 }
1167 }
1168 catch (Exception exception)
1169 {
1170 Log.Error(exception, Resources.Failed_to_set_amplification);
1171 }
1172 }
1173  
1174 private async void scrollableToolStripComboBox7_KeyPress(object sender, KeyPressEventArgs e)
1175 {
1176 switch (e.KeyChar)
1177 {
1178 case (char)Keys.Enter:
1179 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
1180  
27 office 1181 if (int.TryParse(toolStripComboBox.Text, out var amplification))
1182 try
1183 {
54 office 1184 if (await _catAssemblies.CatSetAsync<int, bool>("PC", new object[] { amplification },
1185 _cancellationToken))
34 office 1186 {
1187 toolStripComboBox.Text = $"{amplification}";
27 office 1188  
34 office 1189 Log.Information($"{Resources.Amplification_set} {amplification}W");
1190  
1191 e.Handled = true;
1192 }
27 office 1193 }
1194 catch (Exception exception)
1195 {
1196 Log.Error(exception, Resources.Failed_to_set_amplification);
1197 }
54 office 1198  
34 office 1199 break;
1200 }
27 office 1201 }
1202  
39 office 1203 private void toolStripMenuItem30_Click(object sender, EventArgs e)
33 office 1204 {
1205 if (!int.TryParse(scrollableToolStripComboBox9.Text, out var start)
1206 || !int.TryParse(scrollableToolStripComboBox10.Text, out var stop))
1207 return;
29 office 1208  
54 office 1209 if (!int.TryParse(scrollableToolStripComboBox3.Text, out var pause)) pause = 5;
33 office 1210  
54 office 1211 if (!int.TryParse(scrollableToolStripComboBox4.Text, out var step)) step = 5000;
33 office 1212  
54 office 1213 if (!int.TryParse(scrollableToolStripComboBox6.Text, out var scanDetectPause)) scanDetectPause = 10;
33 office 1214  
1215 if (_bandScan != null)
1216 {
39 office 1217 _bandScan.Stop();
33 office 1218 _bandScan = null;
1219 }
1220  
1221 _bandScan = new BandScan(_catAssemblies, start, stop, _serialPort, Configuration);
1222  
1223 if (toolStripMenuItem14.Checked)
1224 {
1225 _bandScan.Start(step, pause, scanDetectPause, toolStripMenuItem16.Checked);
1226  
1227 return;
1228 }
1229  
36 office 1230 _bandScan.Start(step, pause, 0, toolStripMenuItem16.Checked);
33 office 1231 }
35 office 1232  
1233 private async void toolStripMenuItem32_Click(object sender, EventArgs e)
1234 {
1235 var toolStripMenuItem = toolStripMenuItem31;
1236  
1237 try
1238 {
54 office 1239 if (await _catAssemblies.CatSetAsync<TxState, bool>("TX", new object[] { TxState.ON },
1240 _cancellationToken))
35 office 1241 toolStripMenuItem.Text = Resources.On;
1242 }
1243 catch (Exception exception)
1244 {
1245 Log.Error(exception, Resources.Failed_to_set_PTT_state);
1246 }
1247 }
1248  
1249 private async void toolStripMenuItem33_Click(object sender, EventArgs e)
1250 {
1251 var toolStripMenuItem = toolStripMenuItem31;
1252  
1253 try
1254 {
54 office 1255 if (await _catAssemblies.CatSetAsync<TxState, bool>("TX", new object[] { TxState.OFF },
1256 _cancellationToken))
35 office 1257 toolStripMenuItem.Text = Resources.Off;
1258 }
1259 catch (Exception exception)
1260 {
1261 Log.Error(exception, Resources.Failed_to_set_PTT_state);
1262 }
1263 }
1264  
1265 private async void toolStripMenuItem26_DropDownOpening(object sender, EventArgs e)
1266 {
1267 var toolStripMenuItem = toolStripMenuItem31;
1268  
1269 try
1270 {
1271 switch (await _catAssemblies.CatReadAsync<TxState>("TX", new object[] { }, _cancellationToken))
1272 {
1273 case TxState.ON:
1274 toolStripMenuItem.Text = Resources.On;
1275 break;
1276 case TxState.OFF:
1277 toolStripMenuItem.Text = Resources.Off;
1278 break;
1279 }
1280 }
1281 catch (Exception exception)
1282 {
1283 Log.Error(exception, Resources.Failed_to_read_PTT_state);
1284 }
1285 }
37 office 1286  
1287 private async void scrollableToolStripComboBox8_SelectedIndexChanged(object sender, EventArgs e)
1288 {
1289 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
1290  
56 office 1291 if (!SplitState.TryParse(toolStripComboBox.Text, out var splitState)) return;
1292  
1293 try
1294 {
1295 if (await _catAssemblies.CatSetAsync<int, bool>("ST", new object[] { splitState },
1296 _cancellationToken)) Log.Information($"{Resources.Split_state_set} {splitState}W");
1297 }
1298 catch (Exception exception)
1299 {
1300 Log.Error(exception, Resources.Failed_to_set_split_state);
1301 }
37 office 1302 }
38 office 1303  
1304 private async void toolStripMenuItem35_Click(object sender, EventArgs e)
1305 {
1306 var scrollableToolStripComboBox = scrollableToolStripComboBox12;
1307  
41 office 1308 var channel = scrollableToolStripComboBox.Text;
1309 if (!string.IsNullOrEmpty(channel))
38 office 1310 {
1311 if (!_memoryChannelStore.TryGetValue(channel, out var memoryChannel))
1312 {
46 office 1313 memoryChannel = MemoryChannel.Create(Configuration.Radio);
41 office 1314 memoryChannel.CurrentLocation = channel;
54 office 1315 memoryChannel.MemoryRadioMode =
1316 MemoryRadioMode.Create(Configuration.Radio, toolStripComboBox1.Text);
38 office 1317 }
1318  
1319 if (memoryChannel.Tag = !string.IsNullOrEmpty(toolStripTextBox1.Text))
54 office 1320 memoryChannel.Text = $"{toolStripTextBox1.Text,-12}";
38 office 1321  
1322 if (int.TryParse(scrollableToolStripComboBox1.Text, out var frequency))
1323 {
1324 memoryChannel.Frequency = frequency;
1325  
1326 try
1327 {
54 office 1328 if (await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT", new object[] { memoryChannel },
1329 _cancellationToken)) Log.Information(Resources.Stored_VFO_A_to_memory);
38 office 1330 }
1331 catch (Exception exception)
1332 {
1333 Log.Error(exception, Resources.Failed_to_save_VFO_A_to_memory);
1334 }
1335 }
1336 }
1337 }
1338  
1339 private void scrollableToolStripComboBox12_SelectedIndexChanged(object sender, EventArgs e)
1340 {
1341 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
1342  
41 office 1343 var channel = toolStripComboBox.Text;
1344 if (!string.IsNullOrEmpty(channel))
38 office 1345 {
1346 if (_memoryChannelStore.TryGetValue(channel, out var memoryChannel))
1347 {
1348 toolStripTextBox1.Text = memoryChannel.Text;
1349 return;
1350 }
1351  
1352 toolStripTextBox1.Text = string.Empty;
1353 }
1354 }
1355  
1356 private async void toolStripMenuItem20_Click(object sender, EventArgs e)
1357 {
1358 try
1359 {
1360 var frequency = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
1361  
1362 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { frequency }, _cancellationToken);
1363  
1364 await _catAssemblies.CatWriteAsync("SV", new object[] { }, _cancellationToken);
1365 }
1366 catch (Exception exception)
1367 {
1368 Log.Error(exception, Resources.Unable_to_swap_VFO_A_and_VFO_B);
1369 }
1370 }
50 office 1371  
1372 private async void lockToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
1373 {
1374 var toolStripMenuItem = (ToolStripMenuItem)sender;
1375 try
1376 {
1377 LockState state;
1378 switch (toolStripMenuItem.Checked)
1379 {
1380 case true:
1381 state = LockState.ON;
1382 break;
1383 default:
1384 state = LockState.OFF;
1385 break;
1386 }
1387  
54 office 1388 if (!await _catAssemblies.CatSetAsync<LockState, bool>("LK", new object[] { state },
1389 _cancellationToken)) Log.Error(Resources.Failed_to_set_lock_state);
50 office 1390 }
1391 catch (Exception exception)
1392 {
1393 Log.Error(exception, Resources.Failed_to_read_lock_state);
1394 }
1395 }
54 office 1396  
1397 private void menuToolStripMenuItem_Click(object sender, EventArgs e)
1398 {
1399 if (_menuForm != null) return;
1400  
1401 _menuForm = new MenuForm(Configuration, _catAssemblies, _cancellationToken);
1402 _menuForm.Closing += MenuForm_Closing;
1403 _menuForm.Show();
1404 }
1405  
1406 private void MenuForm_Closing(object sender, CancelEventArgs e)
1407 {
1408 if (_menuForm == null) return;
1409  
1410 _menuForm.Dispose();
1411 _menuForm = null;
1412 }
1 office 1413 }
54 office 1414 }