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