HamBook – Blame information for rev 25

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