HamBook – Blame information for rev 46

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