HamBook – Blame information for rev 41

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;
41 office 5 using HamBook.Radios.Yaesu.FT_891;
16 office 6 using HamBook.Utilities.Serialization;
15 office 7 using Serilog;
8 using System;
9 using System.Collections;
10 using System.Collections.Concurrent;
11 using System.Collections.Generic;
12 using System.ComponentModel;
13 using System.Data;
14 using System.Diagnostics;
15 using System.Drawing;
16 using System.IO;
17 using System.Linq;
18 using System.Reflection;
19 using System.Text;
20 using System.Text.RegularExpressions;
21 using System.Threading;
22 using System.Threading.Tasks;
23 using System.Windows.Forms;
24  
25 namespace HamBook
26 {
27 public partial class MemoryOrganizerForm : Form
28 {
29 private Configuration.Configuration Configuration { get; set; }
30  
31 private CatAssemblies _catAssemblies;
32 private CancellationToken _cancellationToken;
41 office 33 private Radios.Generic.MemoryBanks _memoryBanks;
22 office 34 private CancellationTokenSource _cancellationTokenSource;
35 private CancellationTokenSource _localCancellationTokenSource;
36 private CancellationToken _localCancellationToken;
15 office 37  
38 public MemoryOrganizerForm()
39 {
40 InitializeComponent();
22 office 41  
42 _localCancellationTokenSource = new CancellationTokenSource();
43 _localCancellationToken = _localCancellationTokenSource.Token;
15 office 44 }
45  
46 public MemoryOrganizerForm(Configuration.Configuration configuration, CatAssemblies catAssemblies, CancellationToken cancellationToken) : this()
47 {
48 Configuration = configuration;
49 _catAssemblies = catAssemblies;
22 office 50  
41 office 51 _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_localCancellationToken, cancellationToken);
22 office 52 _cancellationToken = _cancellationTokenSource.Token;
41 office 53  
54 _memoryBanks = Radios.Generic.MemoryBanks.Create(configuration.Radio);
15 office 55 }
56  
57 /// <summary>
58 /// Clean up any resources being used.
59 /// </summary>
60 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
61 protected override void Dispose(bool disposing)
62 {
63 if (disposing && (components != null))
64 {
22 office 65 if (_cancellationTokenSource != null)
66 {
67 _cancellationTokenSource.Cancel();
68 }
69  
15 office 70 components.Dispose();
71 }
72 base.Dispose(disposing);
73 }
74  
75 private async void button1_Click(object sender, EventArgs e)
76 {
41 office 77 var rows = dataGridView1.Rows.OfType<DataGridViewRow>().OrderBy(row => row.Index).ToList();
22 office 78 var count = rows.Count;
79  
80 toolStripProgressBar1.Minimum = 0;
81 toolStripProgressBar1.Maximum = count;
82  
83 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
84 {
85 try
86 {
87 switch (rowProgress)
88 {
89 case DataGridViewRowProgressSuccess<MemoryChannel> rowProgressSuccess:
90 var result = rowProgressSuccess.Data;
91  
92 rowProgress.Row.Cells["FrequencyColumn"].Value = result.Frequency;
93 rowProgress.Row.Cells["ClarifierDirectionColumn"].Value = (char)result.ClarifierDirection;
94 rowProgress.Row.Cells["ClarifierOffsetColumn"].Value = result.ClarifierOffset;
95 rowProgress.Row.Cells["ClarColumn"].Value = result.Clar;
96 rowProgress.Row.Cells["ModeColumn"].Value = (string)result.MemoryRadioMode;
97 rowProgress.Row.Cells["CtcssColumn"].Value = (string)result.CtcssMode;
98 rowProgress.Row.Cells["PhaseColumn"].Value = (string)result.Phase;
99 rowProgress.Row.Cells["TagColumn"].Value = result.Tag;
26 office 100 rowProgress.Row.Cells["TextColumn"].Value = result.Text;
22 office 101 rowProgress.Row.Tag = rowProgressSuccess.Data;
102  
41 office 103  
104 toolStripStatusLabel1.Text = $"{Resources.Read_memory_bank} {rowProgress.Index + 1}";
22 office 105 break;
106 case DataGridViewRowProgressFailure rowProgressFailure:
107 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_read_memory_bank}");
108  
41 office 109 toolStripStatusLabel1.Text = $"{Resources.Could_not_read_memory_bank} {rowProgress.Index + 1}";
22 office 110 break;
111 }
112  
113 toolStripProgressBar1.Increment(1);
114 statusStrip1.Update();
115 }
41 office 116 catch (Exception exception)
22 office 117 {
41 office 118 Log.Error(exception, Resources.Unexpected_error_while_reading_memory_bank);
22 office 119 }
120 });
121  
122 await Task.Run(() => ReadMemoryBanks(rows, progress, _cancellationToken), _cancellationToken);
123  
124 if (!_cancellationToken.IsCancellationRequested)
125 {
126 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
127 toolStripStatusLabel1.Text = "Done.";
128 }
15 office 129 }
130  
131 private async void button2_Click(object sender, EventArgs e)
132 {
41 office 133 var rows = dataGridView1.Rows.OfType<DataGridViewRow>().OrderBy(row => row.Index).ToList();
22 office 134 var count = rows.Count;
135  
136 toolStripProgressBar1.Minimum = 0;
137 toolStripProgressBar1.Maximum = count;
138  
139 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
140 {
141 try
142 {
143 switch (rowProgress)
144 {
145 case DataGridViewRowProgressSuccess<bool> rowProgressSuccess:
146 var success = rowProgressSuccess.Data;
147  
41 office 148 if (success)
22 office 149 {
150  
151 toolStripStatusLabel1.Text =
41 office 152 $"{Resources.Wrote_memory_bank} {rowProgress.Index + 1}";
22 office 153 toolStripProgressBar1.Increment(1);
154 statusStrip1.Update();
155 return;
156 }
157  
41 office 158 Log.Error($"{Resources.Could_not_write_memory_bank}");
22 office 159 break;
160 case DataGridViewRowProgressFailure rowProgressFailure:
161 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_write_memory_bank}");
162 break;
163 }
164  
41 office 165 toolStripStatusLabel1.Text =
166 $"{Resources.Could_not_write_memory_bank} {rowProgress.Index + 1}";
167 toolStripProgressBar1.Increment(1);
168 statusStrip1.Update();
22 office 169 }
41 office 170 catch (Exception exception)
171 {
172 Log.Error(exception, Resources.Unexpected_error_while_writing_memory_bank);
173 }
22 office 174  
175 });
176  
177 await Task.Run(() => WriteMemoryBanks(rows, progress, _cancellationToken), _cancellationToken);
178  
179 if (!_cancellationToken.IsCancellationRequested)
180 {
181 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
182 toolStripStatusLabel1.Text = "Done.";
183 }
15 office 184 }
185  
186 private void MemoryOrganizerForm_Load(object sender, EventArgs e)
187 {
188 toolStripProgressBar1.Minimum = 0;
189 toolStripProgressBar1.Maximum = 98;
190  
41 office 191 var memoryBankQueue = new ConcurrentQueue<string>();
192 var memoryBankAddRowsTaskCompletionSource = new TaskCompletionSource<object>();
15 office 193  
194 async void IdleHandler(object idleHandlerSender, EventArgs idleHandlerArgs)
195 {
41 office 196 await memoryBankAddRowsTaskCompletionSource.Task;
15 office 197  
198 try
199 {
200 if (!memoryBankQueue.TryDequeue(out var memoryBank))
201 {
202 Application.Idle -= IdleHandler;
203  
204 dataGridView1.Sort(dataGridView1.Columns["LocationColumn"], ListSortDirection.Ascending);
205 toolStripStatusLabel1.Text = "Done.";
206  
207 return;
208 }
209  
210 var index = dataGridView1.Rows.Add();
211  
41 office 212 dataGridView1.Rows[index].Cells["LocationColumn"].Value = memoryBank;
15 office 213 dataGridView1.Rows[index].Cells["FrequencyColumn"].Value = default;
214 dataGridView1.Rows[index].Cells["ClarifierDirectionColumn"].Value = default;
215 dataGridView1.Rows[index].Cells["ClarifierOffsetColumn"].Value = default;
216 dataGridView1.Rows[index].Cells["ClarColumn"].Value = default;
217 dataGridView1.Rows[index].Cells["ModeColumn"].Value = default;
218 dataGridView1.Rows[index].Cells["CtcssColumn"].Value = default;
219 dataGridView1.Rows[index].Cells["PhaseColumn"].Value = default;
220 dataGridView1.Rows[index].Cells["TagColumn"].Value = default;
221 dataGridView1.Rows[index].Cells["TextColumn"].Value = default;
222  
223 toolStripStatusLabel1.Text = $"{Resources.Read_memory_bank} {memoryBank}";
224  
225 toolStripProgressBar1.Increment(1);
226  
227 statusStrip1.Update();
228 }
229 catch (Exception exception)
230 {
231 Log.Error(exception, Resources.Could_not_update_data_grid_view);
232 }
233 }
234  
235 Application.Idle += IdleHandler;
236 try
237 {
41 office 238 foreach (var memoryBank in _memoryBanks.GetMemoryBanks())
15 office 239 {
240 memoryBankQueue.Enqueue(memoryBank);
241 }
242  
41 office 243 memoryBankAddRowsTaskCompletionSource.TrySetResult(new { });
15 office 244 }
245 catch (Exception exception)
246 {
247 Application.Idle -= IdleHandler;
248  
249 Log.Error(exception, Resources.Unable_to_create_memory_banks);
250 }
251 }
252  
253 private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
254 {
255 var dataGridView = (DataGridView)sender;
256  
257 if (dataGridView.CurrentCell is DataGridViewCheckBoxCell)
258 {
259 dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
260 }
261 }
262  
263 private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
264 {
265 var dataGridView = (DataGridView)sender;
266  
267 dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
268 }
269  
270 private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
271 {
272 var dataGridView = (DataGridView)sender;
273  
274 if (dataGridView.CurrentCell is DataGridViewCheckBoxCell)
275 {
276 if (dataGridView.CurrentCell.IsInEditMode)
277 {
278 if (dataGridView.IsCurrentCellDirty)
279 {
280 dataGridView.EndEdit();
281 }
282 }
283 }
284 }
285  
286 private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
287 {
288 var dataGridView = (DataGridView)sender;
289  
290 if (e.RowIndex == -1 || e.ColumnIndex == -1)
291 {
292 return;
293 }
294  
295 switch (dataGridView.Columns[e.ColumnIndex].Name)
296 {
297 case "EnableColumn":
298 //ProcessEnable(dataGridView.Rows[e.RowIndex]);
299 break;
300 }
301 }
302  
303 private void DataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
304 {
305 var dataGridView = (DataGridView)sender;
306  
307 if (e.RowIndex == -1 || e.ColumnIndex == -1 ||
308 !(dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn))
309 {
310 return;
311 }
312  
313 dataGridView.EndEdit();
314 }
315  
316 private void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
317 {
318 var dataGridView = (DataGridView)sender;
319  
320 if (e.RowIndex == -1 || e.ColumnIndex == -1 ||
321 !(dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn))
322 {
323 return;
324 }
325  
326 dataGridView.EndEdit();
327 }
328  
329 private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
330 {
331 // @(-.-)@ -(o.o)- @(o_o)@
332 }
333  
334 private static List<DataGridViewRow> GetSelectedDataGridViewRows(DataGridView dataGridView)
335 {
336 return dataGridView.SelectedRows.OfType<DataGridViewRow>().OrderBy(row => row.Index).ToList();
337 }
338  
339 private async Task ReadMemoryBanks(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress,
340 CancellationToken cancellationToken)
341 {
342 var count = rows.Count;
343  
344 for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i)
345 {
346 try
347 {
41 office 348 var location = $"{rows[i].Cells["LocationColumn"].Value}";
15 office 349  
41 office 350 var result = await _catAssemblies.CatReadAsync<MemoryChannel>("MT", new object[] { location }, _cancellationToken);
15 office 351  
352 progress.Report(new DataGridViewRowProgressSuccess<MemoryChannel>(rows[i], i, result));
353 }
354 catch (UnexpectedRadioResponseException exception)
355 {
356 progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception));
357 }
358 catch (Exception exception)
359 {
360 progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception));
361 }
362 }
363 }
364  
365 private async Task WriteMemoryBanks(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress,
366 CancellationToken cancellationToken)
367 {
368 var count = rows.Count;
369  
370 for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i)
371 {
372 try
373 {
41 office 374 var location = $"{rows[i].Cells["LocationColumn"].Value}";
15 office 375  
376 var frequency = int.Parse($"{rows[i].Cells["FrequencyColumn"].Value}");
377 var clarifierDirection = char.Parse($"{rows[i].Cells["ClarifierDirectionColumn"].Value}");
378 var clarifierOffset = int.Parse($"{rows[i].Cells["ClarifierOffsetColumn"].Value}");
40 office 379 var clar = Convert.ToBoolean(rows[i].Cells["ClarColumn"].Value);
15 office 380 var radioMode = new MemoryRadioMode($"{rows[i].Cells["ModeColumn"].Value}");
381 var ctcssMode = new CtcssMode($"{rows[i].Cells["CtcssColumn"].Value}");
382 var phase = new RadioPhase($"{rows[i].Cells["PhaseColumn"].Value}");
40 office 383 var tag = Convert.ToBoolean(rows[i].Cells["TagColumn"].Value);
17 office 384 var text = $"{rows[i].Cells["TextColumn"].Value, -12}";
15 office 385  
386 var memoryChannel = new MemoryChannel
387 {
41 office 388 CurrentLocation = location,
15 office 389 Frequency = frequency,
390 ClarifierDirection = clarifierDirection,
391 ClarifierOffset = clarifierOffset,
392 Clar = clar,
393 MemoryRadioMode = radioMode,
394 CtcssMode = ctcssMode,
395 Phase = phase,
396 Tag = tag,
397 Text = text
398 };
399  
400 var result = await _catAssemblies.CatSetAsync<MemoryChannel, bool>("MT", new object[] { memoryChannel }, _cancellationToken);
401  
402 progress.Report(new DataGridViewRowProgressSuccess<bool>(rows[i], i, result));
403 }
404 catch (UnexpectedRadioResponseException exception)
405 {
406 progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception));
407 }
408 catch (Exception exception)
409 {
410 progress.Report(new DataGridViewRowProgressFailure(rows[i], i, exception));
411 }
412 }
413 }
16 office 414  
415 private void importToolStripMenuItem_Click(object sender, EventArgs e)
416 {
417 openFileDialog1.ShowDialog();
418 }
419  
420 private void exportToolStripMenuItem_Click(object sender, EventArgs e)
421 {
422 saveFileDialog1.ShowDialog();
423 }
424  
425 private async void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
426 {
427 if (e.Cancel)
428 {
429 return;
430 }
431  
432 var fileName = saveFileDialog1.FileName;
26 office 433 var list = new List<MemoryChannelIndexed>();
16 office 434 foreach(var row in dataGridView1.Rows.OfType<DataGridViewRow>().OrderBy(row => row.Index))
435 {
436 if (row.Tag is MemoryChannel memoryChannel)
437 {
26 office 438 var memoryChannelOrganizerBanks = new MemoryChannelIndexed(row.Index, memoryChannel);
16 office 439 list.Add(memoryChannelOrganizerBanks);
440 }
441 }
442  
443 var memoryBanks = list.ToArray();
444  
445 switch (await Serialization.Serialize(memoryBanks, fileName, "MemoryChannelOrganizerBank",
446 "<!ATTLIST MemoryChannelOrganizerBank xmlns:xsi CDATA #IMPLIED xsi:noNamespaceSchemaLocation CDATA #IMPLIED>",
447 CancellationToken.None))
448 {
26 office 449 case SerializationSuccess<MemoryChannelIndexed[]> configuration:
16 office 450 Log.Information(Resources.Serialized_memory_banks);
451 break;
452 case SerializationFailure serializationFailure:
453 Log.Warning(serializationFailure.Exception.Message, Resources.Failed_to_serialize_memory_banks);
454 break;
455 }
456 }
457  
458 private async void openFileDialog1_FileOk(object sender, CancelEventArgs e)
459 {
460 if(e.Cancel)
461 {
462 return;
463 }
464  
465 var fileName = openFileDialog1.FileName;
26 office 466 MemoryChannelIndexed[] memoryBanks = null;
16 office 467  
468 var deserializationResult =
26 office 469 await Serialization.Deserialize<MemoryChannelIndexed[]>(fileName,
16 office 470 "urn:hambook-memorychannelorganizerbank-schema", "MemoryChannelOrganizerBanks.xsd", CancellationToken.None);
471  
472 switch (deserializationResult)
473 {
26 office 474 case SerializationSuccess<MemoryChannelIndexed[]> serializationSuccess:
16 office 475 Log.Information(Resources.Deserialized_memory_banks);
476 memoryBanks = serializationSuccess.Result;
477 break;
478 case SerializationFailure serializationFailure:
479 Log.Warning(serializationFailure.Exception, Resources.Failed_to_deserialize_memory_banks);
480 return;
481 }
482  
483 toolStripProgressBar1.Minimum = 0;
484 toolStripProgressBar1.Maximum = 98;
485  
26 office 486 var memoryBankQueue = new ConcurrentQueue<MemoryChannelIndexed>();
16 office 487 var snapshotsQueuedTaskCompletionSource = new TaskCompletionSource<object>();
488  
489 async void IdleHandler(object idleHandlerSender, EventArgs idleHandlerArgs)
490 {
491 await snapshotsQueuedTaskCompletionSource.Task;
492  
493 try
494 {
495 if (!memoryBankQueue.TryDequeue(out var memoryBank))
496 {
497 Application.Idle -= IdleHandler;
498  
499 dataGridView1.Sort(dataGridView1.Columns["LocationColumn"], ListSortDirection.Ascending);
500 toolStripStatusLabel1.Text = "Done.";
501  
502 return;
503 }
504  
505 dataGridView1.Rows[memoryBank.Index].Cells["FrequencyColumn"].Value = memoryBank.MemoryChannel.Frequency;
506 dataGridView1.Rows[memoryBank.Index].Cells["ClarifierDirectionColumn"].Value = (char)memoryBank.MemoryChannel.ClarifierDirection;
507 dataGridView1.Rows[memoryBank.Index].Cells["ClarifierOffsetColumn"].Value = memoryBank.MemoryChannel.ClarifierOffset;
508 dataGridView1.Rows[memoryBank.Index].Cells["ClarColumn"].Value = memoryBank.MemoryChannel.Clar;
509 dataGridView1.Rows[memoryBank.Index].Cells["ModeColumn"].Value = (string)memoryBank.MemoryChannel.MemoryRadioMode;
510 dataGridView1.Rows[memoryBank.Index].Cells["CtcssColumn"].Value = (string)memoryBank.MemoryChannel.CtcssMode;
511 dataGridView1.Rows[memoryBank.Index].Cells["PhaseColumn"].Value = (string)memoryBank.MemoryChannel.Phase;
512 dataGridView1.Rows[memoryBank.Index].Cells["TagColumn"].Value = memoryBank.MemoryChannel.Tag;
513 dataGridView1.Rows[memoryBank.Index].Cells["TextColumn"].Value = memoryBank.MemoryChannel.Text;
514  
515 toolStripProgressBar1.Increment(1);
516  
517 statusStrip1.Update();
518 }
519 catch (Exception exception)
520 {
521 Log.Error(exception, Resources.Could_not_update_data_grid_view);
522 }
523 }
524  
525 Application.Idle += IdleHandler;
526 try
527 {
528 foreach (var memoryChannel in memoryBanks)
529 {
530 memoryBankQueue.Enqueue(memoryChannel);
531 }
532  
533 snapshotsQueuedTaskCompletionSource.TrySetResult(new { });
534 }
535 catch (Exception exception)
536 {
537 Application.Idle -= IdleHandler;
538  
539 Log.Error(exception, Resources.Unable_to_create_memory_banks);
540 }
541 }
22 office 542  
543 private void MemoryOrganizerForm_FormClosing(object sender, FormClosingEventArgs e)
544 {
545 if(_cancellationTokenSource != null)
546 {
547 _cancellationTokenSource.Cancel();
548 }
549 }
40 office 550  
41 office 551 private async void readToolStripMenuItem_Click(object sender, EventArgs e)
40 office 552 {
41 office 553 var rows = GetSelectedDataGridViewRows(dataGridView1);
554  
555 var count = rows.Count;
556  
557 toolStripProgressBar1.Minimum = 0;
558 toolStripProgressBar1.Maximum = count;
559  
560 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
561 {
562 try
563 {
564 switch (rowProgress)
565 {
566 case DataGridViewRowProgressSuccess<MemoryChannel> rowProgressSuccess:
567 var result = rowProgressSuccess.Data;
568  
569 rowProgress.Row.Cells["FrequencyColumn"].Value = result.Frequency;
570 rowProgress.Row.Cells["ClarifierDirectionColumn"].Value = (char)result.ClarifierDirection;
571 rowProgress.Row.Cells["ClarifierOffsetColumn"].Value = result.ClarifierOffset;
572 rowProgress.Row.Cells["ClarColumn"].Value = result.Clar;
573 rowProgress.Row.Cells["ModeColumn"].Value = (string)result.MemoryRadioMode;
574 rowProgress.Row.Cells["CtcssColumn"].Value = (string)result.CtcssMode;
575 rowProgress.Row.Cells["PhaseColumn"].Value = (string)result.Phase;
576 rowProgress.Row.Cells["TagColumn"].Value = result.Tag;
577 rowProgress.Row.Cells["TextColumn"].Value = result.Text;
578 rowProgress.Row.Tag = rowProgressSuccess.Data;
579  
580  
581 toolStripStatusLabel1.Text = $"{Resources.Read_memory_bank} {rowProgress.Index + 1}";
582 break;
583 case DataGridViewRowProgressFailure rowProgressFailure:
584 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_read_memory_bank}");
585  
586 toolStripStatusLabel1.Text = $"{Resources.Could_not_read_memory_bank} {rowProgress.Index + 1}";
587 break;
588 }
589  
590 toolStripProgressBar1.Increment(1);
591 statusStrip1.Update();
592 }
593 catch (Exception exception)
594 {
595 Log.Error(exception, Resources.Unexpected_error_while_reading_memory_bank);
596 }
597 });
598  
599 await Task.Run(() => ReadMemoryBanks(rows, progress, _cancellationToken), _cancellationToken);
600  
601 if (!_cancellationToken.IsCancellationRequested)
602 {
603 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
604 toolStripStatusLabel1.Text = "Done.";
605 }
40 office 606 }
41 office 607  
608 private async void writeToolStripMenuItem_Click(object sender, EventArgs e)
609 {
610 var rows = GetSelectedDataGridViewRows(dataGridView1);
611 var count = rows.Count;
612  
613 toolStripProgressBar1.Minimum = 0;
614 toolStripProgressBar1.Maximum = count;
615  
616 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
617 {
618 try
619 {
620 switch (rowProgress)
621 {
622 case DataGridViewRowProgressSuccess<bool> rowProgressSuccess:
623 var success = rowProgressSuccess.Data;
624  
625 if (success)
626 {
627  
628 toolStripStatusLabel1.Text =
629 $"{Resources.Wrote_memory_bank} {rowProgress.Index + 1}";
630 toolStripProgressBar1.Increment(1);
631 statusStrip1.Update();
632 return;
633 }
634  
635 Log.Error($"{Resources.Could_not_write_memory_bank}");
636 break;
637 case DataGridViewRowProgressFailure rowProgressFailure:
638 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_write_memory_bank}");
639 break;
640 }
641  
642 toolStripStatusLabel1.Text =
643 $"{Resources.Could_not_write_memory_bank} {rowProgress.Index + 1}";
644 toolStripProgressBar1.Increment(1);
645 statusStrip1.Update();
646 }
647 catch (Exception exception)
648 {
649 Log.Error(exception, Resources.Unexpected_error_while_writing_memory_bank);
650 }
651  
652 });
653  
654 await Task.Run(() => WriteMemoryBanks(rows, progress, _cancellationToken), _cancellationToken);
655  
656 if (!_cancellationToken.IsCancellationRequested)
657 {
658 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
659 toolStripStatusLabel1.Text = "Done.";
660 }
661 }
15 office 662 }
663 }