HamBook – Blame information for rev 17

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:
412 frequency = frequency - 100;
413 break;
414 case 1:
415 frequency = frequency + 100;
416 break;
417 }
418  
419 soundPlayer.Play();
420  
421 try
422 {
15 office 423 await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency }, _cancellationToken);
5 office 424 toolStripComboBox.Text = $"{frequency}";
7 office 425  
426 Log.Information($"{Resources.Set_VFO_A_frequency} {frequency}Hz");
5 office 427 }
428 catch (Exception exception)
429 {
430 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
431 }
3 office 432 }
1 office 433 }
434 }
435  
9 office 436 private async void scrollableToolStripComboBox1_MouseWheel(object sender, MouseEventArgs e)
1 office 437 {
5 office 438 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
1 office 439 {
7 office 440 var toolStripComboBox = (ScrollableToolStripComboBox)sender;
5 office 441 if (int.TryParse(toolStripComboBox.Text, out var frequency))
3 office 442 {
5 office 443 switch (Math.Sign(e.Delta))
444 {
445 case -1:
446 frequency = frequency - 100;
447 break;
448 case 1:
449 frequency = frequency + 100;
450 break;
451 }
3 office 452  
6 office 453 soundPlayer.Play();
454  
5 office 455 try
456 {
15 office 457 await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency }, _cancellationToken);
5 office 458 toolStripComboBox.Text = $"{frequency}";
7 office 459  
460 Log.Information($"{Resources.Set_VFO_B_frequency} {frequency}Hz");
5 office 461 }
462 catch (Exception exception)
463 {
464 Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
465 }
1 office 466 }
467 }
468 }
469  
9 office 470 private async void scrollableToolStripComboBox1_TextChanged(object sender, EventArgs e)
1 office 471 {
3 office 472 var toolStripComboBox = (ToolStripComboBox)sender;
473 if (int.TryParse(toolStripComboBox.Text, out var frequency))
1 office 474 {
3 office 475 try
476 {
15 office 477 await _catAssemblies.CatSetAsync<int, bool>("FA", new object[] { frequency }, _cancellationToken);
3 office 478 }
479 catch (Exception exception)
480 {
481 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
482 }
1 office 483 }
484 }
485  
9 office 486 private async void scrollableToolStripComboBox2_TextChanged(object sender, EventArgs e)
1 office 487 {
3 office 488 var toolStripComboBox = (ToolStripComboBox)sender;
489 if (int.TryParse(toolStripComboBox.Text, out var frequency))
1 office 490 {
491 try
492 {
15 office 493 await _catAssemblies.CatSetAsync<int, bool>("FB", new object[] { frequency }, _cancellationToken);
1 office 494 }
495 catch (Exception exception)
496 {
497 Log.Error(exception, Resources.Failed_to_set_VFO_B_frequency);
498 }
3 office 499 }
500 }
501  
9 office 502 private async void toolStripMenuItem1_Click(object sender, EventArgs e)
3 office 503 {
504 if (_bandScan == null)
505 {
1 office 506 return;
507 }
508  
9 office 509 await _bandScan.Stop();
3 office 510 _bandScan = null;
1 office 511 }
3 office 512  
9 office 513 private async void scanToolStripMenuItem_Click(object sender, EventArgs e)
3 office 514 {
5 office 515 if (!(sender is ToolStripMenuItem toolStripMenuItem) ||
516 !int.TryParse(toolStripMenuItem.Tag.ToString(), out var meters))
3 office 517 {
5 office 518 return;
3 office 519 }
520  
5 office 521 if (!int.TryParse(scrollableToolStripComboBox3.Text, out var pause))
3 office 522 {
5 office 523 pause = 5;
3 office 524 }
525  
5 office 526 if(!int.TryParse(scrollableToolStripComboBox4.Text, out var step))
3 office 527 {
5 office 528 step = 5000;
3 office 529 }
530  
5 office 531 if (!Configuration.Definitions.TryGetBand(meters, out var band))
3 office 532 {
5 office 533 return;
3 office 534 }
535  
536 if (_bandScan != null)
537 {
9 office 538 await _bandScan.Stop();
539 _bandScan = null;
3 office 540 }
541  
12 office 542 _bandScan = new BandScan(_catAssemblies, band.Min, band.Max, _serialPort, Configuration);
9 office 543  
544 _bandScan.Start(step, pause, Configuration.ScanDetectPause);
3 office 545 }
546  
11 office 547 private void modeToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
3 office 548 {
11 office 549 Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken).ContinueWith(async task =>
7 office 550 {
11 office 551 try
552 {
553 var mode = await _catAssemblies.CatReadAsync<RadioMode>("MD", new object[] { }, _cancellationToken);
7 office 554  
11 office 555 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
556 {
557 toolStripComboBox1.Text = mode;
558 });
559 }
560 catch (Exception exception)
561 {
562 Log.Error(exception, Resources.Failed_to_read_radio_mode);
563 }
7 office 564  
11 office 565 try
566 {
567 var fa = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
7 office 568  
11 office 569 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
570 {
571 scrollableToolStripComboBox1.Text = $"{fa}";
572  
573 });
574  
575 }
576 catch (Exception exception)
577 {
578 Log.Error(exception, Resources.Failed_to_read_VFO_A);
579 }
580  
581 try
582 {
583 var fb = await _catAssemblies.CatReadAsync<int>("FB", new object[] { }, _cancellationToken);
584  
585 contextMenuStrip1.InvokeIfRequired(contextMenuStrip =>
586 {
587 scrollableToolStripComboBox2.Text = $"{fb}";
588  
589 });
590 }
591 catch (Exception exception)
592 {
593 Log.Error(exception, Resources.Failed_to_read_VFO_B);
594 }
595 }, _cancellationToken);
3 office 596 }
10 office 597  
598 private void spectrogramToolStripMenuItem_Click(object sender, EventArgs e)
599 {
600 if (_spectrogramForm != null)
601 {
602 return;
603 }
604  
605 _spectrogramForm = new SpectrogramForm(Configuration, _cancellationToken);
606 _spectrogramForm.Closing += SpectrogramForm_Closing;
607 _spectrogramForm.Show();
608 }
609  
610 private void SpectrogramForm_Closing(object sender, CancelEventArgs e)
611 {
612 if (_spectrogramForm == null)
613 {
614 return;
615 }
616  
617 _spectrogramForm.Dispose();
618 _spectrogramForm = null;
14 office 619  
620 // Commit the configuration.
621 _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1),
622 async () =>
623 {
624 await SaveConfiguration();
625 }, _cancellationToken);
10 office 626 }
15 office 627  
628 private void toolStripMenuItem3_Click(object sender, EventArgs e)
629 {
630 if (_memoryOrganizerForm != null)
631 {
632 return;
633 }
634  
635 _memoryOrganizerForm = new MemoryOrganizerForm(Configuration, _catAssemblies, _cancellationToken);
636 _memoryOrganizerForm.Closing += MemoryOrganizerForm_Closing;
637 _memoryOrganizerForm.Show();
638 }
639  
640 private void MemoryOrganizerForm_Closing(object sender, CancelEventArgs e)
641 {
642 if (_memoryOrganizerForm == null)
643 {
644 return;
645 }
646  
647 _memoryOrganizerForm.Dispose();
648 _memoryOrganizerForm = null;
649  
650 }
651  
652 private async void toolStripMenuItem4_Click(object sender, EventArgs e)
653 {
654 if (_tickerTaskRunning)
655 {
656 return;
657 }
658  
659 var toolStripTextBox = (ToolStripTextBox)toolStripTextBox6;
660  
661 try
662 {
663 var result = await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { "001" }, _cancellationToken);
664  
665 _tickerTextMemoryChannel = await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { $"{result.CurrentLocation}" }, _cancellationToken);
666  
667 _storedMemoryChannelTagText = _tickerTextMemoryChannel.Text;
668 _storedMemoryChannelLocation = _tickerTextMemoryChannel.CurrentLocation;
669 }
670 catch(Exception exception)
671 {
672 Log.Error(exception, Resources.Could_not_read_memory_bank);
673 }
674  
675 var tickerText = $"{toolStripTextBox.Text,-12}";
676  
677 _tagTickerCancellationTokenSource = new CancellationTokenSource();
678 _tagTickerCancellationToken = _tagTickerCancellationTokenSource.Token;
679  
680 var characterQueue = new Queue<char>(12);
681 foreach(var i in Enumerable.Range(0, 12))
682 {
683 var x = tickerText.ElementAtOrDefault(i);
684  
685 if(x == default)
686 {
687 characterQueue.Enqueue(' ');
688 continue;
689 }
690  
691 characterQueue.Enqueue(x);
692 }
693  
694 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
695 _tickerTask = Task.Run(() => CycleText(characterQueue), _cancellationToken);
696 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
697 }
698  
699 private async void toolStripMenuItem5_Click(object sender, EventArgs e)
700 {
701 if(!_tickerTaskRunning)
702 {
703 return;
704 }
705  
706 _tagTickerCancellationTokenSource.Cancel();
707 if (_tickerTask != null)
708 {
709 await _tickerTask;
710 _tickerTask = null;
711 }
712  
713 try
714 {
715 _tickerTextMemoryChannel.CurrentLocation = $"{_storedMemoryChannelLocation:000}";
17 office 716 _tickerTextMemoryChannel.Text = $"{_storedMemoryChannelTagText, -12}";
15 office 717  
718 var success = await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT", new object[] { _tickerTextMemoryChannel }, _cancellationToken);
719 if (!success)
720 {
721 Log.Error(Resources.Error_while_restoring_memory_text);
722  
723 return;
724 }
725 }
726 catch(Exception exception)
727 {
728 Log.Error(exception, Resources.Error_while_restoring_memory_text);
729 }
17 office 730 finally
731 {
732 _tickerTaskRunning = false;
733 }
15 office 734 }
735  
736 private async Task CycleText(Queue<char> characterQueue)
737 {
738 _tickerTaskRunning = true;
739 try
740 {
741 do
742 {
743 var text = string.Join("", characterQueue.OfType<char>());
744  
745 _tickerTextMemoryChannel.Text = text;
746  
747 await _catAssemblies.CatWriteAsync<MemoryChannel>("MT", new object[] { _tickerTextMemoryChannel }, _cancellationToken);
748  
749 var x = characterQueue.Dequeue();
750 characterQueue.Enqueue(x);
751  
752 await Task.Delay(250);
753  
754 } while (!_tagTickerCancellationToken.IsCancellationRequested);
755 }
756 catch(Exception exception)
757 {
758 Log.Error(exception, Resources.Error_while_cycling_text);
759 }
760 }
1 office 761 }
762 }