using GenesisCordonelInterface.API; using GenesisCordonelInterface.UI; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug { public partial class MeterBatchConfigPanel : UserControl { private readonly InterfaceGCIToLaatzen _api; private MainForm _mainform; private MainView _mainView; public Grid.MeterGridManager _gridManager; public event Action SelectedSlotsChanged; private bool isRefreshing; private List comPorts = new List(); public MeterBatchConfigPanel(MainForm mainform, MainView mainview) { _mainform = mainform; _mainView = mainview; _api = _mainView._gciApi._innerMeterAPI; InitializeComponent(); //GRID RefreshComPorts(); _gridManager = new Grid.MeterGridManager(grid); _gridManager.Init(comPorts); grid.KeyDown += grid_KeyDown; _mainView._gciApi.MeterBatchStatusChanged += Api_MeterBatchStatusChanged; //global event of table UpdateGrid(_api.GetMeterBatchDebugStatuses()); } #region INIT // ---------------------------------------------------- private void InitializeGridColumns() { grid.Columns.Clear(); grid.Columns.Add("Slot", "Slot"); grid.Columns.Add(new DataGridViewCheckBoxColumn { Name = "Selected", HeaderText = "Selected" }); grid.Columns.Add("PcbId", "PcbId"); grid.Columns.Add(new DataGridViewCheckBoxColumn { Name = "IsLoggedOn", HeaderText = "IsLoggedOn" }); grid.Columns.Add(CreateComPortColumn("RequestPort", "RequestPort")); grid.Columns.Add(CreateComPortColumn("StreamingPort", "StreamingPort")); grid.Columns.Add(CreateButtonColumn("DetectRequest", "DetectRequest", "...")); grid.Columns.Add(CreateButtonColumn("DetectStreaming", "DetectStreaming", "...")); grid.Columns.Add("FwVersion", "FwVersion"); grid.Columns.Add("InterfaceVersion", "InterfaceVersion"); foreach (DataGridViewColumn col in grid.Columns) { col.ReadOnly = col.Name != "Selected" && col.Name != "RequestPort" && col.Name != "StreamingPort" && col.Name != "DetectRequest" && col.Name != "DetectStreaming"; } EnableDoubleBuffering(grid); } private DataGridViewComboBoxColumn CreateComPortColumn(string name, string headerText) { return new DataGridViewComboBoxColumn { Name = name, HeaderText = headerText, DataSource = new List(comPorts), FlatStyle = FlatStyle.Flat, DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton }; } private DataGridViewButtonColumn CreateButtonColumn(string name, string headerText, string text) { return new DataGridViewButtonColumn { Name = name, HeaderText = headerText, Text = text, UseColumnTextForButtonValue = true }; } private void RefreshComPorts() { comPorts = SerialPort.GetPortNames() .OrderBy(NaturalComPortOrder) .ToList(); if (!comPorts.Contains("")) comPorts.Insert(0, ""); } // ---------------------------------------------------- #endregion #region REFRESH EVENT DRIVEN // ---------------------------------------------------- private void Api_MeterBatchStatusChanged(List data) { if (IsDisposed) return; if (InvokeRequired) { BeginInvoke(new Action(() => UpdateGrid(data))); return; } UpdateGrid(data); } private void UpdateGrid(List data) { isRefreshing = true; try { if (data == null || data.Count == 0) { _gridManager.ClearSlots(); return; } foreach (var meter in data) { EnsurePortValueExists(meter.RequestPort); EnsurePortValueExists(meter.StreamingPort); } _gridManager.Update(data); } finally { isRefreshing = false; } } // ---------------------------------------------------- #endregion #region COM PORT HELPERS // ---------------------------------------------------- private void UpdateComPortColumnItems(string columnName) { var col = grid.Columns[columnName] as DataGridViewComboBoxColumn; if (col == null) return; col.DataSource = null; col.DataSource = new List(comPorts); } private void EnsurePortValueExists(string port) { if (string.IsNullOrWhiteSpace(port)) return; if (comPorts.Contains(port)) return; comPorts.Add(port); comPorts = comPorts.OrderBy(NaturalComPortOrder).ToList(); if (!comPorts.Contains("")) comPorts.Insert(0, ""); _gridManager.UpdateComPortItems(comPorts); } private static int NaturalComPortOrder(string port) { if (string.IsNullOrWhiteSpace(port)) return 0; string number = new string(port.Where(char.IsDigit).ToArray()); int parsed; if (int.TryParse(number, out parsed)) return parsed; return int.MaxValue; } // ---------------------------------------------------- #endregion #region GRID HELPERS // ---------------------------------------------------- private DataGridViewRow FindOrCreateRow(int slot) { foreach (DataGridViewRow row in grid.Rows) { if (row.Cells["Slot"].Value != null && Convert.ToInt32(row.Cells["Slot"].Value) == slot) { return row; } } int idx = grid.Rows.Add(); var newRow = grid.Rows[idx]; newRow.Cells["Slot"].Value = slot; return newRow; } private void Set(DataGridViewRow row, string col, object value) { if (!grid.Columns.Contains(col)) return; if (value == null) value = ""; var cell = row.Cells[col]; if (!Equals(cell.Value, value)) cell.Value = value; } // ---------------------------------------------------- #endregion #region USER EDIT // ---------------------------------------------------- private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e) { if (grid.IsCurrentCellDirty) grid.CommitEdit(DataGridViewDataErrorContexts.Commit); } private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (isRefreshing) return; if (e.RowIndex < 0) return; string columnName = grid.Columns[e.ColumnIndex].Name; if (columnName != "Selected" && columnName != "RequestPort" && columnName != "StreamingPort") return; int slot = Convert.ToInt32(grid.Rows[e.RowIndex].Cells["Slot"].Value); if (columnName == "Selected") { bool selected = Convert.ToBoolean( grid.Rows[e.RowIndex] .Cells["Selected"] .Value); _api.SetSlotSelected(slot, selected); SelectedSlotsChanged?.Invoke(); return; } string port = Convert.ToString(grid.Rows[e.RowIndex].Cells[columnName].Value); if (columnName == "RequestPort") { //_gciApi.SetSlotRequestPort(slot, port); return; } if (columnName == "StreamingPort") { //_gciApi.SetSlotStreamingPort(slot, port); return; } } private async void grid_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex < 0) return; string columnName = grid.Columns[e.ColumnIndex].Name; if (columnName != "DetectRequest" && columnName != "DetectStreaming") return; int slot = Convert.ToInt32(grid.Rows[e.RowIndex].Cells["Slot"].Value); if (columnName == "DetectRequest") { await DetectRequestPortAsync(slot); return; } if (columnName == "DetectStreaming") { await DetectStreamingPortAsync(slot); return; } } private async Task DetectRequestPortAsync(int slot) { try { grid.Enabled = false; //await _gciApi.DetectRequestPortAsync(slot); //_gciApi.RaiseMeterBatchStatusChanged(); } finally { grid.Enabled = true; } } private async Task DetectStreamingPortAsync(int slot) { try { grid.Enabled = false; //await _gciApi.DetectStreamingPortAsync(slot); //_gciApi.RaiseMeterBatchStatusChanged(); } finally { grid.Enabled = true; } } private void grid_DataError(object sender, DataGridViewDataErrorEventArgs e) { e.ThrowException = false; } // ---------------------------------------------------- #endregion #region PERFORMANCE // ---------------------------------------------------- private void EnableDoubleBuffering(DataGridView dgv) { typeof(DataGridView) .GetProperty( "DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) ?.SetValue(dgv, true, null); } // ---------------------------------------------------- #endregion public void AddEmptySlotRow() { _gridManager.AddEmptySlotRow(); } public bool RemoveSlotRow(int slotId) { return _gridManager.RemoveSlot(slotId); } public List GetGridData() { return _gridManager.GetGridData(); } public List GetSelectedGridData() { return _gridManager.GetSelectedGridData(); } public void ClearSelection() { grid.EndEdit(); foreach (DataGridViewRow row in grid.Rows) { if (row.IsNewRow) continue; if (grid.Columns.Contains("Selected")) { row.Cells["Selected"].Value = false; } } grid.ClearSelection(); if (grid.CurrentCell != null) grid.CurrentCell = null; } private void grid_KeyDown(object sender, KeyEventArgs e) { if (e.Control && e.KeyCode == Keys.V) { PasteFromClipboard(); e.Handled = true; } } private void PasteFromClipboard() { string text = Clipboard.GetText(); if (string.IsNullOrWhiteSpace(text)) return; var lines = text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); int startRow = grid.CurrentCell.RowIndex; int startCol = grid.CurrentCell.ColumnIndex; for (int i = 0; i < lines.Length; i++) { var cells = lines[i].Split('\t'); int rowIndex = startRow + i; if (rowIndex >= grid.Rows.Count) grid.Rows.Add(); for (int j = 0; j < cells.Length; j++) { int colIndex = startCol + j; if (colIndex >= grid.Columns.Count) continue; string columnName = grid.Columns[colIndex].Name; if (columnName == "RequestPort" || columnName == "RequestPortType" || columnName == "StreamingPort") { string value = cells[j]; // 👉 dôležité pre ComboBox EnsurePortValueExists(value); grid.Rows[rowIndex].Cells[colIndex].Value = value; } } } } } }