HamBook – Blame information for rev 53

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