HamBook – Blame information for rev 59

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