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