HamBook – Blame information for rev 54

Subversion Repositories:
Rev:
Rev Author Line No. Line
54 office 1 using System;
2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.Drawing;
6 using System.Linq;
7 using System.Threading;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10 using HamBook.Properties;
11 using HamBook.Radios;
12 using HamBook.Radios.Generic;
13 using HamBook.Utilities;
14 using Serilog;
15 using static Org.BouncyCastle.Crypto.Digests.SkeinEngine;
16  
17 namespace HamBook
18 {
19 public partial class MenuForm : Form
20 {
21 private static ScheduledContinuation _searchTextBoxChangedContinuation;
22  
23 private readonly CatAssemblies _catAssemblies;
24 private readonly MenuIndex _menuIndex;
25 private CancellationToken _cancellationToken;
26 private CancellationToken _localCancellationToken;
27 private readonly CancellationTokenSource _localCancellationTokenSource;
28 private readonly CancellationTokenSource _cancellationTokenSource;
29 private CancellationTokenSource _readLinkedCancellationTokenSource;
30 private CancellationTokenSource _readCancellationTokenSource;
31 private Task _readMenuTask;
32 private CancellationTokenSource _writeCancellationTokenSource;
33 private CancellationTokenSource _writeLinkedCancellationTokenSource;
34 private Task _writeMenuTask;
35  
36 public MenuForm()
37 {
38 InitializeComponent();
39 Utilities.WindowState.FormTracker.Track(this);
40  
41 _localCancellationTokenSource = new CancellationTokenSource();
42 _localCancellationToken = _localCancellationTokenSource.Token;
43 }
44  
45 public MenuForm(Configuration.Configuration configuration, CatAssemblies catAssemblies,
46 CancellationToken cancellationToken) : this()
47 {
48 Configuration = configuration;
49 _catAssemblies = catAssemblies;
50 _cancellationToken = cancellationToken;
51  
52 _searchTextBoxChangedContinuation = new ScheduledContinuation();
53 _menuIndex = MenuIndex.Create(Configuration.Radio);
54  
55 _cancellationTokenSource =
56 CancellationTokenSource.CreateLinkedTokenSource(_localCancellationToken, cancellationToken);
57 _cancellationToken = _cancellationTokenSource.Token;
58 }
59  
60 private Configuration.Configuration Configuration { get; }
61  
62 private void AddMenuItem<T>(string menuIndex, string menuFunction, Func<IEnumerable<T>> values,
63 T defaultValue = default, int index = -1)
64 {
65 if (index == -1) index = dataGridView1.Rows.Add();
66  
67 dataGridView1.Rows[index].Cells["IndexColumn"].Value = menuIndex;
68 dataGridView1.Rows[index].Cells["FunctionColumn"].Value = menuFunction;
69  
70 foreach (var value in values.Invoke())
71 {
72 ((DataGridViewComboBoxCell)dataGridView1.Rows[index].Cells["ValueColumn"]).Items.Add($"{value}");
73 ((DataGridViewComboBoxCell)dataGridView1.Rows[index].Cells["ValueColumn"]).Value = $"{defaultValue}";
74 }
75 }
76  
77 private void MenuForm_Load(object sender, EventArgs e)
78 {
79 // Generate columns based on radio type.
80 switch (Configuration.Radio)
81 {
82 case "Yaesu FT-891":
83 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
84 { Name = "IndexColumn", HeaderText = "Index", ReadOnly = true });
85 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
86 { Name = "FunctionColumn", HeaderText = "Function", ReadOnly = true });
87 dataGridView1.Columns.Add(new DataGridViewComboBoxColumn
88 { Name = "ValueColumn", HeaderText = "Value" });
89  
90  
91 AddMenuItem("0101", "AGC FAST DELAY", () => { return Mathematics.GenerateRange(20, 4000, 20); },
92 300);
93  
94 AddMenuItem("0102", "AGC MID DELAY", () => { return Mathematics.GenerateRange(20, 4000, 20); },
95 700);
96  
97 AddMenuItem("0103", "AGC SLOW DELAY", () => { return Mathematics.GenerateRange(20, 4000, 20); },
98 3000);
99  
100 AddMenuItem("0201", "LCD CONTRAST", () => { return Mathematics.GenerateRange(1, 15); }, 8);
101  
102 AddMenuItem("0202", "DIMMER BACKLIT", () => { return Mathematics.GenerateRange(1, 15); }, 8);
103  
104 AddMenuItem("0203", "DIMMER LCD", () => { return Mathematics.GenerateRange(1, 15); }, 8);
105  
106 AddMenuItem("0204", "DIMMER TX/BUSY", () => { return Mathematics.GenerateRange(1, 15); }, 8);
107  
108 AddMenuItem("0205", "PEAK HOLD", () => { return new[] { "OFF", "0.5", "1.0", "2.0" }; }, "OFF");
109  
110 AddMenuItem("0206", "ZIN LED", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
111  
112 AddMenuItem("0207", "POP-UP MENU", () => { return new[] { "UPPER", "LOWER" }; }, "LOWER");
113  
114 AddMenuItem("0301", "DVS RX OUT LVL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
115  
116 AddMenuItem("0302", "DVS TX OUT LVL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
117  
118 AddMenuItem("0401", "KEYER TYPE",
119 () =>
120 {
121 return new[] { "OFF", "BUG", "ELEKEY-A", "ELEKEY-B", "ELEKEY-Y", "ACS" };
122 }, "ELEKEY-B");
123  
124 AddMenuItem("0402", "KEYER DOT/DASH", () => { return new[] { "NOR", "KEY" }; }, "NOR");
125  
126 AddMenuItem("0403", "CW WEIGHT", () =>
127 {
128 var value = new List<string>();
129 for (var i = 2.0; i <= 4.5; i += 0.1)
130 {
131 var v = $"{(decimal)i:f1}";
132 value.Add(v);
133 }
134  
135 return value;
136 }, "3.0");
137  
138 AddMenuItem("0404", "BEACON INTERVAL",
139 () => { return new[] { "OFF" }.Concat(Mathematics.GenerateRange(1, 690).Select(i => i.ToString())); },
140 "OFF");
141  
142 AddMenuItem("0405", "NUMBER STYLE",
143 () => { return new[] { "1290", "AUNO", "AUNT", "A2NO", "A2NT", "12NO", "12NT" }; }, "1290");
144  
145 AddMenuItem("0406", "CONTEST NUMBER", () => { return Mathematics.GenerateRange(0, 9999); }, 1);
146  
147 AddMenuItem("0407", "CW MEMORY 1", () => { return new[] { "TEXT", "MESSAGE" }; }, "TEXT");
148  
149 AddMenuItem("0408", "CW MEMORY 2", () => { return new[] { "TEXT", "MESSAGE" }; }, "TEXT");
150  
151 AddMenuItem("0409", "CW MEMORY 3", () => { return new[] { "TEXT", "MESSAGE" }; }, "TEXT");
152  
153 AddMenuItem("0410", "CW MEMORY 4", () => { return new[] { "TEXT", "MESSAGE" }; }, "TEXT");
154  
155 AddMenuItem("0411", "CW MEMORY 5", () => { return new[] { "TEXT", "MESSAGE" }; }, "TEXT");
156  
157 AddMenuItem("0501", "NB WIDTH", () => { return new[] { 1, 3, 10 }; }, 3);
158  
159 AddMenuItem("0502", "NB REJECTION", () => { return new[] { 10, 30, 50 }; }, 30);
160  
161 AddMenuItem("0503", "NB LEVEL", () => { return Mathematics.GenerateRange(0, 10); }, 5);
162  
163 AddMenuItem("0504", "BEEP LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 30);
164  
165 AddMenuItem("0505", "RF/SQL VR", () => { return new[] { "RF", "SQL" }; }, "RF");
166  
167 AddMenuItem("0506", "CAT RATE", () => { return new[] { 4800, 9600, 19200, 38400 }; }, 9600);
168  
169 AddMenuItem("0507", "CAT TOT", () => { return new[] { 10, 100, 1000, 3000 }; }, 1000);
170  
171 AddMenuItem("0508", "CAT RTS", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
172  
173 AddMenuItem("0509", "MEM GROUP", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
174  
175 AddMenuItem("0510", "FM SETTING", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
176  
177 AddMenuItem("0511", "REC SETTING", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
178  
179 AddMenuItem("0512", "ATAS SETTING", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
180  
181 AddMenuItem("0513", "QUICK SPL FREQ", () => { return Mathematics.GenerateRange(-20, 20); }, 5);
182  
183 AddMenuItem("0514", "TX TOT",
184 () =>
185 {
186 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(1, 30).Select(i => i.ToString()));
187 }, "OFF");
188  
189 AddMenuItem("0515", "MIC SCAN", () => { return new[] { "DISABLE", "ENABLE" }; }, "ENABLE");
190  
191 AddMenuItem("0516", "MIC SCAN RESUME", () => { return new[] { "PAUSE", "TIME" }; }, "TIME");
192  
193 AddMenuItem("0517", "REF FREQ ADJ", () => { return Mathematics.GenerateRange(-25, 25); });
194  
195 AddMenuItem("0518", "CLAR SELECT", () => { return new[] { "RX", "TX", "TRX" }; }, "RX");
196  
197 AddMenuItem("0519", "APO", () => { return new[] { "OFF", "1", "2", "4", "6", "8", "10", "12" }; },
198 "RX");
199  
200 AddMenuItem("0520", "FAN CONTROL", () => { return new[] { "NORMAL", "CONTEST" }; }, "NORMAL");
201  
202 AddMenuItem("0601", "AM LCUT FREQ",
203 () =>
204 {
205 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
206 .Select(i => i.ToString()));
207 }, "OFF");
208  
209 AddMenuItem("0602", "AM LCUT SLOPE", () => { return new[] { 6, 18 }; }, 6);
210  
211 AddMenuItem("0603", "AM HCUT FREQ",
212 () =>
213 {
214 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
215 .Select(i => i.ToString()));
216 }, "OFF");
217  
218 AddMenuItem("0604", "AM HCUT SLOPE", () => { return new[] { 6, 18 }; }, 6);
219  
220 AddMenuItem("0605", "AM MIC SELECT", () => { return new[] { "MIC", "REAR" }; }, "MIC");
221  
222 AddMenuItem("0606", "AM OUT LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
223  
224 AddMenuItem("0607", "AM PTT SELECT", () => { return new[] { "DAKY", "RTS", "DTR" }; }, "DAKY");
225  
226 AddMenuItem("0701", "CW LCUT FREQ",
227 () =>
228 {
229 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
230 .Select(i => i.ToString()));
231 }, "250");
232  
233 AddMenuItem("0702", "CW LCUT SLOPE", () => { return new[] { 6, 18 }; }, 18);
234  
235 AddMenuItem("0703", "CW HCUT FREQ",
236 () =>
237 {
238 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
239 .Select(i => i.ToString()));
240 }, "1200");
241  
242 AddMenuItem("0704", "CW HCUT SLOPE", () => { return new[] { 6, 18 }; }, 18);
243  
244 AddMenuItem("0705", "CW OUT LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
245  
246 AddMenuItem("0706", "CW AUTO MODE", () => { return new[] { "OFF", "50M", "ON" }; }, "OFF");
247  
248 AddMenuItem("0707", "CW BFO", () => { return new[] { "USB", "LSB", "AUTO" }; }, "USB");
249  
250 AddMenuItem("0708", "CW BK-IN TYPE", () => { return new[] { "SEMI", "FULL" }; }, "SEMI");
251  
252 AddMenuItem("0709", "CW BK-IN DELAY", () => { return Mathematics.GenerateRange(30, 3000, 10); },
253 200);
254  
255 AddMenuItem("0710", "CW WAVE SHAPE", () => { return new[] { string.Empty, "2", "4" }; }, "4");
256  
257 AddMenuItem("0711", "CW FREQ DISPLAY", () => { return new[] { "FREQ", "PITCH" }; }, "PITCH");
258  
259 AddMenuItem("0712", "PC KEYING", () => { return new[] { "OFF", "DAKY", "RTS", "DTR" }; }, "OFF");
260  
261 AddMenuItem("0713", "QSK DELAY TIME", () => { return new[] { 15, 20, 25, 30 }; }, 15);
262  
263 AddMenuItem("0801", "DATA MODE", () => { return new[] { "PSK", "OTHERS" }; }, "OTHERS");
264  
265 AddMenuItem("0802", "PSK TONE", () => { return new[] { 1000, 1500, 2000 }; }, 1000);
266  
267 AddMenuItem("0803", "OTHER DISP", () => { return Mathematics.GenerateRange(-3000, 3000, 10); },
268 1000);
269  
270 AddMenuItem("0804", "OTHER SHIFT", () => { return Mathematics.GenerateRange(-3000, 3000, 10); },
271 1500);
272  
273 AddMenuItem("0805", "DATA LCUT FREQ",
274 () =>
275 {
276 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
277 .Select(i => i.ToString()));
278 }, "OFF");
279  
280 AddMenuItem("0806", "DATA LCUT SLOPE", () => { return new[] { 6, 18 }; }, 18);
281  
282 AddMenuItem("0807", "DATA HCUT FREQ",
283 () =>
284 {
285 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
286 .Select(i => i.ToString()));
287 }, "OFF");
288  
289 AddMenuItem("0808", "DATA HCUT SLOPE", () => { return new[] { 6, 18 }; }, 18);
290  
291 AddMenuItem("0809", "DATA IN SELECT", () => { return new[] { "MIC", "REAR" }; }, "REAR");
292  
293 AddMenuItem("0810", "DATA PTT SELECT", () => { return new[] { "DAKY", "RTS", "DTR" }; }, "DAKY");
294  
295 AddMenuItem("0811", "DATA OUT LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
296  
297 AddMenuItem("0812", "DATA BFO", () => { return new[] { "USB", "LSB" }; }, "USB");
298  
299 AddMenuItem("0901", "FM MIC SELECT", () => { return new[] { "MIC", "REAR" }; }, "MIC");
300  
301 AddMenuItem("0902", "FM OUT LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
302  
303 AddMenuItem("0903", "PKT PTT SELECT", () => { return new[] { "DAKY", "RTS", "DTR" }; }, "DAKY");
304  
305 AddMenuItem("0904", "RPT SHIFT 28MHz", () => { return Mathematics.GenerateRange(0, 1000, 10); },
306 100);
307  
308 AddMenuItem("0905", "RPT SHIFT 50MHz", () => { return Mathematics.GenerateRange(0, 4000, 10); },
309 100);
310  
311 AddMenuItem("0906", "DCS POLARITY",
312 () => { return new[] { "Tn-Rn", "Tn-Riv", "Tiv-Rn", "Tiv-Riv" }; }, "Tn-Rn");
313  
314 AddMenuItem("1001", "RTTY LCUT FREQ",
315 () =>
316 {
317 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
318 .Select(i => i.ToString()));
319 }, "300");
320  
321 AddMenuItem("1002", "RTTY LCUT SLOPE", () => { return new[] { 6, 18 }; }, 18);
322  
323 AddMenuItem("1003", "RTTY HCUT FREQ",
324 () =>
325 {
326 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
327 .Select(i => i.ToString()));
328 }, "OFF");
329  
330 AddMenuItem("1004", "RTTY HCUT SLOPE", () => { return new[] { 6, 18 }; }, 18);
331  
332 AddMenuItem("1005", "RTTY SHIFT PORT", () => { return new[] { "SHIFT", "DTR", "RTS" }; }, "SHIFT");
333  
334 AddMenuItem("1006", "RTTY POLARITY-R", () => { return new[] { "NOR", "REV" }; }, "NOR");
335  
336 AddMenuItem("1007", "RTTY POLARITY-T", () => { return new[] { "NOR", "REV" }; }, "NOR");
337  
338 AddMenuItem("1008", "RTTY OUT LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
339  
340 AddMenuItem("1009", "RTTY SHIFT FREQ", () => { return new[] { 170, 200, 425, 850 }; }, 170);
341  
342 AddMenuItem("1010", "RTTY MARK FREQ", () => { return new[] { 1275, 2125 }; }, 2125);
343  
344 AddMenuItem("1011", "RTTY BFO", () => { return new[] { "USB", "LSB" }; }, "LSB");
345  
346 AddMenuItem("1101", "SSB LCUT FREQ",
347 () =>
348 {
349 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
350 .Select(i => i.ToString()));
351 }, "100");
352  
353 AddMenuItem("1102", "SSB LCUT SLOPE", () => { return new[] { 6, 18 }; }, 6);
354  
355 AddMenuItem("1103", "SSB HCUT FREQ",
356 () =>
357 {
358 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
359 .Select(i => i.ToString()));
360 }, "3000");
361  
362 AddMenuItem("1104", "SSB HCUT SLOPE", () => { return new[] { 6, 18 }; }, 6);
363  
364 AddMenuItem("1105", "SSB MIC SELECT", () => { return new[] { "MIC", "REAR" }; }, "REAR");
365  
366 AddMenuItem("1106", "RTTY OUT LEVEL", () => { return Mathematics.GenerateRange(0, 100); }, 50);
367  
368 AddMenuItem("1107", "SSB BFO", () => { return new[] { "USB", "LSB", "AUTO" }; }, "USB");
369  
370 AddMenuItem("1108", "SSB PTT SELECT", () => { return new[] { "DAKY", "RTS", "DTR" }; }, "DAKY");
371  
372 AddMenuItem("1109", "SSB TX BPF",
373 () => { return new[] { "100-3000", "100-2900", "200-2800", "300-2700", "400-2600" }; },
374 "300-2700");
375  
376 AddMenuItem("1201", "APF WIDTH", () => { return new[] { "NARROW", "MEDIUM", "WIDE" }; }, "MEDIUM");
377  
378 AddMenuItem("1202", "CONTOUR LEVEL", () => { return Mathematics.GenerateRange(-40, 20); }, -15);
379  
380 AddMenuItem("1203", "CONTOUR WIDTH", () => { return Mathematics.GenerateRange(1, 11); }, 10);
381  
382 AddMenuItem("1204", "IF NOTCH WIDTH", () => { return new[] { "NARROW", "WIDE" }; }, "WIDE");
383  
384 AddMenuItem("1301", "SCP START CYCLE", () => { return new[] { "OFF", "3", "5", "10" }; }, "OFF");
385  
386 AddMenuItem("1302", "SCP SPAN FREQ", () => { return new[] { 37.5, 75, 150, 375, 750 }; }, 750);
387  
388 AddMenuItem("1401", "QUICK DIAL", () => { return new[] { 50, 100, 500 }; }, 500);
389  
390 AddMenuItem("1402", "SSB DIAL STEP", () => { return new[] { 2, 5, 10 }; }, 10);
391  
392 AddMenuItem("1403", "AM DIAL STEP", () => { return new[] { 10, 100 }; }, 10);
393  
394 AddMenuItem("1404", "FM DIAL STEP", () => { return new[] { 10, 100 }; }, 100);
395  
396 AddMenuItem("1405", "DIAL STEP", () => { return new[] { 2, 5, 10 }; }, 5);
397  
398 AddMenuItem("1406", "AM CH STEP", () => { return new[] { 2.5, 5, 2.9, 10, 12.5, 25 }; }, 5);
399  
400 AddMenuItem("1407", "FM CH STEP", () => { return new[] { 5, 6.25, 10, 12.5, 15, 20, 25 }; }, 5);
401  
402 AddMenuItem("1501", "EQ1 FREQ",
403 () =>
404 {
405 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 700, 100)
406 .Select(i => i.ToString()));
407 }, "OFF");
408  
409 AddMenuItem("1502", "EQ1 LEVEL", () => { return Mathematics.GenerateRange(-20, 10); }, 5);
410  
411 AddMenuItem("1503", "EQ1 BWTH", () => { return Mathematics.GenerateRange(1, 10); }, 10);
412  
413 AddMenuItem("1504", "EQ2 FREQ",
414 () =>
415 {
416 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 1500, 100)
417 .Select(i => i.ToString()));
418 }, "OFF");
419  
420 AddMenuItem("1505", "EQ2 LEVEL", () => { return Mathematics.GenerateRange(-20, 10); }, 5);
421  
422 AddMenuItem("1506", "EQ2 BWTH", () => { return Mathematics.GenerateRange(1, 10); }, 10);
423  
424 AddMenuItem("1507", "EQ3 FREQ",
425 () =>
426 {
427 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(1500, 3200, 100)
428 .Select(i => i.ToString()));
429 }, "OFF");
430  
431 AddMenuItem("1508", "EQ3 LEVEL", () => { return Mathematics.GenerateRange(-20, 10); }, 5);
432  
433 AddMenuItem("1509", "EQ3 BWTH", () => { return Mathematics.GenerateRange(1, 10); }, 10);
434  
435 AddMenuItem("1510", "P-EQ1 FREQ",
436 () =>
437 {
438 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 700, 100)
439 .Select(i => i.ToString()));
440 }, "200");
441  
442 AddMenuItem("1511", "P-EQ1 LEVEL", () => { return Mathematics.GenerateRange(-20, 10); });
443  
444 AddMenuItem("1512", "P-EQ1 BWTH", () => { return Mathematics.GenerateRange(1, 10); }, 2);
445  
446 AddMenuItem("1513", "P-EQ2 FREQ",
447 () =>
448 {
449 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 1500, 100)
450 .Select(i => i.ToString()));
451 }, "800");
452  
453 AddMenuItem("1514", "P-EQ2 LEVEL", () => { return Mathematics.GenerateRange(-20, 10); });
454  
455 AddMenuItem("1515", "P-EQ2 BWTH", () => { return Mathematics.GenerateRange(1, 10); }, 1);
456  
457 AddMenuItem("1516", "P-EQ3 FREQ",
458 () =>
459 {
460 return new[] { "OFF" }.Concat(Mathematics.GenerateRange(1500, 3200, 100)
461 .Select(i => i.ToString()));
462 }, "2100");
463  
464 AddMenuItem("1517", "P-EQ3 LEVEL", () => { return Mathematics.GenerateRange(-20, 10); });
465  
466 AddMenuItem("1518", "P-EQ3 BWTH", () => { return Mathematics.GenerateRange(1, 10); }, 1);
467  
468 AddMenuItem("1601", "HF SSB PWR", () => { return Mathematics.GenerateRange(5, 100); }, 100);
469  
470 AddMenuItem("1602", "HF AM PWR", () => { return Mathematics.GenerateRange(5, 40); }, 40);
471  
472 AddMenuItem("1603", "HF PWR", () => { return Mathematics.GenerateRange(5, 100); }, 100);
473  
474 AddMenuItem("1604", "50M SSB PWR", () => { return Mathematics.GenerateRange(5, 100); }, 100);
475  
476 AddMenuItem("1605", "50M AM PWR", () => { return Mathematics.GenerateRange(5, 40); }, 40);
477  
478 AddMenuItem("1606", "50M PWR", () => { return Mathematics.GenerateRange(5, 100); }, 100);
479  
480 AddMenuItem("1607", "SSB MIC GAIN", () => { return Mathematics.GenerateRange(5, 100); }, 50);
481  
482 AddMenuItem("1608", "AM MIC GAIN", () => { return Mathematics.GenerateRange(5, 100); }, 50);
483  
484 AddMenuItem("1609", "FM MIC GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
485  
486 AddMenuItem("1610", "DATA MIC GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
487  
488 AddMenuItem("1611", "SSB DATA GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
489  
490 AddMenuItem("1612", "AM DATA GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
491  
492 AddMenuItem("1613", "FM DATA GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
493  
494 AddMenuItem("1614", "DATA DATA GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
495  
496 AddMenuItem("1615", "TUNER SELECT", () => { return new[] { "OFF", "EXTERNAL", "ATAS", "LAMP" }; },
497 "OFF");
498  
499 AddMenuItem("1616", "VOX SELECT", () => { return new[] { "MIC", "DATA" }; }, "MIC");
500  
501 AddMenuItem("1617", "VOX GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
502  
503 AddMenuItem("1618", "VOX DELAY", () => { return Mathematics.GenerateRange(30, 3000, 10); }, 1000);
504  
505 AddMenuItem("1619", "ANTI VOX GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
506  
507 AddMenuItem("1620", "DATA VOX GAIN", () => { return Mathematics.GenerateRange(0, 100); }, 50);
508  
509 AddMenuItem("1621", "DATA VOX DELAY", () => { return Mathematics.GenerateRange(30, 3000); }, 100);
510  
511 AddMenuItem("1622", "ANTI DVOX GAIN", () => { return Mathematics.GenerateRange(0, 100); });
512  
513 AddMenuItem("1623", "EMERGENCY FREQ", () => { return new[] { "DISABLE", "ENABLE" }; }, "DISABLE");
514  
515 break;
516 }
517  
518 _readCancellationTokenSource = new CancellationTokenSource();
519 _readLinkedCancellationTokenSource =
520 CancellationTokenSource.CreateLinkedTokenSource(new[]
521 { _cancellationTokenSource.Token, _cancellationToken });
522  
523 _readMenuTask = ReadMenu(_readCancellationTokenSource.Token);
524 }
525  
526 private async Task WriteMenu(CancellationToken cancellationToken)
527 {
528 var rows = GetAllDataGridViewRows(dataGridView1);
529  
530 if (!rows.Any()) return;
531  
532 var list = rows.ToList();
533  
534 var count = list.Count;
535  
536 toolStripProgressBar1.Minimum = 0;
537 toolStripProgressBar1.Maximum = count;
538 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
539  
540 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
541 {
542 try
543 {
544 switch (rowProgress)
545 {
546 case DataGridViewRowProgressSuccess<int> rowProgressSuccess:
547 dataGridView1.Rows[rowProgressSuccess.Row.Index].DefaultCellStyle.BackColor =
548 DefaultBackColor;
549 toolStripStatusLabel1.Text = $"{Resources.Wrote_menu} {rowProgressSuccess.Data:0000}";
550 break;
551 case DataGridViewRowProgressFailure<int> rowProgressFailure:
552 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_read_menu}");
553 dataGridView1.Rows[rowProgressFailure.Row.Index].DefaultCellStyle.BackColor = Color.Red;
554  
555 toolStripStatusLabel1.Text = $"{Resources.Could_not_write_menu} {rowProgressFailure.Data:0000}";
556 break;
557 }
558  
559 toolStripProgressBar1.Increment(1);
560 statusStrip1.Update();
561 }
562 catch (Exception exception)
563 {
564 Log.Error(exception, Resources.Unexpected_error_while_reading_memory_bank);
565 }
566 });
567  
568 await Task.Run(() => WriteMenu(list, progress, cancellationToken), cancellationToken);
569  
570 if (!_cancellationToken.IsCancellationRequested)
571 {
572 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
573 toolStripStatusLabel1.Text = "Done.";
574 }
575 }
576  
577 private async Task WriteMenu(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress,
578 CancellationToken cancellationToken)
579 {
580 var count = rows.Count;
581  
582 for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i)
583 {
584 if (!int.TryParse($"{rows[i].Cells["IndexColumn"].Value}", out var menu))
585 {
586 continue;
587 }
588  
589 try
590 {
591 var value = $"{rows[i].Cells["ValueColumn"].Value}";
592 int parameter = 0;
593 switch (menu)
594 {
595 case 205:
596 parameter = Array.IndexOf(new[] { "OFF", "0.5", "1.0", "2.0" }, value);
597 break;
598 case 508:
599 case 509:
600 case 510:
601 case 511:
602 case 512:
603 case 515:
604 case 1623:
605 case 206:
606 parameter = Array.IndexOf(new[] { "DISABLE", "ENABLE" }, value);
607 break;
608 case 207:
609 parameter = Array.IndexOf(new[] { "UPPER", "LOWER" }, value);
610 break;
611 case 401:
612 parameter = Array.IndexOf(new[] { "OFF", "BUG", "ELEKEY-A", "ELEKEY-B", "ELEKEY-Y", "ACS" },
613 value);
614 break;
615 case 1006:
616 case 1007:
617 case 402:
618 parameter = Array.IndexOf(new[] { "NOR", "REV" }, value);
619 break;
620 case 403:
621 var list = new List<string>();
622 for (var j = 2.0; j <= 4.5; j += 0.1)
623 {
624 var v = $"{(decimal)j:f1}";
625 list.Add(v);
626 }
627  
628 parameter = list.IndexOf(value);
629 break;
630 case 404:
631 parameter = Array.IndexOf(
632 new[] { "OFF" }.Concat(Mathematics.GenerateRange(1, 690).Select(o => o.ToString()))
633 .ToArray(), value);
634 break;
635 case 405:
636 parameter = Array.IndexOf(new[] { "1290", "AUNO", "AUNT", "A2NO", "A2NT", "12NO", "12NT" },
637 value);
638 break;
639 case 407:
640 case 408:
641 case 409:
642 case 410:
643 case 411:
644 parameter = Array.IndexOf(new[] { "TEXT", "MESSAGE" }, value);
645 break;
646 case 501:
647 parameter = Array.IndexOf(new[] { 1, 3, 10 }, value);
648 break;
649 case 502:
650 parameter = Array.IndexOf(new[] { 10, 30, 50 }, value);
651 break;
652 case 505:
653 parameter = Array.IndexOf(new[] { "RF", "SQL" }, value);
654 break;
655 case 506:
656 parameter = Array.IndexOf(new[] { 4800, 9600, 19200, 38400 }, value);
657 break;
658 case 507:
659 parameter = Array.IndexOf(new[] { 10, 100, 1000, 3000 }, value);
660 break;
661 case 513:
662 parameter = Array.IndexOf(Mathematics.GenerateRange(-20, 20).ToArray(), value);
663 break;
664 case 514:
665 parameter = Array.IndexOf(
666 new[] { "OFF" }.Concat(Mathematics.GenerateRange(1, 30).Select(o => o.ToString()))
667 .ToArray(),
668 value);
669 break;
670 case 516:
671 parameter = Array.IndexOf(new[] { "PAUSE", "TIME" }, value);
672 break;
673 case 517:
674 parameter = Array.IndexOf(Mathematics.GenerateRange(-25, 25).ToArray(), value);
675 break;
676 case 518:
677 parameter = Array.IndexOf(new[] { "RX", "TX", "TRX" }, value);
678 break;
679 case 519:
680 parameter = Array.IndexOf(new[] { "OFF", "1", "2", "4", "6", "8", "10", "12" }, value);
681 break;
682 case 520:
683 parameter = Array.IndexOf(new[] { "NORMAL", "CONTEST" }, value);
684 break;
685 case 601:
686 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
687 .Select(o => o.ToString())).ToArray(), value);
688 break;
689 case 1102:
690 case 1104:
691 case 1002:
692 case 1004:
693 case 806:
694 case 808:
695 case 704:
696 case 702:
697 case 604:
698 case 602:
699 parameter = Array.IndexOf(new[] { 6, 18 }, value);
700 break;
701 case 603:
702 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
703 .Select(o => o.ToString())).ToArray(), value);
704 break;
705 case 1105:
706 case 901:
707 case 809:
708 case 605:
709 parameter = Array.IndexOf(new[] { "MIC", "REAR" }, value);
710 break;
711 case 1108:
712 case 903:
713 case 810:
714 case 607:
715 parameter = Array.IndexOf(new[] { "DAKY", "RTS", "DTR" }, value);
716 break;
717 case 701:
718 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
719 .Select(o => o.ToString())).ToArray(), value);
720 break;
721 case 703:
722 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
723 .Select(o => o.ToString())).ToArray(), value);
724 break;
725 case 706:
726 parameter = Array.IndexOf(new[] { "OFF", "50M", "ON" }, value);
727 break;
728 case 1107:
729 case 707:
730 parameter = Array.IndexOf(new[] { "USB", "LSB", "AUTO" }, value);
731 break;
732 case 708:
733 parameter = Array.IndexOf(new[] { "SEMI", "FULL" }, value);
734 break;
735 case 709:
736 parameter = Array.IndexOf(Mathematics.GenerateRange(30, 3000, 10).ToArray(), value);
737 break;
738 case 710:
739 parameter = Array.IndexOf(new[] { string.Empty, "2", "4" }, value);
740 break;
741 case 711:
742 parameter = Array.IndexOf(new[] { "FREQ", "PITCH" }, value);
743 break;
744 case 712:
745 parameter = Array.IndexOf(new[] { "OFF", "DAKY", "RTS", "DTR" }, value);
746 break;
747 case 713:
748 parameter = Array.IndexOf(new[] { 15, 20, 25, 30 }, value);
749 break;
750 case 801:
751 parameter = Array.IndexOf(new[] { "PSK", "OTHERS" }, value);
752 break;
753 case 802:
754 parameter = Array.IndexOf(new[] { 1000, 1500, 2000 }, value);
755 break;
756 case 803:
757 parameter = Array.IndexOf(Mathematics.GenerateRange(-3000, 3000, 10).ToArray(), value);
758 break;
759 case 804:
760 parameter = Array.IndexOf(Mathematics.GenerateRange(-3000, 3000, 10).ToArray(), value);
761 break;
762 case 805:
763 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
764 .Select(o => o.ToString())).ToArray(), value);
765 break;
766 case 807:
767 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
768 .Select(o => o.ToString())).ToArray(), value);
769 break;
770 case 1011:
771 case 812:
772 parameter = Array.IndexOf(new[] { "USB", "LSB" }, value);
773 break;
774 case 904:
775 parameter = Array.IndexOf(Mathematics.GenerateRange(0, 1000, 10).ToArray(), value);
776 break;
777 case 905:
778 parameter = Array.IndexOf(Mathematics.GenerateRange(0, 4000, 10).ToArray(), value);
779 break;
780 case 906:
781 parameter = Array.IndexOf(new[] { "Tn-Rn", "Tn-Riv", "Tiv-Rn", "Tiv-Riv" }, value);
782 break;
783 case 1001:
784 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
785 .Select(o => o.ToString())).ToArray(), value);
786 break;
787 case 1003:
788 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
789 .Select(o => o.ToString())).ToArray(), value);
790 break;
791 case 1005:
792 parameter = Array.IndexOf(new[] { "SHIFT", "DTR", "RTS" }, value);
793 break;
794 case 1009:
795 parameter = Array.IndexOf(new[] { 170, 200, 425, 850 }, value);
796 break;
797 case 1010:
798 parameter = Array.IndexOf(new[] { 1275, 2125 }, value);
799 break;
800 case 1101:
801 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 1000, 50)
802 .Select(o => o.ToString())).ToArray(), value);
803 break;
804 case 1103:
805 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 4000, 50)
806 .Select(o => o.ToString())).ToArray(), value);
807 break;
808 case 1109:
809 parameter = Array.IndexOf(
810 new[] { "100-3000", "100-2900", "200-2800", "300-2700", "400-2600" }, value);
811 break;
812 case 1201:
813 parameter = Array.IndexOf(new[] { "NARROW", "MEDIUM", "WIDE" }, value);
814 break;
815 case 1202:
816 parameter = Array.IndexOf(Mathematics.GenerateRange(-40, 20).ToArray(), value);
817 break;
818 case 1204:
819 parameter = Array.IndexOf(new[] { "NARROW", "WIDE" }, value);
820 break;
821 case 1301:
822 parameter = Array.IndexOf(new[] { "OFF", "3", "5", "10" }, value);
823 break;
824 case 1302:
825 parameter = Array.IndexOf(new[] { 37.5, 75, 150, 375, 750 }, value);
826 break;
827 case 1401:
828 parameter = Array.IndexOf(new[] { 50, 100, 500 }, value);
829 break;
830 case 1402:
831 parameter = Array.IndexOf(new[] { 2, 5, 10 }, value);
832 break;
833 case 1403:
834 case 1404:
835 parameter = Array.IndexOf(new[] { 2, 5, 10 }, value);
836 break;
837 case 1405:
838 parameter = Array.IndexOf(new[] { 2, 5, 10 }, value);
839 break;
840 case 1406:
841 parameter = Array.IndexOf(new[] { 2.5, 5, 2.9, 10, 12.5, 25 }, value);
842 break;
843 case 1407:
844 parameter = Array.IndexOf(new[] { 5, 6.25, 10, 12.5, 15, 20, 25 }, value);
845 break;
846 case 1501:
847 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 700, 100)
848 .Select(o => o.ToString())).ToArray(), value);
849 break;
850 case 1504:
851 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 1500, 100)
852 .Select(o => o.ToString())).ToArray(), value);
853 break;
854 case 1514:
855 case 1511:
856 case 1508:
857 case 1505:
858 parameter = Array.IndexOf(Mathematics.GenerateRange(-20, 10).ToArray(), value);
859 break;
860 case 1507:
861 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(1500, 3200, 100)
862 .Select(o => o.ToString())).ToArray(), value);
863 break;
864 case 1510:
865 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(100, 700, 100)
866 .Select(o => o.ToString())).ToArray(), value);
867 break;
868 case 1513:
869 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(700, 1500, 100)
870 .Select(o => o.ToString())).ToArray(), value);
871 break;
872 case 1515:
873 parameter = Array.IndexOf(Mathematics.GenerateRange(1, 10).ToArray(), value);
874 break;
875 case 1516:
876 parameter = Array.IndexOf(new[] { "OFF" }.Concat(Mathematics.GenerateRange(1500, 3200, 100)
877 .Select(o => o.ToString())).ToArray(), value);
878 break;
879 case 1614:
880 case 1613:
881 case 1612:
882 case 1611:
883 case 1610:
884 case 1609:
885 case 1608:
886 case 1607:
887 case 1606:
888 case 1603:
889 case 1604:
890 case 1601:
891 parameter = Array.IndexOf(Mathematics.GenerateRange(5, 100).ToArray(), value);
892 break;
893 case 1605:
894 case 1602:
895 parameter = Array.IndexOf(Mathematics.GenerateRange(5, 40).ToArray(), value);
896 break;
897 case 1615:
898 parameter = Array.IndexOf(new[] { "OFF", "EXTERNAL", "ATAS", "LAMP" }, value);
899 break;
900 case 1616:
901 parameter = Array.IndexOf(new[] { "MIC", "DATA" }, value);
902 break;
903 case 1618:
904 parameter = Array.IndexOf(Mathematics.GenerateRange(30, 3000, 10).ToArray(), value);
905 break;
906 case 1622:
907 case 1620:
908 case 1619:
909 parameter = Array.IndexOf(Mathematics.GenerateRange(0, 100).ToArray(), value);
910 break;
911 case 1621:
912 parameter = Array.IndexOf(Mathematics.GenerateRange(30, 3000).ToArray(), value);
913 break;
914 default:
915 if (!int.TryParse(value, out parameter))
916 {
917 throw new ArgumentException(Resources.Invalid_menu_item);
918 }
919  
920 break;
921 }
922  
923 await _catAssemblies.CatWriteAsync<int>("EX", new object[] { menu, parameter }, cancellationToken);
924  
925 progress.Report(new DataGridViewRowProgressSuccess<int>(rows[i], i, menu));
926 }
927 catch (UnexpectedRadioResponseException exception)
928 {
929 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception, menu));
930 }
931 catch (Exception exception)
932 {
933 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception, menu));
934 }
935 }
936 }
937  
938 private async Task ReadMenu(CancellationToken cancellationToken)
939 {
940 var rows = GetAllDataGridViewRows(dataGridView1);
941  
942 if (!rows.Any()) return;
943  
944 var list = rows.ToList();
945  
946 var count = list.Count;
947  
948 toolStripProgressBar1.Minimum = 0;
949 toolStripProgressBar1.Maximum = count;
950 toolStripProgressBar1.Value = toolStripProgressBar1.Minimum;
951  
952 var progress = new Progress<DataGridViewRowProgress>(rowProgress =>
953 {
954 try
955 {
956 switch (rowProgress)
957 {
958 case DataGridViewRowProgressSuccess<int> rowProgressSuccess:
959 dataGridView1.Rows[rowProgressSuccess.Row.Index].DefaultCellStyle.BackColor =
960 DefaultBackColor;
961  
962 if (!int.TryParse(
963 $"{dataGridView1.Rows[rowProgressSuccess.Row.Index].Cells["IndexColumn"].Value}",
964 out var menu)) throw new ArgumentException(Resources.Invalid_menu_item);
965  
966 switch (Configuration.Radio)
967 {
968 case "Yaesu FT-891":
969 switch (menu)
970 {
971 case 403:
972 var v403 = $"{rowProgressSuccess.Data}".ToCharArray();
973 dataGridView1.Rows[rowProgressSuccess.Row.Index].Cells["ValueColumn"]
974 .Value = $"{v403[0]}.{v403[1]}";
975 break;
976 case 205:
977 case 206:
978 case 207:
979 case 401:
980 case 402:
981 case 404:
982 case 405:
983 case 407:
984 case 408:
985 case 409:
986 case 410:
987 case 411:
988 case 501:
989 case 502:
990 case 505:
991 case 506:
992 case 507:
993 case 508:
994 case 509:
995 case 510:
996 case 511:
997 case 512:
998 case 514:
999 case 515:
1000 case 516:
1001 case 518:
1002 case 519:
1003 case 520:
1004 case 601:
1005 case 602:
1006 case 603:
1007 case 605:
1008 case 607:
1009 case 701:
1010 case 702:
1011 case 703:
1012 case 704:
1013 case 706:
1014 case 707:
1015 case 708:
1016 case 710:
1017 case 711:
1018 case 712:
1019 case 713:
1020 case 801:
1021 case 802:
1022 case 805:
1023 case 806:
1024 case 807:
1025 case 808:
1026 case 809:
1027 case 810:
1028 case 811:
1029 case 812:
1030 case 901:
1031 case 902:
1032 case 903:
1033 case 906:
1034 case 1001:
1035 case 1002:
1036 case 1003:
1037 case 1004:
1038 case 1005:
1039 case 1006:
1040 case 1007:
1041 case 1009:
1042 case 1010:
1043 case 1011:
1044 case 1101:
1045 case 1102:
1046 case 1103:
1047 case 1104:
1048 case 1105:
1049 case 1107:
1050 case 1108:
1051 case 1109:
1052 case 1201:
1053 case 1204:
1054 case 1301:
1055 case 1302:
1056 case 1401:
1057 case 1402:
1058 case 1403:
1059 case 1404:
1060 case 1405:
1061 case 1406:
1062 case 1407:
1063 case 1501:
1064 case 1504:
1065 case 1507:
1066 case 1510:
1067 case 1513:
1068 case 1516:
1069 case 1615:
1070 case 1616:
1071 case 1623:
1072 var value = (dataGridView1.Rows[rowProgressSuccess.Row.Index]
1073 .Cells["ValueColumn"] as DataGridViewComboBoxCell)
1074 .Items[rowProgressSuccess.Data];
1075 dataGridView1.Rows[rowProgressSuccess.Row.Index].Cells["ValueColumn"]
1076 .Value = $"{value}";
1077 break;
1078 default:
1079 dataGridView1.Rows[rowProgressSuccess.Row.Index].Cells["ValueColumn"]
1080 .Value = $"{rowProgressSuccess.Data}";
1081 break;
1082 }
1083  
1084 break;
1085 }
1086  
1087 toolStripStatusLabel1.Text = $"{Resources.Read_menu} {menu:0000}";
1088 break;
1089 case DataGridViewRowProgressFailure<int> rowProgressFailure:
1090 Log.Error(rowProgressFailure.Exception, $"{Resources.Could_not_read_menu}");
1091 dataGridView1.Rows[rowProgressFailure.Row.Index].DefaultCellStyle.BackColor = Color.Red;
1092  
1093 toolStripStatusLabel1.Text = $"{Resources.Could_not_read_menu} {rowProgressFailure.Data:0000}";
1094 break;
1095 }
1096  
1097 toolStripProgressBar1.Increment(1);
1098 statusStrip1.Update();
1099 }
1100 catch (Exception exception)
1101 {
1102 Log.Error(exception, Resources.Unexpected_error_while_reading_memory_bank);
1103 }
1104 });
1105  
1106 await Task.Run(() => ReadMenu(list, progress, cancellationToken), cancellationToken);
1107  
1108 if (!_cancellationToken.IsCancellationRequested)
1109 {
1110 try
1111 {
1112 toolStripProgressBar1.Value = toolStripProgressBar1.Maximum;
1113 toolStripStatusLabel1.Text = "Done.";
1114 }
1115 catch(NullReferenceException ex)
1116 {
1117 // toolStripProgressBar1 disposed on close
1118 }
1119 }
1120 }
1121  
1122 private async Task ReadMenu(IReadOnlyList<DataGridViewRow> rows, IProgress<DataGridViewRowProgress> progress,
1123 CancellationToken cancellationToken)
1124 {
1125 var count = rows.Count;
1126  
1127 for (var i = 0; i < count && !cancellationToken.IsCancellationRequested; ++i)
1128 {
1129 if (!int.TryParse($"{rows[i].Cells["IndexColumn"].Value}", out var menu))
1130 {
1131 continue;
1132 }
1133  
1134 try
1135 {
1136 var result = await _catAssemblies.CatReadAsync<int>("EX", new object[] { menu }, cancellationToken);
1137  
1138 progress.Report(new DataGridViewRowProgressSuccess<int>(rows[i], i, result));
1139 }
1140 catch (UnexpectedRadioResponseException exception)
1141 {
1142 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception, menu));
1143 }
1144 catch (Exception exception)
1145 {
1146 progress.Report(new DataGridViewRowProgressFailure<int>(rows[i], i, exception, menu));
1147 }
1148 }
1149 }
1150  
1151 //Mix two colors
1152 //Example: Steps=10 & Position=4 makes Color2 mix 40% into Color1
1153 /// <summary>
1154 /// Mix two colors.
1155 /// </summary>
1156 /// <param name="color1"></param>
1157 /// <param name="color2"></param>
1158 /// <param name="steps"></param>
1159 /// <param name="position"></param>
1160 /// <example>Steps=10 & Positon=4 makes Color2 mix 40% into Color1</example>
1161 /// <remarks>https://stackoverflow.com/questions/38337849/transparent-selectionbackcolor-for-datagridview-cell</remarks>
1162 /// <returns></returns>
1163 public static Color MixColor(Color color1, Color color2, int steps, int position)
1164 {
1165 if (position <= 0 || steps <= 1) return color1;
1166 if (position >= steps) return color2;
1167 return Color.FromArgb(
1168 color1.R + (color2.R - color1.R) / steps * position,
1169 color1.G + (color2.G - color1.G) / steps * position,
1170 color1.B + (color2.B - color1.B) / steps * position
1171 );
1172 }
1173  
1174 private static IEnumerable<DataGridViewRow> GetSelectedDataGridViewRows(DataGridView dataGridView)
1175 {
1176 return dataGridView.SelectedRows.OfType<DataGridViewRow>().OrderBy(row => row.Index);
1177 }
1178  
1179 private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
1180 {
1181  
1182 }
1183  
1184 private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
1185 {
1186 var dataGridView = (DataGridView)sender;
1187  
1188 dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
1189 }
1190  
1191 private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
1192 {
1193 }
1194  
1195 private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
1196 {
1197  
1198 }
1199  
1200 private void DataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
1201 {
1202  
1203 }
1204  
1205 private void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
1206 {
1207  
1208 }
1209  
1210 private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
1211 {
1212 // @(-.-)@ -(o.o)- @(o_o)@
1213 }
1214  
1215 private static List<DataGridViewRow> GetAllDataGridViewRows(DataGridView dataGridView)
1216 {
1217 return dataGridView.Rows.OfType<DataGridViewRow>().ToList();
1218 }
1219  
1220 private void TextBox1_TextChanged(object sender, EventArgs e)
1221 {
1222 _searchTextBoxChangedContinuation.Schedule(TimeSpan.FromSeconds(1), () =>
1223 {
1224 textBox1.InvokeIfRequired(textBox =>
1225 {
1226 var search = textBox.Text;
1227  
1228 dataGridView1.InvokeIfRequired(dataGridView =>
1229 {
1230 foreach (var row in GetAllDataGridViewRows(dataGridView))
1231 {
1232 if (row.Cells["FunctionColumn"].Value == null) continue;
1233  
1234 switch (((string)row.Cells["FunctionColumn"].Value).IndexOf(search,
1235 StringComparison.OrdinalIgnoreCase))
1236 {
1237 case -1:
1238 row.Visible = false;
1239 break;
1240 default:
1241 row.Visible = true;
1242 break;
1243 }
1244 }
1245 });
1246 });
1247 }, _cancellationToken);
1248 }
1249  
1250 private async void button1_Click(object sender, EventArgs e)
1251 {
1252 if (_readLinkedCancellationTokenSource != null)
1253 {
1254 _readLinkedCancellationTokenSource.Cancel();
1255 _readLinkedCancellationTokenSource = null;
1256 }
1257  
1258 if (_readMenuTask != null)
1259 {
1260 await _readMenuTask;
1261 _readMenuTask = null;
1262 }
1263  
1264 _readCancellationTokenSource = new CancellationTokenSource();
1265 _readLinkedCancellationTokenSource =
1266 CancellationTokenSource.CreateLinkedTokenSource(new[]
1267 { _cancellationTokenSource.Token, _cancellationToken });
1268  
1269 _readMenuTask = ReadMenu(_readLinkedCancellationTokenSource.Token);
1270 }
1271  
1272 private void DataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
1273 {
1274 var dataGridView = sender as DataGridView;
1275 foreach (DataGridViewCell cell in dataGridView.Rows[e.RowIndex].Cells)
1276 {
1277 if (cell.Selected == false) continue;
1278 var bgColorCell = Color.White;
1279 if (cell.Style.BackColor != Color.Empty)
1280 bgColorCell = cell.Style.BackColor;
1281 else if (cell.InheritedStyle.BackColor != Color.Empty) bgColorCell = cell.InheritedStyle.BackColor;
1282 cell.Style.SelectionBackColor = MixColor(bgColorCell, Color.FromArgb(0, 150, 255), 10, 4);
1283 }
1284 }
1285  
1286 private async void button2_Click(object sender, EventArgs e)
1287 {
1288 if (_writeLinkedCancellationTokenSource != null)
1289 {
1290 _writeLinkedCancellationTokenSource.Cancel();
1291 _writeLinkedCancellationTokenSource = null;
1292 }
1293  
1294 if (_writeMenuTask != null)
1295 {
1296 await _writeMenuTask;
1297 _writeMenuTask = null;
1298 }
1299  
1300 _writeCancellationTokenSource = new CancellationTokenSource();
1301 _writeLinkedCancellationTokenSource =
1302 CancellationTokenSource.CreateLinkedTokenSource(new[]
1303 { _cancellationTokenSource.Token, _cancellationToken });
1304  
1305 _writeMenuTask = WriteMenu(_writeLinkedCancellationTokenSource.Token);
1306 }
1307 }
1308 }