HamBook – Blame information for rev 45

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