HamBook – Blame information for rev 24

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;
1 office 31  
32 namespace HamBook
33 {
34 public partial class Form1 : Form
35 {
36 private ScheduledContinuation _changedConfigurationContinuation;
37 private Configuration.Configuration Configuration { get; set; }
9 office 38 private SerialPortStream _serialPort;
1 office 39 private LogMemorySink _memorySink;
40 private ViewLogsForm _viewLogsForm;
41 private AboutForm _aboutForm;
42 private SettingsForm _settingsForm;
43 private SparkleUpdater _sparkle;
44 private readonly CancellationToken _cancellationToken;
45 private readonly CancellationTokenSource _cancellationTokenSource;
46 private CatAssemblies _catAssemblies;
3 office 47 private BandScan _bandScan;
10 office 48 private SpectrogramForm _spectrogramForm;
15 office 49 private MemoryOrganizerForm _memoryOrganizerForm;
1 office 50  
15 office 51 private CancellationTokenSource _tagTickerCancellationTokenSource;
52 private CancellationToken _tagTickerCancellationToken;
53 private string _storedMemoryChannelTagText;
54 private string _storedMemoryChannelLocation;
55 private MemoryChannel _tickerTextMemoryChannel;
56 private Task _tickerTask;
57 private volatile bool _tickerTaskRunning;
58  
1 office 59 public bool MemorySinkEnabled { get; set; }
60  
61 private Form1()
62 {
63 _cancellationTokenSource = new CancellationTokenSource();
64 _cancellationToken = _cancellationTokenSource.Token;
65  
66 _changedConfigurationContinuation = new ScheduledContinuation();
3 office 67  
1 office 68 }
69  
70 public Form1(Mutex mutex) : this()
71 {
72 InitializeComponent();
73  
74 _memorySink = new LogMemorySink();
75  
76 Log.Logger = new LoggerConfiguration()
77 .MinimumLevel.Debug()
78 .WriteTo.Conditional(condition => MemorySinkEnabled, configureSink => configureSink.Sink(_memorySink))
79 .WriteTo.File(Path.Combine(Constants.UserApplicationDirectory, "Logs", $"{Constants.AssemblyName}.log"),
80 rollingInterval: RollingInterval.Day)
81 .CreateLogger();
82  
83 // Start application update.
84 var manifestModuleName = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName;
85 var icon = Icon.ExtractAssociatedIcon(manifestModuleName);
86  
87 _sparkle = new SparkleUpdater("https://hambook.grimore.org/update/appcast.xml",
88 new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY="))
89 {
90 UIFactory = new UIFactory(icon),
91 RelaunchAfterUpdate = true
92 };
93 }
94  
95 private async void Form1_Load(object sender, EventArgs e)
96 {
13 office 97 _sparkle.StartLoop(true, true);
98  
1 office 99 Configuration = await LoadConfiguration();
100  
7 office 101 _serialPort = InitializeSerialPort(Configuration);
1 office 102  
7 office 103 _catAssemblies = InitializeAssemblies(_serialPort);
1 office 104  
105 try
106 {
9 office 107 switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
1 office 108 {
109 case PowerState.ON:
7 office 110 Log.Information(Resources.Attempting_to_initialize_radio);
9 office 111 if(!await InitializeRadio())
7 office 112 {
113 return;
114 }
115  
116 Log.Information(Resources.Initializing_GUI);
1 office 117 break;
118 }
119 }
120 catch(Exception exception)
121 {
122 Log.Error(exception, Resources.Failed_to_read_power_state);
123 }
124 }
125  
9 office 126 private async void quitToolStripMenuItem_Click(object sender, EventArgs e)
1 office 127 {
9 office 128 if(_bandScan != null)
129 {
130 await _bandScan.Stop();
131 _bandScan = null;
132 }
133  
14 office 134 // Save configuration on quit.
135 await SaveConfiguration();
136  
1 office 137 Close();
138 }
139  
140 private void viewLogsToolStripMenuItem_Click(object sender, EventArgs e)
141 {
142 if (_viewLogsForm != null)
143 {
144 return;
145 }
146  
147 _viewLogsForm = new ViewLogsForm(this, _memorySink, _cancellationToken);
148 _viewLogsForm.Closing += ViewLogsForm_Closing;
149 _viewLogsForm.Show();
150 }
151  
152 private void ViewLogsForm_Closing(object sender, CancelEventArgs e)
153 {
154 if (_viewLogsForm == null)
155 {
156 return;
157 }
158  
159 _viewLogsForm.Closing -= ViewLogsForm_Closing;
160 _viewLogsForm.Close();
161 _viewLogsForm = null;
162 }
163  
164 private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
165 {
166 if (_aboutForm != null)
167 {
168 return;
169 }
170  
171 _aboutForm = new AboutForm(_cancellationToken);
172 _aboutForm.Closing += AboutForm_Closing;
173 _aboutForm.Show();
174 }
175  
176 private void AboutForm_Closing(object sender, CancelEventArgs e)
177 {
178 if (_aboutForm == null)
179 {
180 return;
181 }
182  
183 _aboutForm.Dispose();
184 _aboutForm = null;
185 }
186  
187 private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
188 {
189 if (_settingsForm != null)
190 {
191 return;
192 }
193  
194 _settingsForm = new SettingsForm(Configuration, _cancellationToken);
195 _settingsForm.Closing += SettingsForm_Closing;
196 _settingsForm.Show();
197 }
198  
199 private void SettingsForm_Closing(object sender, CancelEventArgs e)
200 {
201 if (_settingsForm == null)
202 {
203 return;
204 }
205  
206 if(_settingsForm.SaveOnClose)
207 {
208 // Commit the configuration.
209 _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
210 async () => {
211 await SaveConfiguration();
212  
11 office 213 if(_bandScan != null)
214 {
215 await _bandScan.Stop();
216 _bandScan = null;
217 }
218  
219  
1 office 220 Miscellaneous.LaunchOnBootSet(Configuration.LaunchOnBoot);
221  
7 office 222 _serialPort = InitializeSerialPort(Configuration);
1 office 223  
7 office 224 _catAssemblies = InitializeAssemblies(_serialPort);
225  
226 try
227 {
9 office 228 switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
7 office 229 {
230 case PowerState.ON:
231 Log.Information(Resources.Attempting_to_initialize_radio);
9 office 232 if (!await InitializeRadio())
7 office 233 {
234 return;
235 }
236 Log.Information(Resources.Initializing_GUI);
237 break;
238 }
239 }
240 catch (Exception exception)
241 {
242 Log.Error(exception, Resources.Failed_to_read_power_state);
243 }
244  
1 office 245 }, _cancellationToken);
246 }
247  
248 _settingsForm.Dispose();
249 _settingsForm = null;
250 }
251  
252 public async Task SaveConfiguration()
253 {
254 if (!Directory.Exists(Constants.UserApplicationDirectory))
255 {
256 Directory.CreateDirectory(Constants.UserApplicationDirectory);
257 }
258  
259 switch (await Serialization.Serialize(Configuration, Constants.ConfigurationFile, "Configuration",
260 "<!ATTLIST Configuration xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
261 CancellationToken.None))
262 {
3 office 263 case SerializationSuccess<Configuration.Configuration> configuration:
16 office 264 Log.Information(Resources.Configuration_serialized_successfully);
1 office 265 break;
266 case SerializationFailure serializationFailure:
16 office 267 Log.Warning(serializationFailure.Exception.Message, Resources.Configuration_failed_to_serialize);
1 office 268 break;
269 }
270 }
271  
272 public static async Task<Configuration.Configuration> LoadConfiguration()
273 {
274 if (!Directory.Exists(Constants.UserApplicationDirectory))
275 {
276 Directory.CreateDirectory(Constants.UserApplicationDirectory);
277 }
278  
279 var deserializationResult =
280 await Serialization.Deserialize<Configuration.Configuration>(Constants.ConfigurationFile,
281 Constants.ConfigurationNamespace, Constants.ConfigurationXsd, CancellationToken.None);
282  
283 switch (deserializationResult)
284 {
285 case SerializationSuccess<Configuration.Configuration> serializationSuccess:
286 return serializationSuccess.Result;
287 case SerializationFailure serializationFailure:
16 office 288 Log.Warning(serializationFailure.Exception, Resources.Configuration_failed_to_deserialize);
1 office 289 return new Configuration.Configuration();
290 default:
291 return new Configuration.Configuration();
292 }
293 }
294  
9 office 295 private async Task<bool> InitializeRadio()
1 office 296 {
297 try
298 {
9 office 299 await _catAssemblies.CatWriteAsync<InformationState>("AI", new object[] { InformationState.OFF }, _cancellationToken);
300  
11 office 301 return await _catAssemblies.CatReadAsync<bool>("ID", new object[] { }, _cancellationToken);
1 office 302 }
303 catch(Exception exception)
304 {
7 office 305 Log.Error(exception, Resources.Unable_to_initialize_radio);
11 office 306  
7 office 307 return false;
1 office 308 }
7 office 309 }
310  
9 office 311 private CatAssemblies InitializeAssemblies(SerialPortStream serialPort)
7 office 312 {
313 if(_catAssemblies != null)
1 office 314 {
7 office 315 _catAssemblies.Dispose();
316 _catAssemblies = null;
1 office 317 }
318  
7 office 319 return new CatAssemblies(serialPort, Configuration.Radio);
320 }
321  
9 office 322 private SerialPortStream InitializeSerialPort(Configuration.Configuration configuration)
7 office 323 {
324 if (_serialPort != null)
1 office 325 {
7 office 326 if (_serialPort.IsOpen)
327 {
328 _serialPort.Close();
329 }
330 _serialPort.Dispose();
331 _serialPort = null;
1 office 332 }
333  
7 office 334 // Set up serial connection.
9 office 335 var serialPort = new SerialPortStream(configuration.Port, configuration.Speed, configuration.DataBits, configuration.Parity, configuration.StopBits);
7 office 336 serialPort.ReadTimeout = configuration.SerialPortTimeout.Read;
337 serialPort.WriteTimeout = configuration.SerialPortTimeout.Write;
338 serialPort.Handshake = configuration.Handshake;
9 office 339 serialPort.Encoding = Encoding.ASCII;
1 office 340  
7 office 341 Log.Information($"{Resources.Initialized_serial_port} {configuration.Port} {configuration.Speed} {configuration.Parity} {configuration.DataBits} {configuration.StopBits}");
342  
343 return serialPort;
1 office 344 }
345  
346 private async void updateToolStripMenuItem_Click(object sender, EventArgs e)
347 {
348 // Manually check for updates, this will not show a ui
349 var result = await _sparkle.CheckForUpdatesQuietly();
350 if (result.Status == NetSparkleUpdater.Enums.UpdateStatus.UpdateAvailable)
351 {
352 // if update(s) are found, then we have to trigger the UI to show it gracefully
353 _sparkle.ShowUpdateNeededUI();
354 return;
355 }
356  
357 MessageBox.Show(Resources.No_updates_available_at_this_time, Resources.HamBook, MessageBoxButtons.OK,
358 MessageBoxIcon.Asterisk,
359 MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly, false);
360 }
361  
9 office 362 private async void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
1 office 363 {
364 var toolStripComboBox = (ToolStripComboBox)sender;
3 office 365 if(RadioMode.TryParse(toolStripComboBox.Text, out var radioMode))
1 office 366 {
3 office 367 try
1 office 368 {
15 office 369 await _catAssemblies.CatSetAsync<RadioMode, bool>("MD", new object[] { radioMode }, _cancellationToken);
1 office 370 }
3 office 371 catch (Exception exception)
372 {
373 Log.Error(exception, Resources.Failed_to_set_radio_mode, radioMode);
374 }
1 office 375 }
376 }
377  
378 private async void onToolStripMenuItem_Click(object sender, EventArgs e)
379 {
380 try
381 {
15 office 382 await _catAssemblies.CatSetAsync<PowerState, bool>("PS", new object[] { PowerState.ON }, _cancellationToken);
1 office 383 }
384 catch(Exception exception)
385 {
386 Log.Error(exception, Resources.Failed_to_set_power_state);
387 }
388 }
389  
390 private async void offToolStripMenuItem_Click(object sender, EventArgs e)
391 {
392 try
393 {
15 office 394 await _catAssemblies.CatSetAsync<PowerState, bool>("PS", new object[] { PowerState.OFF }, _cancellationToken);
1 office 395 }
396 catch(Exception exception)
397 {
398 Log.Error(exception, Resources.Failed_to_set_power_state);
399 }
400 }
401  
9 office 402 private async void toolStripComboBox2_MouseWheel(object sender, MouseEventArgs e)
1 office 403 {
5 office 404 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
1 office 405 {
7 office 406 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
5 office 407 if (int.TryParse(toolStripComboBox.Text, out var frequency))
3 office 408 {
5 office 409 switch (Math.Sign(e.Delta))
410 {
411 case -1:
21 office 412 frequency = frequency - Configuration.Navigation.FrequencyStep;
5 office 413 break;
414 case 1:
21 office 415 frequency = frequency + Configuration.Navigation.FrequencyStep;
5 office 416 break;
417 }
418  
24 office 419 if (frequency < 0)
420 {
421 frequency = 0;
422 }
423  
5 office 424 soundPlayer.Play();
425  
426 try
427 {
15 office 428 await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency }, _cancellationToken);
5 office 429 toolStripComboBox.Text = $"{frequency}";
7 office 430  
431 Log.Information($"{Resources.Set_VFO_A_frequency} {frequency}Hz");
5 office 432 }
433 catch (Exception exception)
434 {
435 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
436 }
3 office 437 }
1 office 438 }
439 }
440  
9 office 441 private async void scrollableToolStripComboBox1_MouseWheel(object sender, MouseEventArgs e)
1 office 442 {
5 office 443 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
1 office 444 {
7 office 445 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
5 office 446 if (int.TryParse(toolStripComboBox.Text, out var frequency))
3 office 447 {
5 office 448 switch (Math.Sign(e.Delta))
449 {
450 case -1:
21 office 451 frequency = frequency - Configuration.Navigation.FrequencyStep;
5 office 452 break;
453 case 1:
21 office 454 frequency = frequency + Configuration.Navigation.FrequencyStep;
5 office 455 break;
456 }
3 office 457  
24 office 458 if (frequency < 0)
459 {
460 frequency = 0;
461 }
462  
6 office 463 soundPlayer.Play();
464  
5 office 465 try
466 {
15 office 467 await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency }, _cancellationToken);
5 office 468 toolStripComboBox.Text = $"{frequency}";
7 office 469  
470 Log.Information($"{Resources.Set_VFO_B_frequency} {frequency}Hz");
5 office 471 }
472 catch (Exception exception)
473 {
474 Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
475 }
1 office 476 }
477 }
478 }
479  
9 office 480 private async void scrollableToolStripComboBox1_TextChanged(object sender, EventArgs e)
1 office 481 {
3 office 482 var toolStripComboBox = (ToolStripComboBox)sender;
483 if (int.TryParse(toolStripComboBox.Text, out var frequency))
1 office 484 {
3 office 485 try
486 {
15 office 487 await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency }, _cancellationToken);
3 office 488 }
489 catch (Exception exception)
490 {
491 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
492 }
1 office 493 }
494 }
495  
9 office 496 private async void scrollableToolStripComboBox2_TextChanged(object sender, EventArgs e)
1 office 497 {
3 office 498 var toolStripComboBox = (ToolStripComboBox)sender;
499 if (int.TryParse(toolStripComboBox.Text, out var frequency))
1 office 500 {
501 try
502 {
15 office 503 await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency }, _cancellationToken);
1 office 504 }
505 catch (Exception exception)
506 {
507 Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
508 }
3 office 509 }
510 }
511  
9 office 512 private async void toolStripMenuItem1_Click(object sender, EventArgs e)
3 office 513 {
514 if (_bandScan == null)
515 {
1 office 516 return;
517 }
518  
9 office 519 await _bandScan.Stop();
3 office 520 _bandScan = null;
1 office 521 }
3 office 522  
9 office 523 private async void scanToolStripMenuItem_Click(object sender, EventArgs e)
3 office 524 {
5 office 525 if (!(sender is ToolStripMenuItem toolStripMenuItem) ||
526 !int.TryParse(toolStripMenuItem.Tag.ToString(), out var meters))
3 office 527 {
5 office 528 return;
3 office 529 }
530  
5 office 531 if (!int.TryParse(scrollableToolStripComboBox3.Text, out var pause))
3 office 532 {
5 office 533 pause = 5;
3 office 534 }
535  
5 office 536 if(!int.TryParse(scrollableToolStripComboBox4.Text, out var step))
3 office 537 {
5 office 538 step = 5000;
3 office 539 }
540  
21 office 541 if(!int.TryParse(scrollableToolStripComboBox6.Text, out var scanDetectPause))
542 {
543 scanDetectPause = 10;
544 }
545  
5 office 546 if (!Configuration.Definitions.TryGetBand(meters, out var band))
3 office 547 {
5 office 548 return;
3 office 549 }
550  
551 if (_bandScan != null)
552 {
9 office 553 await _bandScan.Stop();
554 _bandScan = null;
3 office 555 }
556  
21 office 557 _bandScan = new BandScan(_catAssemblies, (int)band.Min, (int)band.Max, _serialPort, Configuration);
9 office 558  
23 office 559 //toolStripMenuItem16
21 office 560 if (toolStripMenuItem14.Checked)
561 {
23 office 562 _bandScan.Start(step, pause, scanDetectPause, toolStripMenuItem16.Checked);
21 office 563  
564 return;
565 }
566  
23 office 567 _bandScan.Start(step, pause, toolStripMenuItem16.Checked);
3 office 568 }
569  
11 office 570 private void modeToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
3 office 571 {
11 office 572 Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken).ContinueWith(async task =>
7 office 573 {
11 office 574 try
575 {
576 var mode = await _catAssemblies.CatReadAsync<RadioMode>("MD", new object[] { }, _cancellationToken);
7 office 577  
11 office 578 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
579 {
580 toolStripComboBox1.Text = mode;
581 });
582 }
583 catch (Exception exception)
584 {
585 Log.Error(exception, Resources.Failed_to_read_radio_mode);
586 }
7 office 587  
11 office 588 try
589 {
590 var fa = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
7 office 591  
11 office 592 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
593 {
594 scrollableToolStripComboBox1.Text = $"{fa}";
595  
596 });
597  
598 }
599 catch (Exception exception)
600 {
601 Log.Error(exception, Resources.Failed_to_read_VFO_A);
602 }
603  
604 try
605 {
606 var fb = await _catAssemblies.CatReadAsync<int>("FB", new object[] { }, _cancellationToken);
607  
608 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
609 {
610 scrollableToolStripComboBox2.Text = $"{fb}";
611  
612 });
613 }
614 catch (Exception exception)
615 {
616 Log.Error(exception, Resources.Failed_to_read_VFO_B);
617 }
19 office 618  
619 try
620 {
621 var mc = await _catAssemblies.CatReadAsync<int>("MC", new object[] { }, _cancellationToken);
622  
623 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
624 {
625 scrollableToolStripComboBox5.Text = $"{mc}";
626  
627 });
628 }
629 catch (Exception exception)
630 {
631 Log.Error(exception, Resources.Failed_to_read_memory_channel);
632 }
24 office 633  
634 try
635 {
636 var pc = await _catAssemblies.CatReadAsync<int>("PC", new object[] { }, _cancellationToken);
637  
638 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
639 {
640 scrollableToolStripComboBox7.Text = $"{pc}";
641  
642 });
643 }
644 catch (Exception exception)
645 {
646 Log.Error(exception, Resources.Failed_to_read_memory_channel);
647 }
11 office 648 }, _cancellationToken);
3 office 649 }
10 office 650  
651 private void spectrogramToolStripMenuItem_Click(object sender, EventArgs e)
652 {
653 if (_spectrogramForm != null)
654 {
655 return;
656 }
657  
658 _spectrogramForm = new SpectrogramForm(Configuration, _cancellationToken);
659 _spectrogramForm.Closing += SpectrogramForm_Closing;
660 _spectrogramForm.Show();
661 }
662  
663 private void SpectrogramForm_Closing(object sender, CancelEventArgs e)
664 {
665 if (_spectrogramForm == null)
666 {
667 return;
668 }
669  
670 _spectrogramForm.Dispose();
671 _spectrogramForm = null;
14 office 672  
673 // Commit the configuration.
674 _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
675 async () =>
676 {
677 await SaveConfiguration();
678 }, _cancellationToken);
10 office 679 }
15 office 680  
681 private void toolStripMenuItem3_Click(object sender, EventArgs e)
682 {
683 if (_memoryOrganizerForm != null)
684 {
685 return;
686 }
687  
688 _memoryOrganizerForm = new MemoryOrganizerForm(Configuration, _catAssemblies, _cancellationToken);
689 _memoryOrganizerForm.Closing += MemoryOrganizerForm_Closing;
690 _memoryOrganizerForm.Show();
691 }
692  
693 private void MemoryOrganizerForm_Closing(object sender, CancelEventArgs e)
694 {
695 if (_memoryOrganizerForm == null)
696 {
697 return;
698 }
699  
700 _memoryOrganizerForm.Dispose();
701 _memoryOrganizerForm = null;
702  
703 }
704  
705 private async void toolStripMenuItem4_Click(object sender, EventArgs e)
706 {
707 if (_tickerTaskRunning)
708 {
709 return;
710 }
711  
712 var toolStripTextBox = (ToolStripTextBox)toolStripTextBox6;
713  
714 try
715 {
716 var result = await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { "001" }, _cancellationToken);
717  
718 _tickerTextMemoryChannel = await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { $"{result.CurrentLocation}" }, _cancellationToken);
719  
720 _storedMemoryChannelTagText = _tickerTextMemoryChannel.Text;
721 _storedMemoryChannelLocation = _tickerTextMemoryChannel.CurrentLocation;
722 }
723 catch(Exception exception)
724 {
725 Log.Error(exception, Resources.Could_not_read_memory_bank);
726 }
727  
728 var tickerText = $"{toolStripTextBox.Text,-12}";
729  
730 _tagTickerCancellationTokenSource = new CancellationTokenSource();
731 _tagTickerCancellationToken = _tagTickerCancellationTokenSource.Token;
732  
733 var characterQueue = new Queue<char>(12);
734 foreach(var i in Enumerable.Range(0, 12))
735 {
736 var x = tickerText.ElementAtOrDefault(i);
737  
738 if(x == default)
739 {
740 characterQueue.Enqueue(' ');
741 continue;
742 }
743  
744 characterQueue.Enqueue(x);
745 }
746  
747 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
748 _tickerTask = Task.Run(() => CycleText(characterQueue), _cancellationToken);
749 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
750 }
751  
752 private async void toolStripMenuItem5_Click(object sender, EventArgs e)
753 {
754 if(!_tickerTaskRunning)
755 {
756 return;
757 }
758  
759 _tagTickerCancellationTokenSource.Cancel();
760 if (_tickerTask != null)
761 {
762 await _tickerTask;
763 _tickerTask = null;
764 }
765  
766 try
767 {
768 _tickerTextMemoryChannel.CurrentLocation = $"{_storedMemoryChannelLocation:000}";
17 office 769 _tickerTextMemoryChannel.Text = $"{_storedMemoryChannelTagText, -12}";
15 office 770  
771 var success = await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT", new object[] { _tickerTextMemoryChannel }, _cancellationToken);
772 if (!success)
773 {
774 Log.Error(Resources.Error_while_restoring_memory_text);
775  
776 return;
777 }
778 }
779 catch(Exception exception)
780 {
781 Log.Error(exception, Resources.Error_while_restoring_memory_text);
782 }
17 office 783 finally
784 {
785 _tickerTaskRunning = false;
786 }
15 office 787 }
788  
789 private async Task CycleText(Queue<char> characterQueue)
790 {
791 _tickerTaskRunning = true;
792 try
793 {
794 do
795 {
796 var text = string.Join("", characterQueue.OfType<char>());
797  
798 _tickerTextMemoryChannel.Text = text;
799  
800 await _catAssemblies.CatWriteAsync<MemoryChannel>("MT", new object[] { _tickerTextMemoryChannel }, _cancellationToken);
801  
802 var x = characterQueue.Dequeue();
803 characterQueue.Enqueue(x);
804  
805 await Task.Delay(250);
806  
807 } while (!_tagTickerCancellationToken.IsCancellationRequested);
808 }
809 catch(Exception exception)
810 {
811 Log.Error(exception, Resources.Error_while_cycling_text);
812 }
813 }
19 office 814  
815 private async void scrollableToolStripComboBox5_MouseWheel(object sender, MouseEventArgs e)
816 {
817 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
818 {
819 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
820 if (int.TryParse(toolStripComboBox.Text, out var memoryChannel))
821 {
822 switch (Math.Sign(e.Delta))
823 {
824 case -1:
825 memoryChannel = memoryChannel - 1;
826 break;
827 case 1:
828 memoryChannel = memoryChannel + 1;
829 break;
830 }
831  
24 office 832  
833 if (memoryChannel < 0)
834 {
835 memoryChannel = 0;
836 }
837  
19 office 838 soundPlayer.Play();
839  
840 try
841 {
24 office 842 await _catAssemblies.CatWriteAsync<int>("MC", new object[] { memoryChannel }, _cancellationToken);
843  
19 office 844 toolStripComboBox.Text = $"{memoryChannel}";
845  
846 Log.Information($"{Resources.Set_VFO_A_frequency} {memoryChannel}");
847 }
848 catch (Exception exception)
849 {
850 Log.Error(exception, Resources.Failed_to_set_memory_channel);
851 }
852 }
853 }
854 }
855  
856 private async void scrollableToolStripComboBox5_TextChanged(object sender, EventArgs e)
857 {
858 var toolStripComboBox = (ToolStripComboBox)sender;
859 if (int.TryParse(toolStripComboBox.Text, out var memoryChannel))
860 {
861 try
862 {
24 office 863 await _catAssemblies.CatWriteAsync<int>("MC", new object[] { memoryChannel }, _cancellationToken);
19 office 864 }
865 catch (Exception exception)
866 {
867 Log.Error(exception, Resources.Failed_to_set_memory_channel);
868 }
869 }
870 }
20 office 871  
872 private async void powerToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
873 {
874 var toolStripMenuItem = toolStripMenuItem11;
875  
876 try
877 {
878 switch (await _catAssemblies.CatReadAsync<PowerState>("PS", new object[] { }, _cancellationToken))
879 {
880 case PowerState.ON:
881 toolStripMenuItem.Text = Resources.On;
882 break;
883 case PowerState.OFF:
884 toolStripMenuItem.Text = Resources.Off;
885 break;
886 }
887 }
888 catch (Exception exception)
889 {
890 Log.Error(exception, Resources.Failed_to_read_power_state);
891 }
892 }
23 office 893  
894 private async void toolStripMenuItem17_Click(object sender, EventArgs e)
895 {
896 try
897 {
898 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _cancellationToken);
899  
900 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _cancellationToken);
901 }
902 catch (Exception exception)
903 {
904 Log.Error(exception, Resources.Failed_tuning_current_frequency);
905 }
906 }
24 office 907  
908 private async void scrollableToolStripComboBox7_MouseWheel(object sender, MouseEventArgs e)
909 {
910 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
911 if (int.TryParse(toolStripComboBox.Text, out var amplification))
912 {
913 switch (Math.Sign(e.Delta))
914 {
915 case -1:
916 amplification = amplification - 1;
917 break;
918 case 1:
919 amplification = amplification + 1;
920 break;
921 }
922  
923 if (amplification < 0)
924 {
925 amplification = 0;
926 }
927  
928 try
929 {
930 await _catAssemblies.CatWriteAsync<int>("PC", new object[] { amplification }, _cancellationToken);
931  
932 toolStripComboBox.Text = $"{amplification}";
933  
934 Log.Information($"{Resources.Amplification_set} {amplification}W");
935 }
936 catch (Exception exception)
937 {
938 Log.Error(exception, Resources.Failed_to_set_amplification);
939 }
940 }
941 }
942  
943 private async void scrollableToolStripComboBox7_TextChanged(object sender, EventArgs e)
944 {
945 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
946 if (int.TryParse(toolStripComboBox.Text, out var amplification))
947 {
948  
949 try
950 {
951 await _catAssemblies.CatWriteAsync<int>("PC", new object[] { amplification }, _cancellationToken);
952  
953 toolStripComboBox.Text = $"{amplification}";
954  
955 Log.Information($"{Resources.Amplification_set} {amplification}W");
956 }
957 catch (Exception exception)
958 {
959 Log.Error(exception, Resources.Failed_to_set_amplification);
960 }
961 }
962 }
963  
964 private async void scrollableToolStripComboBox8_MouseWheel(object sender, MouseEventArgs e)
965 {
966 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
967 if (int.TryParse(toolStripComboBox.Text, out var squelch))
968 {
969 var value = _catAssemblies.CatGetDefault<int>("SQ", new object[] { });
970  
971 switch (Math.Sign(e.Delta))
972 {
973 case -1:
974 squelch = squelch - value;
975 break;
976 case 1:
977 squelch = squelch + value;
978 break;
979 }
980  
981 if(squelch < 0)
982 {
983 squelch = 0;
984 }
985  
986 try
987 {
988 await _catAssemblies.CatWriteAsync<int>("SQ", new object[] { squelch }, _cancellationToken);
989  
990 toolStripComboBox.Text = $"{squelch}";
991  
992 Log.Information($"{Resources.Squelch_set} {squelch}");
993 }
994 catch (Exception exception)
995 {
996 Log.Error(exception, Resources.Failed_to_set_squelch);
997 }
998 }
999 }
1000  
1001 private async void scrollableToolStripComboBox8_TextChanged(object sender, EventArgs e)
1002 {
1003 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
1004 if (int.TryParse(toolStripComboBox.Text, out var squelch))
1005 {
1006  
1007 try
1008 {
1009 await _catAssemblies.CatWriteAsync<int>("SQ", new object[] { squelch }, _cancellationToken);
1010  
1011 toolStripComboBox.Text = $"{squelch}";
1012  
1013 Log.Information($"{Resources.Squelch_set} {squelch}");
1014 }
1015 catch (Exception exception)
1016 {
1017 Log.Error(exception, Resources.Failed_to_set_squelch);
1018 }
1019 }
1020 }
1021  
1022 private async void toolStripMenuItem22_CheckStateChanged(object sender, EventArgs e)
1023 {
1024 var toolStripMenuItem = (ToolStripMenuItem)sender;
1025 try
1026 {
1027 if (toolStripMenuItem.Checked)
1028 {
1029 await _catAssemblies.CatWriteAsync<IpoState>("PA", new object[] { IpoState.IPO }, _cancellationToken);
1030 return;
1031 }
1032  
1033 await _catAssemblies.CatWriteAsync<IpoState>("PA", new object[] { IpoState.AMP }, _cancellationToken);
1034 }
1035 catch (Exception exception)
1036 {
1037 Log.Error(exception, Resources.Failed_setting_IPO);
1038 }
1039 }
1040  
1041 private async void toolStripMenuItem23_CheckStateChanged(object sender, EventArgs e)
1042 {
1043 var toolStripMenuItem = (ToolStripMenuItem)sender;
1044  
1045 try
1046 {
1047 if (toolStripMenuItem.Checked)
1048 {
1049 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _cancellationToken);
1050  
1051 return;
1052 }
1053  
1054 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_OFF }, _cancellationToken);
1055 }
1056 catch (Exception exception)
1057 {
1058 Log.Error(exception, Resources.Failed_setting_the_tuner_state);
1059 }
1060 }
1061  
1062 private async void toolStripMenuItem24_Click(object sender, EventArgs e)
1063 {
1064 try
1065 {
1066 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _cancellationToken);
1067 }
1068 catch(Exception exception)
1069 {
1070  
1071 }
1072 }
1 office 1073 }
1074 }