HamBook – Blame information for rev 56

Subversion Repositories:
Rev:
Rev Author Line No. Line
54 office 1 using System;
15 office 2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.ComponentModel;
53 office 5 using System.Drawing;
15 office 6 using System.Linq;
51 office 7 using System.Media;
8 using System.Reflection;
49 office 9 using System.Threading;
15 office 10 using System.Threading.Tasks;
11 using System.Windows.Forms;
54 office 12 using HamBook.Properties;
13 using HamBook.Radios;
14 using HamBook.Radios.Generic;
15 using HamBook.Utilities.Serialization;
16 using Serilog;
15 office 17  
18 namespace HamBook
19 {
20 public partial class MemoryOrganizerForm : Form
21 {
54 office 22 private readonly CancellationTokenSource _cancellationTokenSource;
15 office 23  
54 office 24 private readonly CatAssemblies _catAssemblies;
25 private readonly CancellationToken _localCancellationToken;
26 private readonly CancellationTokenSource _localCancellationTokenSource;
27 private readonly MemoryBanks _memoryBanks;
56 office 28 private readonly MemoryRadioMode _memoryRadioMode;
15 office 29 private CancellationToken _cancellationToken;
52 office 30 private List<DataGridViewRow> _clipboardRows;
56 office 31 private CancellationTokenSource _readCancellationTokenSource;
32 private CancellationTokenSource _readLinkedCancellationTokenSource;
33 private Task _readMemoryBanksTask;
54 office 34 private CancellationTokenSource _writeCancellationTokenSource;
35 private CancellationTokenSource _writeLinkedCancellationTokenSource;
36 private Task _writeMemoryBanksTask;
15 office 37  
38 public MemoryOrganizerForm()
39 {
40 InitializeComponent();
53 office 41 Utilities.WindowState.FormTracker.Track(this);
22 office 42  
43 _localCancellationTokenSource = new CancellationTokenSource();
44 _localCancellationToken = _localCancellationTokenSource.Token;
15 office 45 }
46  
54 office 47 public MemoryOrganizerForm(Configuration.Configuration configuration, CatAssemblies catAssemblies,
48 CancellationToken cancellationToken) : this()
15 office 49 {
50 Configuration = configuration;
51 _catAssemblies = catAssemblies;
22 office 52  
54 office 53 _cancellationTokenSource =
54 CancellationTokenSource.CreateLinkedTokenSource(_localCancellationToken, cancellationToken);
22 office 55 _cancellationToken = _cancellationTokenSource.Token;
41 office 56  
54 office 57 _memoryBanks = MemoryBanks.Create(Configuration.Radio);
56 office 58 _memoryRadioMode = MemoryRadioMode.Create(Configuration.Radio);
15 office 59 }
60  
54 office 61 private Configuration.Configuration Configuration { get; }
62  
15 office 63 /// <summary>
54 office 64 /// Clean up any resources being used.
15 office 65 /// </summary>
66 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
67 protected override void Dispose(bool disposing)
68 {
54 office 69 if (disposing && components != null)
15 office 70 {
54 office 71 if (_cancellationTokenSource != null) _cancellationTokenSource.Cancel();
22 office 72  
15 office 73 components.Dispose();
74 }
54 office 75  
15 office 76 base.Dispose(disposing);
77 }
78  
79 private async void button1_Click(object sender, EventArgs e)
80 {
41 office 81 var rows = dataGridView1.Rows.OfType<DataGridViewRow>().OrderBy(row => row.Index).ToList();
22 office 82 var count = rows.Count;
83  
84 toolStripProgressBar1.Minimum = 0;
85 toolStripProgressBar1.Maximum = count;
54 office 86 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
22 office 87  
88 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
89 {
90 try
91 {
92 switch (rowProgress)
93 {
94 case DataGridViewRowProgressSuccess<MemoryChannel> rowProgressSuccess:
54 office 95 dataGridView1.Rows[rowProgressSuccess.Row.Index].DefaultCellStyle.BackColor =
96 DefaultBackColor;
22 office 97  
53 office 98 switch (Configuration.Radio)
47 office 99 {
100 case "Yaesu FT-891":
101 var result = (Radios.Yaesu.FT_891.MemoryChannel)rowProgressSuccess.Data;
22 office 102  
47 office 103 rowProgress.Row.Cells["FrequencyColumn"].Value = result.Frequency;
54 office 104 rowProgress.Row.Cells["ClarifierDirectionColumn"].Value =
105 (char)result.ClarifierDirection;
47 office 106 rowProgress.Row.Cells["ClarifierOffsetColumn"].Value = result.ClarifierOffset;
107 rowProgress.Row.Cells["ClarColumn"].Value = result.Clar;
108 rowProgress.Row.Cells["ModeColumn"].Value = result.MemoryRadioMode.Name;
109 rowProgress.Row.Cells["CtcssColumn"].Value = (string)result.Ctcss;
110 rowProgress.Row.Cells["PhaseColumn"].Value = (string)result.Phase;
111 rowProgress.Row.Cells["TagColumn"].Value = result.Tag;
112 rowProgress.Row.Cells["TextColumn"].Value = result.Text;
113 rowProgress.Row.Tag = rowProgressSuccess.Data;
114 break;
115 }
41 office 116  
117 toolStripStatusLabel1.Text = $"{Resources.Read_memory_bank} {rowProgress.Index + 1}";
22 office 118 break;
54 office 119 case DataGridViewRowProgressFailure<int> rowProgressFailure:
22 office 120 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_read_memory_bank}");
53 office 121 dataGridView1.Rows[rowProgressFailure.Row.Index].DefaultCellStyle.BackColor = Color.Red;
22 office 122  
54 office 123 toolStripStatusLabel1.Text =
124 $"{Resources.Could_not_read_memory_bank} {rowProgress.Index + 1}";
22 office 125 break;
126 }
127  
128 toolStripProgressBar1.Increment(1);
129 statusStrip1.Update();
130 }
41 office 131 catch (Exception exception)
22 office 132 {
41 office 133 Log.Error(exception, Resources.Unexpected_error_while_reading_memory_bank);
22 office 134 }
135 });
136  
137 await Task.Run(() => ReadMemoryBanks(rows, progress, _cancellationToken), _cancellationToken);
138  
139 if (!_cancellationToken.IsCancellationRequested)
140 {
141 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
142 toolStripStatusLabel1.Text = "Done.";
143 }
15 office 144 }
145  
146 private async void button2_Click(object sender, EventArgs e)
147 {
41 office 148 var rows = dataGridView1.Rows.OfType<DataGridViewRow>().OrderBy(row => row.Index).ToList();
22 office 149 var count = rows.Count;
150  
151 toolStripProgressBar1.Minimum = 0;
152 toolStripProgressBar1.Maximum = count;
54 office 153 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
22 office 154  
155 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
156 {
157 try
158 {
159 switch (rowProgress)
160 {
161 case DataGridViewRowProgressSuccess<bool> rowProgressSuccess:
54 office 162 dataGridView1.Rows[rowProgressSuccess.Row.Index].DefaultCellStyle.BackColor =
163 DefaultBackColor;
22 office 164 var success = rowProgressSuccess.Data;
54 office 165  
41 office 166 if (success)
22 office 167 {
168 toolStripStatusLabel1.Text =
54 office 169 $"{Resources.Wrote_memory_bank} {rowProgress.Index + 1}";
22 office 170 toolStripProgressBar1.Increment(1);
171 statusStrip1.Update();
172 return;
173 }
174  
41 office 175 Log.Error($"{Resources.Could_not_write_memory_bank}");
22 office 176 break;
54 office 177 case DataGridViewRowProgressFailure<int> rowProgressFailure:
53 office 178 dataGridView1.Rows[rowProgressFailure.Row.Index].DefaultCellStyle.BackColor = Color.Red;
22 office 179 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_write_memory_bank}");
180 break;
181 }
182  
41 office 183 toolStripStatusLabel1.Text =
184 $"{Resources.Could_not_write_memory_bank} {rowProgress.Index + 1}";
185 toolStripProgressBar1.Increment(1);
186 statusStrip1.Update();
22 office 187 }
41 office 188 catch (Exception exception)
189 {
190 Log.Error(exception, Resources.Unexpected_error_while_writing_memory_bank);
191 }
22 office 192 });
193  
194 await Task.Run(() => WriteMemoryBanks(rows, progress, _cancellationToken), _cancellationToken);
195  
196 if (!_cancellationToken.IsCancellationRequested)
197 {
198 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
199 toolStripStatusLabel1.Text = "Done.";
200 }
15 office 201 }
202  
203 private void MemoryOrganizerForm_Load(object sender, EventArgs e)
204 {
47 office 205 // Generate columns based on radio type.
54 office 206 switch (Configuration.Radio)
47 office 207 {
208 case "Yaesu FT-891":
54 office 209 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
210 { Name = "LocationColumn", HeaderText = "Location", ReadOnly = true });
211 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
212 { Name = "FrequencyColumn", HeaderText = "Frequency" });
213 var clarifierDropDownColumn = new DataGridViewComboBoxColumn
214 { Name = "ClarifierDirectionColumn", HeaderText = "Clarifier" };
47 office 215 clarifierDropDownColumn.Items.AddRange(
216 "+",
217 "-"
218 );
219 dataGridView1.Columns.Add(clarifierDropDownColumn);
54 office 220 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
221 { Name = "ClarifierOffsetColumn", HeaderText = "Offset" });
222 dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn
223 { Name = "ClarColumn", HeaderText = "Clar" });
224 var modeComboBoxColumn = new DataGridViewComboBoxColumn
225 { Name = "ModeColumn", HeaderText = "Mode" };
56 office 226 foreach (var name in _memoryRadioMode.Names)
51 office 227 modeComboBoxColumn.Items.Add(
228 name
229 );
54 office 230  
47 office 231 dataGridView1.Columns.Add(modeComboBoxColumn);
54 office 232 var ctcssComboBoxColumn = new DataGridViewComboBoxColumn
233 { Name = "CtcssColumn", HeaderText = "CTCSS" };
47 office 234 ctcssComboBoxColumn.Items.AddRange(
235 "Off",
236 "Enc/Dec",
237 "Enc"
238 );
239 dataGridView1.Columns.Add(ctcssComboBoxColumn);
54 office 240 var phaseComboBoxColumn = new DataGridViewComboBoxColumn
241 { Name = "PhaseColumn", HeaderText = "Phase" };
47 office 242 phaseComboBoxColumn.Items.AddRange(
243 "Simplex",
244 "Plus Shift",
245 "Minus Shift"
246 );
247 dataGridView1.Columns.Add(phaseComboBoxColumn);
54 office 248 dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn
249 { Name = "TagColumn", HeaderText = "Tag" });
250 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
251 {
252 Name = "TextColumn", HeaderText = "Text",
253 MaxInputLength = Radios.Yaesu.FT_891.Constants.MaxTagCharacters
254 });
47 office 255 break;
256 }
257  
15 office 258 toolStripProgressBar1.Minimum = 0;
259 toolStripProgressBar1.Maximum = 98;
54 office 260 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
15 office 261  
41 office 262 var memoryBankQueue = new ConcurrentQueue<string>();
263 var memoryBankAddRowsTaskCompletionSource = new TaskCompletionSource<object>();
15 office 264  
265 async void IdleHandler(object idleHandlerSender, EventArgs idleHandlerArgs)
266 {
41 office 267 await memoryBankAddRowsTaskCompletionSource.Task;
15 office 268  
269 try
270 {
271 if (!memoryBankQueue.TryDequeue(out var memoryBank))
272 {
273 Application.Idle -= IdleHandler;
274  
275 dataGridView1.Sort(dataGridView1.Columns["LocationColumn"], ListSortDirection.Ascending);
276 toolStripStatusLabel1.Text = "Done.";
277  
278 return;
279 }
280  
281 var index = dataGridView1.Rows.Add();
282  
54 office 283 switch (Configuration.Radio)
47 office 284 {
285 case "Yaesu FT-891":
286 dataGridView1.Rows[index].Cells["LocationColumn"].Value = memoryBank;
287 dataGridView1.Rows[index].Cells["FrequencyColumn"].Value = default;
56 office 288 dataGridView1.Rows[index].Cells["ClarifierDirectionColumn"].Value = "+";
289 dataGridView1.Rows[index].Cells["ClarifierOffsetColumn"].Value = 0;
47 office 290 dataGridView1.Rows[index].Cells["ClarColumn"].Value = default;
291 dataGridView1.Rows[index].Cells["ModeColumn"].Value = default;
56 office 292 dataGridView1.Rows[index].Cells["CtcssColumn"].Value = "Off";
293 dataGridView1.Rows[index].Cells["PhaseColumn"].Value = "Simplex";
47 office 294 dataGridView1.Rows[index].Cells["TagColumn"].Value = default;
295 dataGridView1.Rows[index].Cells["TextColumn"].Value = default;
296 break;
297 }
15 office 298  
47 office 299 toolStripStatusLabel1.Text = $"{Resources.Created_memory_bank} {memoryBank}";
15 office 300 toolStripProgressBar1.Increment(1);
301 statusStrip1.Update();
302 }
303 catch (Exception exception)
304 {
305 Log.Error(exception, Resources.Could_not_update_data_grid_view);
306 }
307 }
308  
309 Application.Idle += IdleHandler;
310 try
311 {
54 office 312 foreach (var memoryBank in _memoryBanks.GetMemoryBanks()) memoryBankQueue.Enqueue(memoryBank);
15 office 313  
41 office 314 memoryBankAddRowsTaskCompletionSource.TrySetResult(new { });
15 office 315 }
316 catch (Exception exception)
317 {
318 Application.Idle -= IdleHandler;
319  
320 Log.Error(exception, Resources.Unable_to_create_memory_banks);
321 }
322 }
323  
324 private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
325 {
326 var dataGridView = (DataGridView)sender;
327  
328 if (dataGridView.CurrentCell is DataGridViewCheckBoxCell)
329 dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
330 }
331  
332 private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
333 {
334 var dataGridView = (DataGridView)sender;
335  
336 dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
337 }
338  
339 private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
340 {
341 }
342  
343 private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
344 {
345 var dataGridView = (DataGridView)sender;
346  
54 office 347 if (e.RowIndex == -1 || e.ColumnIndex == -1) return;
15 office 348  
349 switch (dataGridView.Columns[e.ColumnIndex].Name)
350 {
351 case "EnableColumn":
352 //ProcessEnable(dataGridView.Rows[e.RowIndex]);
353 break;
354 }
355 }
356  
357 private void DataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
358 {
359 var dataGridView = (DataGridView)sender;
360  
361 if (e.RowIndex == -1 || e.ColumnIndex == -1 ||
362 !(dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn))
363 return;
364  
365 dataGridView.EndEdit();
366 }
367  
368 private void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
369 {
370 var dataGridView = (DataGridView)sender;
371  
372 if (e.RowIndex == -1 || e.ColumnIndex == -1 ||
373 !(dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn))
374 return;
375  
376 dataGridView.EndEdit();
377 }
378  
379 private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
380 {
381 // @(-.-)@ -(o.o)- @(o_o)@
382 }
383  
51 office 384 private static IEnumerable<DataGridViewRow> GetSelectedDataGridViewRows(DataGridView dataGridView)
15 office 385 {
51 office 386 return dataGridView.SelectedRows.OfType<DataGridViewRow>().OrderBy(row => row.Index);
15 office 387 }
388  
54 office 389 private async Task ReadMemoryBanks(IReadOnlyList<DataGridViewRow> rows,
390 IProgress<DataGridViewRowProgress> progress,
391 CancellationToken cancellationToken)
15 office 392 {
393 var count = rows.Count;
394  
395 for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i)
396 try
397 {
41 office 398 var location = $"{rows[i].Cells["LocationColumn"].Value}";
15 office 399  
54 office 400 var result =
401 await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { location },
402 cancellationToken);
15 office 403  
404 progress.Report(new DataGridViewRowProgressSuccess<MemoryChannel>(rows[i], i, result));
405 }
406 catch (UnexpectedRadioResponseException exception)
407 {
54 office 408 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception));
15 office 409 }
410 catch (Exception exception)
411 {
54 office 412 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception));
15 office 413 }
414 }
415  
54 office 416 private async Task WriteMemoryBanks(IReadOnlyList<DataGridViewRow> rows,
417 IProgress<DataGridViewRowProgress> progress,
418 CancellationToken cancellationToken)
15 office 419 {
420 var count = rows.Count;
421  
422 for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i)
423 try
424 {
47 office 425 var success = false;
15 office 426  
54 office 427 switch (Configuration.Radio)
47 office 428 {
429 case "Yaesu FT-891":
54 office 430 var memoryChannel =
431 (Radios.Yaesu.FT_891.MemoryChannel)MemoryChannel.Create(Configuration.Radio);
15 office 432  
47 office 433 memoryChannel.CurrentLocation = $"{rows[i].Cells["LocationColumn"].Value}";
434 memoryChannel.Frequency = int.Parse($"{rows[i].Cells["FrequencyColumn"].Value}");
54 office 435 memoryChannel.ClarifierDirection =
436 char.Parse($"{rows[i].Cells["ClarifierDirectionColumn"].Value}");
437 memoryChannel.ClarifierOffset =
438 int.Parse($"{rows[i].Cells["ClarifierOffsetColumn"].Value}");
47 office 439 memoryChannel.Clar = Convert.ToBoolean(rows[i].Cells["ClarColumn"].Value);
56 office 440 memoryChannel.MemoryRadioMode = MemoryRadioMode.Create(Configuration.Radio,
54 office 441 $"{rows[i].Cells["ModeColumn"].Value}");
47 office 442 memoryChannel.Ctcss = new Ctcss($"{rows[i].Cells["CtcssColumn"].Value}");
443 memoryChannel.Phase = new Phase($"{rows[i].Cells["PhaseColumn"].Value}");
444 memoryChannel.Tag = Convert.ToBoolean(rows[i].Cells["TagColumn"].Value);
445 memoryChannel.Text = $"{rows[i].Cells["TextColumn"].Value,-12}";
15 office 446  
54 office 447 success = await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT",
448 new object[] { memoryChannel }, cancellationToken);
47 office 449 break;
450 }
451  
452 progress.Report(new DataGridViewRowProgressSuccess<bool>(rows[i], i, success));
15 office 453 }
454 catch (UnexpectedRadioResponseException exception)
455 {
54 office 456 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception));
15 office 457 }
458 catch (Exception exception)
459 {
54 office 460 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception));
15 office 461 }
462 }
16 office 463  
464 private void importToolStripMenuItem_Click(object sender, EventArgs e)
465 {
466 openFileDialog1.ShowDialog();
467 }
468  
469 private void exportToolStripMenuItem_Click(object sender, EventArgs e)
470 {
471 saveFileDialog1.ShowDialog();
472 }
473  
474 private async void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
475 {
56 office 476 if (e.Cancel)
477 {
478 return;
479 }
16 office 480  
26 office 481 var list = new List<MemoryChannelIndexed>();
54 office 482 foreach (var row in dataGridView1.Rows.OfType<DataGridViewRow>().OrderBy(row => row.Index))
48 office 483 if (row.Tag is MemoryChannel memoryChannel)
16 office 484 {
26 office 485 var memoryChannelOrganizerBanks = new MemoryChannelIndexed(row.Index, memoryChannel);
16 office 486 list.Add(memoryChannelOrganizerBanks);
487 }
488  
489 var memoryBanks = list.ToArray();
490  
56 office 491 var fileName = saveFileDialog1.FileName;
16 office 492 switch (await Serialization.Serialize(memoryBanks, fileName, "MemoryChannelOrganizerBank",
493 "<!ATTLIST MemoryChannelOrganizerBank xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
494 CancellationToken.None))
495 {
26 office 496 case SerializationSuccess<MemoryChannelIndexed[]> configuration:
16 office 497 Log.Information(Resources.Serialized_memory_banks);
498 break;
499 case SerializationFailure serializationFailure:
500 Log.Warning(serializationFailure.Exception.Message, Resources.Failed_to_serialize_memory_banks);
501 break;
502 }
503 }
504  
505 private async void openFileDialog1_FileOk(object sender, CancelEventArgs e)
506 {
56 office 507 if (e.Cancel)
508 {
509 return;
510 }
16 office 511  
26 office 512 MemoryChannelIndexed[] memoryBanks = null;
16 office 513  
56 office 514 var fileName = openFileDialog1.FileName;
16 office 515 var deserializationResult =
26 office 516 await Serialization.Deserialize<MemoryChannelIndexed[]>(fileName,
54 office 517 "urn:hambook-memorychannelorganizerbank-schema", "MemoryChannelIndexed.xsd",
56 office 518 _localCancellationToken);
16 office 519  
520 switch (deserializationResult)
521 {
26 office 522 case SerializationSuccess<MemoryChannelIndexed[]> serializationSuccess:
16 office 523 Log.Information(Resources.Deserialized_memory_banks);
524 memoryBanks = serializationSuccess.Result;
525 break;
526 case SerializationFailure serializationFailure:
527 Log.Warning(serializationFailure.Exception, Resources.Failed_to_deserialize_memory_banks);
528 return;
529 }
530  
531 toolStripProgressBar1.Minimum = 0;
532 toolStripProgressBar1.Maximum = 98;
54 office 533 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
16 office 534  
26 office 535 var memoryBankQueue = new ConcurrentQueue<MemoryChannelIndexed>();
16 office 536 var snapshotsQueuedTaskCompletionSource = new TaskCompletionSource<object>();
537  
538 async void IdleHandler(object idleHandlerSender, EventArgs idleHandlerArgs)
539 {
540 await snapshotsQueuedTaskCompletionSource.Task;
541  
542 try
543 {
544 if (!memoryBankQueue.TryDequeue(out var memoryBank))
545 {
546 Application.Idle -= IdleHandler;
547  
548 dataGridView1.Sort(dataGridView1.Columns["LocationColumn"], ListSortDirection.Ascending);
549 toolStripStatusLabel1.Text = "Done.";
550  
551 return;
552 }
54 office 553  
554 switch (Configuration.Radio)
47 office 555 {
556 case "Yaesu FT-891":
48 office 557 var memoryChannel = (Radios.Yaesu.FT_891.MemoryChannel)memoryBank.MemoryChannel;
558  
54 office 559 dataGridView1.Rows[memoryBank.Index].Cells["FrequencyColumn"].Value =
560 memoryBank.MemoryChannel.Frequency;
561 dataGridView1.Rows[memoryBank.Index].Cells["ClarifierDirectionColumn"].Value =
562 (char)memoryChannel.ClarifierDirection;
563 dataGridView1.Rows[memoryBank.Index].Cells["ClarifierOffsetColumn"].Value =
564 memoryChannel.ClarifierOffset;
48 office 565 dataGridView1.Rows[memoryBank.Index].Cells["ClarColumn"].Value = memoryChannel.Clar;
54 office 566 dataGridView1.Rows[memoryBank.Index].Cells["ModeColumn"].Value =
567 memoryBank.MemoryChannel.MemoryRadioMode.Name;
568 dataGridView1.Rows[memoryBank.Index].Cells["CtcssColumn"].Value =
569 (string)memoryChannel.Ctcss;
570 dataGridView1.Rows[memoryBank.Index].Cells["PhaseColumn"].Value =
571 (string)memoryChannel.Phase;
572 dataGridView1.Rows[memoryBank.Index].Cells["TagColumn"].Value =
573 memoryBank.MemoryChannel.Tag;
574 dataGridView1.Rows[memoryBank.Index].Cells["TextColumn"].Value =
575 memoryBank.MemoryChannel.Text;
47 office 576 dataGridView1.Rows[memoryBank.Index].Tag = memoryBank.MemoryChannel;
577 break;
578 }
16 office 579  
580 toolStripProgressBar1.Increment(1);
581 statusStrip1.Update();
582 }
583 catch (Exception exception)
584 {
585 Log.Error(exception, Resources.Could_not_update_data_grid_view);
586 }
587 }
588  
589 Application.Idle += IdleHandler;
590 try
591 {
54 office 592 foreach (var memoryChannel in memoryBanks) memoryBankQueue.Enqueue(memoryChannel);
16 office 593  
594 snapshotsQueuedTaskCompletionSource.TrySetResult(new { });
595 }
596 catch (Exception exception)
597 {
598 Application.Idle -= IdleHandler;
599  
600 Log.Error(exception, Resources.Unable_to_create_memory_banks);
601 }
602 }
22 office 603  
604 private void MemoryOrganizerForm_FormClosing(object sender, FormClosingEventArgs e)
605 {
54 office 606 if (_cancellationTokenSource != null) _cancellationTokenSource.Cancel();
22 office 607 }
40 office 608  
41 office 609 private async void readToolStripMenuItem_Click(object sender, EventArgs e)
40 office 610 {
54 office 611 if (_readLinkedCancellationTokenSource != null)
612 {
613 _readLinkedCancellationTokenSource.Cancel();
614 _readLinkedCancellationTokenSource = null;
615 }
41 office 616  
54 office 617 if (_readMemoryBanksTask != null)
51 office 618 {
54 office 619 await _readMemoryBanksTask;
620 _readMemoryBanksTask = null;
51 office 621 }
41 office 622  
54 office 623 _readCancellationTokenSource = new CancellationTokenSource();
624 _readLinkedCancellationTokenSource =
625 CancellationTokenSource.CreateLinkedTokenSource(new[]
626 { _cancellationTokenSource.Token, _cancellationToken });
627  
628 _readMemoryBanksTask = ReadMemoryBanks(_readLinkedCancellationTokenSource.Token);
629 }
630  
631 private async Task ReadMemoryBanks(CancellationToken cancellationToken)
632 {
633 var rows = GetSelectedDataGridViewRows(dataGridView1);
634  
635 if (!rows.Any()) return;
636  
51 office 637 var list = rows.ToList();
638  
639 var count = list.Count;
640  
41 office 641 toolStripProgressBar1.Minimum = 0;
642 toolStripProgressBar1.Maximum = count;
54 office 643 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
41 office 644  
645 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
646 {
647 try
648 {
649 switch (rowProgress)
650 {
47 office 651 case DataGridViewRowProgressSuccess<MemoryChannel> rowProgressSuccess:
54 office 652 dataGridView1.Rows[rowProgressSuccess.Row.Index].DefaultCellStyle.BackColor =
653 DefaultBackColor;
53 office 654  
655 switch (rowProgressSuccess.Data)
47 office 656 {
657 case Radios.Yaesu.FT_891.MemoryChannel memoryChannel:
658 rowProgress.Row.Cells["FrequencyColumn"].Value = memoryChannel.Frequency;
54 office 659 rowProgress.Row.Cells["ClarifierDirectionColumn"].Value =
660 (char)memoryChannel.ClarifierDirection;
661 rowProgress.Row.Cells["ClarifierOffsetColumn"].Value =
662 memoryChannel.ClarifierOffset;
47 office 663 rowProgress.Row.Cells["ClarColumn"].Value = memoryChannel.Clar;
664 rowProgress.Row.Cells["ModeColumn"].Value = memoryChannel.MemoryRadioMode.Name;
665 rowProgress.Row.Cells["CtcssColumn"].Value = (string)memoryChannel.Ctcss;
666 rowProgress.Row.Cells["PhaseColumn"].Value = (string)memoryChannel.Phase;
667 rowProgress.Row.Cells["TagColumn"].Value = memoryChannel.Tag;
668 rowProgress.Row.Cells["TextColumn"].Value = memoryChannel.Text;
669 rowProgress.Row.Tag = rowProgressSuccess.Data;
670 break;
671 }
41 office 672  
673 toolStripStatusLabel1.Text = $"{Resources.Read_memory_bank} {rowProgress.Index + 1}";
674 break;
54 office 675 case DataGridViewRowProgressFailure<int> rowProgressFailure:
41 office 676 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_read_memory_bank}");
53 office 677 dataGridView1.Rows[rowProgressFailure.Row.Index].DefaultCellStyle.BackColor = Color.Red;
41 office 678  
54 office 679 toolStripStatusLabel1.Text =
680 $"{Resources.Could_not_read_memory_bank} {rowProgress.Index + 1}";
41 office 681 break;
682 }
683  
684 toolStripProgressBar1.Increment(1);
685 statusStrip1.Update();
686 }
687 catch (Exception exception)
688 {
689 Log.Error(exception, Resources.Unexpected_error_while_reading_memory_bank);
690 }
691 });
692  
54 office 693 await Task.Run(() => ReadMemoryBanks(list, progress, cancellationToken), cancellationToken);
41 office 694  
695 if (!_cancellationToken.IsCancellationRequested)
696 {
697 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
698 toolStripStatusLabel1.Text = "Done.";
699 }
40 office 700 }
41 office 701  
702 private async void writeToolStripMenuItem_Click(object sender, EventArgs e)
703 {
54 office 704 if (_writeLinkedCancellationTokenSource != null)
705 {
706 _writeLinkedCancellationTokenSource.Cancel();
707 _writeLinkedCancellationTokenSource = null;
708 }
41 office 709  
54 office 710 if (_writeMemoryBanksTask != null)
51 office 711 {
54 office 712 await _writeMemoryBanksTask;
713 _writeMemoryBanksTask = null;
51 office 714 }
715  
54 office 716 _writeCancellationTokenSource = new CancellationTokenSource();
717 _writeLinkedCancellationTokenSource =
718 CancellationTokenSource.CreateLinkedTokenSource(new[]
719 { _cancellationTokenSource.Token, _cancellationToken });
720  
721 _writeMemoryBanksTask = WriteMemoryBanks(_writeLinkedCancellationTokenSource.Token);
722 }
723  
724 private async Task WriteMemoryBanks(CancellationToken cancellationToken)
725 {
726 var rows = GetSelectedDataGridViewRows(dataGridView1);
727  
728 if (!rows.Any()) return;
729  
51 office 730 var list = rows.ToList();
731  
732 var count = list.Count;
733  
41 office 734 toolStripProgressBar1.Minimum = 0;
735 toolStripProgressBar1.Maximum = count;
54 office 736 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
41 office 737  
738 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
739 {
740 try
741 {
742 switch (rowProgress)
743 {
744 case DataGridViewRowProgressSuccess<bool> rowProgressSuccess:
54 office 745 dataGridView1.Rows[rowProgressSuccess.Row.Index].DefaultCellStyle.BackColor =
746 DefaultBackColor;
41 office 747 var success = rowProgressSuccess.Data;
748  
749 if (success)
750 {
751 toolStripStatusLabel1.Text =
54 office 752 $"{Resources.Wrote_memory_bank} {rowProgress.Index + 1}";
41 office 753 toolStripProgressBar1.Increment(1);
754 statusStrip1.Update();
54 office 755  
41 office 756 return;
757 }
758  
759 Log.Error($"{Resources.Could_not_write_memory_bank}");
760 break;
54 office 761 case DataGridViewRowProgressFailure<int> rowProgressFailure:
41 office 762 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_write_memory_bank}");
53 office 763 dataGridView1.Rows[rowProgressFailure.Row.Index].DefaultCellStyle.BackColor = Color.Red;
41 office 764 break;
765 }
766  
767 toolStripStatusLabel1.Text =
768 $"{Resources.Could_not_write_memory_bank} {rowProgress.Index + 1}";
769 toolStripProgressBar1.Increment(1);
770 statusStrip1.Update();
771 }
772 catch (Exception exception)
773 {
774 Log.Error(exception, Resources.Unexpected_error_while_writing_memory_bank);
775 }
776 });
777  
54 office 778 await Task.Run(() => WriteMemoryBanks(list, progress, cancellationToken), cancellationToken);
41 office 779  
780 if (!_cancellationToken.IsCancellationRequested)
781 {
782 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
783 toolStripStatusLabel1.Text = "Done.";
784 }
785 }
51 office 786  
787 private async void readFromVFOAToolStripMenuItem_Click(object sender, EventArgs e)
788 {
789 var rows = GetSelectedDataGridViewRows(dataGridView1);
790  
54 office 791 if (!rows.Any()) return;
51 office 792  
793 var list = rows.ToList();
794  
795 try
796 {
797 foreach (var row in list)
798 {
799 var fa = await _catAssemblies.CatReadAsync<int>("FA", new object[] { }, _cancellationToken);
800  
54 office 801 row.Cells["FrequencyColumn"].Value = $"{fa}";
51 office 802 }
803 }
804 catch (Exception exception)
805 {
806 Log.Error(exception, Resources.Failed_to_read_VFO_A);
807 }
808 }
809  
810 private async void readFromVFOBToolStripMenuItem_Click(object sender, EventArgs e)
811 {
812 var rows = GetSelectedDataGridViewRows(dataGridView1);
813  
54 office 814 if (!rows.Any()) return;
51 office 815  
816 var list = rows.ToList();
817  
818 try
819 {
820 foreach (var row in list)
821 {
822 var fb = await _catAssemblies.CatReadAsync<int>("FB", new object[] { }, _cancellationToken);
823  
824 row.Cells["FrequencyColumn"].Value = $"{fb}";
825 }
826 }
827 catch (Exception exception)
828 {
829 Log.Error(exception, Resources.Failed_to_read_VFO_B);
830 }
831 }
832  
833 private async void memoryChannelToolStripMenuItem_Click(object sender, EventArgs e)
834 {
835 var rows = GetSelectedDataGridViewRows(dataGridView1);
836  
54 office 837 if (!rows.Any()) return;
51 office 838  
839 var row = rows.First();
840  
841 try
842 {
54 office 843 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
844 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
51 office 845 {
54 office 846 await _catAssemblies.CatWriteAsync<string>("MC", new[] { row.Cells["LocationColumn"].Value },
847 _cancellationToken);
51 office 848  
849 soundPlayer.Play();
850 }
851 }
852 catch (Exception exception)
853 {
854 Log.Error(exception, Resources.Failed_to_set_memory_channel);
855 }
856 }
857  
858 private async void frequencyToolStripMenuItem_Click(object sender, EventArgs e)
859 {
860 var rows = GetSelectedDataGridViewRows(dataGridView1);
861  
54 office 862 if (!rows.Any()) return;
51 office 863  
864 var row = rows.First();
865  
866 try
867 {
54 office 868 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
869 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
51 office 870 {
54 office 871 if (await _catAssemblies.CatSetAsync<int, bool>("FA", new[] { row.Cells["FrequencyColumn"].Value },
872 _cancellationToken))
51 office 873 if (Configuration.Navigation.MouseScrollSound)
874 soundPlayer.Play();
875 }
876 }
877 catch (Exception exception)
878 {
879 Log.Error(exception, Resources.Failed_to_set_VFO_A_frequency);
880 }
881 }
882  
883 private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
884 {
885 var dataGridView = (DataGridView)sender;
886  
887 var hitTest = dataGridView.HitTest(e.X, e.Y);
888  
889 switch (e.Button)
890 {
891 case MouseButtons.Right:
54 office 892 if (GetSelectedDataGridViewRows(dataGridView).Count() > 1) return;
51 office 893  
894 dataGridView.ClearSelection();
54 office 895 if (hitTest.RowIndex != -1) dataGridView.Rows[hitTest.RowIndex].Selected = true;
51 office 896 break;
897 }
898 }
52 office 899  
900 private IEnumerable<DataGridViewRow> CopySelectedRows(DataGridView dataGridView)
901 {
902 foreach (var row in GetSelectedDataGridViewRows(dataGridView))
903 {
904 var clone = row.Clone() as DataGridViewRow;
905  
906 for (var i = 0; i < row.Cells.Count; ++i)
907 {
54 office 908 if (row.Cells[i].ReadOnly) continue;
52 office 909  
910 clone.Cells[i].Value = row.Cells[i].Value;
911 }
912  
913 yield return clone;
914 }
915 }
54 office 916  
52 office 917 private void DeleteSelectedRows(DataGridView dataGridView)
918 {
919 foreach (var row in GetSelectedDataGridViewRows(dataGridView))
920 for (var i = 0; i < row.Cells.Count; ++i)
921 {
54 office 922 if (row.Cells[i].ReadOnly) continue;
52 office 923  
924 row.Cells[i].Value = default;
925 }
926 }
927  
928  
929 private void PasteSelectedRows(DataGridView dataGridView, IEnumerable<DataGridViewRow> pasteRows)
930 {
931 var rows = pasteRows.ToList();
54 office 932 if (rows.Count == 0) return;
52 office 933  
934 foreach (var row in GetSelectedDataGridViewRows(dataGridView))
935 {
54 office 936 if (rows.Count == 0) return;
52 office 937  
938 var paste = rows[0];
939 for (var i = 0; i < paste.Cells.Count; ++i)
940 {
54 office 941 if (row.Cells[i].ReadOnly) continue;
52 office 942 row.Cells[i].Value = paste.Cells[i].Value;
943 }
944  
945 rows.RemoveAt(0);
946 }
947 }
948  
949 private IEnumerable<DataGridViewRow> CutSelectedRows(DataGridView dataGridView)
950 {
951 foreach (var row in GetSelectedDataGridViewRows(dataGridView))
952 {
953 var clone = row.Clone() as DataGridViewRow;
954  
955 for (var i = 0; i < row.Cells.Count; ++i)
956 {
54 office 957 if (row.Cells[i].ReadOnly) continue;
52 office 958  
959 clone.Cells[i].Value = row.Cells[i].Value;
960  
961 row.Cells[i].Value = default;
962 }
54 office 963  
52 office 964 yield return clone;
965 }
966 }
967  
968 private void cutToolStripMenuItem1_Click(object sender, EventArgs e)
969 {
970 _clipboardRows = new List<DataGridViewRow>();
54 office 971 foreach (var row in CutSelectedRows(dataGridView1)) _clipboardRows.Add(row);
52 office 972 }
973  
974 private void copyToolStripMenuItem1_Click(object sender, EventArgs e)
975 {
976 _clipboardRows = new List<DataGridViewRow>();
54 office 977 foreach (var row in CopySelectedRows(dataGridView1)) _clipboardRows.Add(row);
52 office 978 }
979  
980 private void pasteToolStripMenuItem1_Click(object sender, EventArgs e)
981 {
982 PasteSelectedRows(dataGridView1, _clipboardRows);
983 }
984  
985 private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
986 {
987 DeleteSelectedRows(dataGridView1);
988 }
53 office 989  
990 private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
991 {
54 office 992 var dataGridView = sender as DataGridView;
53 office 993 foreach (DataGridViewCell cell in dataGridView.Rows[e.RowIndex].Cells)
994 {
54 office 995 if (cell.Selected == false) continue;
53 office 996 var bgColorCell = Color.White;
54 office 997 if (cell.Style.BackColor != Color.Empty)
998 bgColorCell = cell.Style.BackColor;
999 else if (cell.InheritedStyle.BackColor != Color.Empty) bgColorCell = cell.InheritedStyle.BackColor;
53 office 1000 cell.Style.SelectionBackColor = MixColor(bgColorCell, Color.FromArgb(0, 150, 255), 10, 4);
1001 }
1002 }
1003  
1004 //Mix two colors
1005 //Example: Steps=10 & Position=4 makes Color2 mix 40% into Color1
1006 /// <summary>
54 office 1007 /// Mix two colors.
53 office 1008 /// </summary>
54 office 1009 /// <param name="color1"></param>
1010 /// <param name="color2"></param>
1011 /// <param name="steps"></param>
1012 /// <param name="position"></param>
53 office 1013 /// <example>Steps=10 & Positon=4 makes Color2 mix 40% into Color1</example>
1014 /// <remarks>https://stackoverflow.com/questions/38337849/transparent-selectionbackcolor-for-datagridview-cell</remarks>
1015 /// <returns></returns>
54 office 1016 public static Color MixColor(Color color1, Color color2, int steps, int position)
53 office 1017 {
54 office 1018 if (position <= 0 || steps <= 1) return color1;
1019 if (position >= steps) return color2;
53 office 1020 return Color.FromArgb(
54 office 1021 color1.R + (color2.R - color1.R) / steps * position,
1022 color1.G + (color2.G - color1.G) / steps * position,
1023 color1.B + (color2.B - color1.B) / steps * position
1024 );
53 office 1025 }
56 office 1026  
1027 private void DataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
1028 {
1029 switch (Configuration.Radio)
1030 {
1031 case "Yaesu FT-891":
1032 e.Row.Cells["LocationColumn"].Value = default;
1033 e.Row.Cells["FrequencyColumn"].Value = default;
1034 e.Row.Cells["ClarifierDirectionColumn"].Value = "+";
1035 e.Row.Cells["ClarifierOffsetColumn"].Value = 0;
1036 e.Row.Cells["ClarColumn"].Value = default;
1037 e.Row.Cells["ModeColumn"].Value = default;
1038 e.Row.Cells["CtcssColumn"].Value = "Off";
1039 e.Row.Cells["PhaseColumn"].Value = "Simplex";
1040 e.Row.Cells["TagColumn"].Value = default;
1041 e.Row.Cells["TextColumn"].Value = default;
1042 break;
1043 }
1044 }
15 office 1045 }
54 office 1046 }