/// /// Copyright (c) 2021 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.Windows.Forms; using log4net; using Common; using Config.Entities; using TBF.Resources; using TBF.BenchControl.Sequences; using System.IO; namespace TBF.BenchControl.TestMethods.S640Communication { public enum CommErr { None = 0, CommFailed, /// 1 HeadDisabledByUser, /// 2 } /// /// (Program.LocalSettings.OptoHeadsEnabled & (1L << ix))) == 0 . . opto head is disabled in configuration /// optoheads[ix] == null . . . . . . . . . . . . . . . . . . . . . opto head is not part of the selected sensors path /// optoHeads[ix].Disabled == true . . . . . . . . . . . . . . . . opto head was disabled by the user /// public partial class S640CommForm : Form, GenericDevices.IHasCompleted { private static readonly ILog log = LogManager.GetLogger(typeof(S640CommForm)); protected static readonly ILog sirtDataLogger = LogManager.GetLogger("SirtData"); public const int UIBoxesCount = 40; public static Color DisabledColor = Color.DarkGray; public static Color OptoOKColor = Color.Green; public static Color OptoNokColor = Color.Red; public const string StartFileName = "Start.pro"; public const string EndFileName = "Ende.pro"; public const string ErrorFileName = "Error.dat"; enum Step { /// Start WatchOptoHeads, SaveStartPro, EnterSNsAndAwaitResponseToStartPro, AwaitResponseToStartPro, /// End EnterSNs, ConfirmSNsAndRadioAddresses, SaveEndePro, AwaitResponseToEndePro, ConfirmError, Idle, } DateTime startTime; int startTimeSec; // Set to 'true' when the form closes public bool Completed { get { return formCompleted; } } bool formCompleted; bool forcedClose; /// Set in the forced close handler /// Number of text boxes for serial numbers public int WaterMetersCount; int textBoxesCount; /// bool[] enabledInConfiguration; Label[] labels; PictureBox[] pictures; TextBox[] messages; TextBox[] serialNumbers; CheckBoxImage[] checkBoxes; int[] ckbIndex; /// Initialized by ShuffleTextBoxes() ... to be used in the future in case of test benches with two lines RegisterReaders.S640Stream.S640Stream[] optoHeads; /// /// Parameters and current state of activities /// DebugMode debugLevel; int optoDataTimeout; string fileExchangePath; int fileExchangeTimeout; bool enterSerialNumbers; ProcParams pPars; /// IList activities; IList tests; /// int currentActivityIx; /// Step step; DateTime savedTimestamp; bool areNewSNsAndRadioAddressesAssigned; System.Windows.Forms.Timer timer; /// /// Used in Step.WatchOptoHeads, initially all zeros /// int[] commOkLoopsCount; /// /// Parameterless constructor (without watermeters, threads) /// public S640CommForm() { InitializeComponent(); labels = new Label[UIBoxesCount] { wmLabel1, wmLabel2, wmLabel3, wmLabel4, wmLabel5, wmLabel6, wmLabel7, wmLabel8, wmLabel9, wmLabel10, wmLabel11, wmLabel12, wmLabel13, wmLabel14, wmLabel15, wmLabel16, wmLabel17, wmLabel18, wmLabel19, wmLabel20, wmLabel21, wmLabel22, wmLabel23, wmLabel24, wmLabel25, wmLabel26, wmLabel27, wmLabel28, wmLabel29, wmLabel30, wmLabel31, wmLabel32, wmLabel33, wmLabel34, wmLabel35, wmLabel36, wmLabel37, wmLabel38, wmLabel39, wmLabel40, }; pictures = new PictureBox[UIBoxesCount] { pictureBox1, pictureBox2, pictureBox3, pictureBox4, pictureBox5, pictureBox6, pictureBox7, pictureBox8, pictureBox9, pictureBox10, pictureBox11, pictureBox12, pictureBox13, pictureBox14, pictureBox15, pictureBox16, pictureBox17, pictureBox18, pictureBox19, pictureBox20, pictureBox21, pictureBox22, pictureBox23, pictureBox24, pictureBox25, pictureBox26, pictureBox27, pictureBox28, pictureBox29, pictureBox30, pictureBox31, pictureBox32, pictureBox33, pictureBox34, pictureBox35, pictureBox36, pictureBox37, pictureBox38, pictureBox39, pictureBox40, }; messages = new TextBox[UIBoxesCount] { fromOptoTextBox1, fromOptoTextBox2, fromOptoTextBox3, fromOptoTextBox4, fromOptoTextBox5, fromOptoTextBox6, fromOptoTextBox7, fromOptoTextBox8, fromOptoTextBox9, fromOptoTextBox10, fromOptoTextBox11, fromOptoTextBox12, fromOptoTextBox13, fromOptoTextBox14, fromOptoTextBox15, fromOptoTextBox16, fromOptoTextBox17, fromOptoTextBox18, fromOptoTextBox19, fromOptoTextBox20, fromOptoTextBox21, fromOptoTextBox22, fromOptoTextBox23, fromOptoTextBox24, fromOptoTextBox25, fromOptoTextBox26, fromOptoTextBox27, fromOptoTextBox28, fromOptoTextBox29, fromOptoTextBox30, fromOptoTextBox31, fromOptoTextBox32, fromOptoTextBox33, fromOptoTextBox34, fromOptoTextBox35, fromOptoTextBox36, fromOptoTextBox37, fromOptoTextBox38, fromOptoTextBox39, fromOptoTextBox40, }; serialNumbers = new TextBox[UIBoxesCount] { textBox1, textBox2, textBox3, textBox4, textBox5, textBox6, textBox7, textBox8, textBox9, textBox10, textBox11, textBox12, textBox13, textBox14, textBox15, textBox16, textBox17, textBox18, textBox19, textBox20, textBox21, textBox22, textBox23, textBox24, textBox25, textBox26, textBox27, textBox28, textBox29, textBox30, textBox31, textBox32, textBox33, textBox34, textBox35, textBox36, textBox37, textBox38, textBox39, textBox40, }; checkBoxes = new CheckBoxImage[UIBoxesCount] { checkBoxImage1, checkBoxImage2, checkBoxImage3, checkBoxImage4, checkBoxImage5, checkBoxImage6, checkBoxImage7, checkBoxImage8, checkBoxImage9, checkBoxImage10, checkBoxImage11, checkBoxImage12, checkBoxImage13, checkBoxImage14, checkBoxImage15, checkBoxImage16, checkBoxImage17, checkBoxImage18, checkBoxImage19, checkBoxImage20, checkBoxImage21, checkBoxImage22, checkBoxImage23, checkBoxImage24, checkBoxImage25, checkBoxImage26, checkBoxImage27, checkBoxImage28, checkBoxImage29, checkBoxImage30, checkBoxImage31, checkBoxImage32, checkBoxImage33, checkBoxImage34, checkBoxImage35, checkBoxImage36, checkBoxImage37, checkBoxImage38, checkBoxImage39, checkBoxImage40, }; ckbIndex = new int[UIBoxesCount]; /// Initialized by ShuffleTextBoxes() ... to be used in the future in case of test benches with two lines } /// /// Constructor for one S640Communication test /// /// Number of text boxes for serial numbers public S640CommForm(S640Activity activity, I640Cfg config, Generic.IProcedureParams procParams, Test test) : this(new List { activity }, config, procParams, new List { test }) { } /// /// Constructor for multiple S640Communication tests /// /// Number of text boxes for serial numbers public S640CommForm(IList activities, I640Cfg config, Generic.IProcedureParams procParams, IList tests) : this() { this.activities = activities; debugLevel = config.DebugLevel; optoDataTimeout = config.OptoDataTimeout; fileExchangePath = string.IsNullOrEmpty(config.FileExchangePath) ? string.Empty : config.FileExchangePath; fileExchangeTimeout = config.FileExchangeTimeout; enterSerialNumbers = config.EnterSerialNumbers; this.tests = tests; this.pPars = procParams as ProcParams; if (activities.Count != tests.Count) { throw new Exception("Something strange: activities.Count != tests.Count"); } if (ProcessData.RegisterReaders.Length != ProcessData.BatchRslts.Batch.WaterMeters.Count) { throw new Exception("Something strange: RegisterReaders.Length != WaterMeters.Count"); } if (activities.Count > 0) { ProcessData.RegisterReaders = StateMachine.GetMetersPath(tests[0]).RegisterReaders; } optoHeads = new RegisterReaders.S640Stream.S640Stream[ProcessData.RegisterReaders.Length]; /// for (int wmPos = 0; wmPos < ProcessData.RegisterReaders.Length; wmPos++) { optoHeads[wmPos] = ProcessData.RegisterReaders[wmPos] as RegisterReaders.S640Stream.S640Stream; } WaterMetersCount = ProcessData.RegisterReaders.Length; ShuffleTextBoxes(WaterMetersCount, ProcessData.LineSize); enabledInConfiguration = new bool[textBoxesCount]; for (int i = 0; i < textBoxesCount; i++) { enabledInConfiguration[i] = (optoHeads[i] != null) && ((Program.LocalSettings.OptoHeadsEnabled & (1L << i)) != 0L); } areNewSNsAndRadioAddressesAssigned = false; formCompleted = false; StartForceCloseHandler(); } /// /// Make sure the layout of labels/text boxes on the screen /// corresponds to the layout of watermeters of the test bench. /// /// Number of watermeters /// Number of watermeters in one line void ShuffleTextBoxes(int wmsCount, int lineSize) { textBoxesCount = UIBoxesCount; /// if (wmsCount < textBoxesCount && lineSize > 0) { int nrLines = (wmsCount + lineSize - 1) / lineSize; int gap = (textBoxesCount - wmsCount) / nrLines; int dest = 0; for (int l = 0; l < nrLines; l++) { for (int i = 0; i < lineSize; i++) { labels[dest] = labels[l * lineSize + l * gap + i]; pictures[dest] = pictures[l * lineSize + l * gap + i]; messages[dest] = messages[l * lineSize + l * gap + i]; serialNumbers[dest] = serialNumbers[l * lineSize + l * gap + i]; checkBoxes[dest] = checkBoxes[l * lineSize + l * gap + i]; ckbIndex[l * lineSize + l * gap + i] = dest; dest++; } } textBoxesCount = wmsCount; } for (int i = 0; i < textBoxesCount; i++) { labels[i].Visible = pictures[i].Visible = messages[i].Visible = checkBoxes[i].Visible = true; if (optoHeads[i] != null) labels[i].Text = (i + 1).ToString(); } /// /// Resize this form to fit enabled controls /// //int xMax = 0; //int yMax = 0; //for (int i = 0; i < textBoxesCount; i++) //{ // if (messages[i].Left + messages[i].Width > xMax) xMax = messages[i].Left + messages[i].Width; // if (messages[i].Top + messages[i].Height > yMax) yMax = messages[i].Top + messages[i].Height; //} /////Width = xMax + 30; //Height = yMax + 50; } private void S640CommForm_Load(object sender, EventArgs e) { Localize(); /// /// Set location and checkbox states to values stored in local settings /// TBF.LocalSettings ls = Program.LocalSettings; Left = (ls.S640CommFormLeft != 0) ? ls.S640CommFormLeft : 150; Top = (ls.S640CommFormTop != 0) ? ls.S640CommFormTop : 150; /// /// Set checkbox states accroding to optoHeads[i].Disabled states /// for (int i = 0; i < textBoxesCount; i++) { if (!enabledInConfiguration[i]) { /// Opto head is disabled in configuration checkBoxes[i].Checked = false; checkBoxes[i].Enabled = false; pictures[i].BackColor = DisabledColor; messages[i].Text = Strings.Opto_head_is_disabled_in_configuration; } else if ((i >= ProcessData.BatchRslts.Batch.WaterMeters.Count) || ProcessData.BatchRslts.Batch.WaterMeters[i] == null || ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled) { /// Opto head was disabled by an operator checkBoxes[i].Checked = false; checkBoxes[i].Enabled = false; pictures[i].BackColor = DisabledColor; messages[i].Text = Strings.Head_was_disabled_by_the_user; } else { /// Opto head is enabled checkBoxes[i].Checked = true; checkBoxes[i].Enabled = true; messages[i].Text = "---"; } /// Reset opto-data indication pictures[i].BackColor = OptoNokColor; messages[i].Enabled = true; if (enterSerialNumbers) { serialNumbers[i].Visible = enabledInConfiguration[i]; serialNumbers[i].Enabled = (activities[currentActivityIx] == S640Activity.End); } } startTimeSec = StateMachine.Time; StartActivity(0); timer = new System.Windows.Forms.Timer(); timer.Interval = 300; // ms timer.Tick += new EventHandler(timer_Tick); timer.Start(); } void Localize() { /// Close/Continue button is localized in other code Text = Strings.Water_Meter_States; retryButton.Text = Strings.RetryBtnText; sampleLabel1.Text = Strings.Optical_head_is_placed_correctly; sampleLabel2.Text = Strings.Missing_opto_pulses; samplePictureBox1.BackColor = OptoOKColor; samplePictureBox2.BackColor = OptoNokColor; } void StartActivity(int acIx) { startTime = DateTime.Now; activityLabel.Text = activities[acIx].ToString(); currentActivityIx = acIx; step = (activities[acIx] == S640Activity.Start) ? Step.WatchOptoHeads : enterSerialNumbers ? Step.EnterSNs : Step.ConfirmSNsAndRadioAddresses; closeButton.Visible = false; retryButton.Visible = false; responseTextBox.Text = string.Empty; if (step == Step.WatchOptoHeads) { /// Start watching optical heads --> reset OK loop counters if (commOkLoopsCount == null || commOkLoopsCount.Length != textBoxesCount) { commOkLoopsCount = new int[textBoxesCount]; } for (int i = 0; i < textBoxesCount; i++) commOkLoopsCount[i] = 0; progressBar1.Visible = (optoDataTimeout != 0); progressBar1.Minimum = 0; progressBar1.Maximum = Math.Max(optoDataTimeout, 1); progressBar1.Value = 0; } TBF.UiBridge.TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 10, 0, 140, 0, 0, 0 }); TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[acIx], Progress.JustStarted)); sirtDataLogger.InfoFormat(""); /// Makes the log more readable when there is a lot of data sirtDataLogger.WarnFormat("Activity = {0}", activities[acIx]); sirtDataLogger.InfoFormat(""); /// Makes the log more readable when there is a lot of data } /// /// Invoked every 0.5 sec. /// void timer_Tick(object sender, EventArgs args) { ///-------------------------------------------------------------------------- if (step == Step.WatchOptoHeads) { long optoHeadsConfig = Program.LocalSettings.OptoHeadsEnabled; bool allOK = true; for (int i = 0; i < textBoxesCount; i++) { if ((optoHeadsConfig & (1L << i)) == 0 || optoHeads[i] == null) { /// Opto head is disabled in configuration checkBoxes[i].Checked = false; checkBoxes[i].Enabled = false; pictures[i].BackColor = DisabledColor; messages[i].Text = Strings.Opto_head_is_disabled_in_configuration; } else if (!checkBoxes[i].Checked) { /// Opto head was disabled by the user pictures[i].BackColor = DisabledColor; } else { /// Opto head is enabled checkBoxes[i].Checked = true; checkBoxes[i].Enabled = true; if (optoHeads[i].PcbNumber == 0) { /// Communication is NOK right now pictures[i].BackColor = OptoNokColor; messages[i].Text = "---"; commOkLoopsCount[i] = 0; allOK = false; } else { /// Communication is OK right now messages[i].Text = string.Format("pcb={0} radio={1}", optoHeads[i].PcbNumber, optoHeads[i].RadioAddress); pictures[i].BackColor = OptoOKColor; /// increment commOkLoopsCount[i] and check its value, considered OK just after 5 repeats commOkLoopsCount[i] = commOkLoopsCount[i] + 1; if (commOkLoopsCount[i] < 5) allOK = false; } } } if (allOK) { log.WarnFormat("allOk"); /// Update water meter properties for (int i = 0; i < textBoxesCount; i++) { if (i < ProcessData.BatchRslts.Batch.WaterMeters.Count && ProcessData.BatchRslts.Batch.WaterMeters[i] != null && !ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled) { if ((optoHeadsConfig & (1L << i)) != 0 && checkBoxes[i].Checked && optoHeads[i] != null) { /// Save PCB Number of the water meter ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNrAux = optoHeads[i].PcbNumber.ToString(); /// PCB number (640) #if ORACLE_DB ProcessData.BatchRslts.Batch.WaterMeters[i].OriRadioAddress = /// Original radio address (640) #endif ProcessData.BatchRslts.Batch.WaterMeters[i].RadioAddress = optoHeads[i].RadioAddress.ToString(); /// New radio address (640) } else { /// Disable the water meter ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled = true; } } checkBoxes[i].Enabled = false; } step = Step.SaveStartPro; } else if (optoDataTimeout != 0 && DateTime.Now - startTime > new TimeSpan(0, 0, optoDataTimeout)) { activityLabel.Text = String.Format("{0}: {1} {2}", Strings.Start, Strings.Optical_heads, Strings.Timeout); log.Error("Start: Optical heads timeout"); step = Step.ConfirmError; } else if (optoDataTimeout != 0) { progressBar1.Value = (int)Math.Round((DateTime.Now - startTime).TotalSeconds); } } ///-------------------------------------------------------------------------- else if (step == Step.SaveStartPro) { activityLabel.Text = string.Format("Start: SIRT Communication"); int count = 0; for (int i = 0; i < textBoxesCount; i++) { if (optoHeads[i] != null && optoHeads[i].PcbNumber != 0 && ProcessData.BatchRslts.Batch.WaterMeters[i] != null) count++; } log.DebugFormat("Saving '{0}' file: {1} water meters found", StartFileName, count); if (debugLevel == DebugMode.Normal) { SaveProFile(Path.Combine(fileExchangePath, StartFileName), S640Activity.Start, optoHeads); } SaveProFile(Path.Combine(Constants.SirtLogDir, string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, StartFileName)), S640Activity.Start, optoHeads); savedTimestamp = DateTime.Now; progressBar1.Visible = (fileExchangeTimeout != 0); progressBar1.Minimum = 0; progressBar1.Maximum = Math.Max(fileExchangeTimeout, 1); progressBar1.Value = 0; for (int i = 0; i < textBoxesCount; i++) { messages[i].Enabled = false; } if (enterSerialNumbers) { for (int i = 0; i < textBoxesCount; i++) { serialNumbers[i].Enabled = true; } serialNumbers[0].Focus(); closeButton.Visible = true; closeButton.Enabled = true; closeButton.Text = Strings.Continue; step = Step.EnterSNsAndAwaitResponseToStartPro; } else { step = Step.AwaitResponseToStartPro; } } ///-------------------------------------------------------------------------- else if (step == Step.EnterSNsAndAwaitResponseToStartPro) { /// Don't do anything, move to the next step in closeButton_Click(...) } ///-------------------------------------------------------------------------- else if (step == Step.AwaitResponseToStartPro) { if (!File.Exists(Path.Combine(fileExchangePath, StartFileName))) { /// File disappeared in time UpdateFirstTestResult(tests); UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[currentActivityIx], Progress.Completed)); step = Step.Idle; NormalClose(); } else if (File.Exists(Path.Combine(fileExchangePath, ErrorFileName))) { /// Error file detected string destination = Path.Combine(Constants.SirtLogDir, string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, ErrorFileName)); File.Move(Path.Combine(fileExchangePath, ErrorFileName), destination); ParseFileAndDisplayErrors(destination); File.Delete(Path.Combine(fileExchangePath, StartFileName)); activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.Start, Strings.Error); step = Step.ConfirmError; } else if (fileExchangeTimeout != 0 && DateTime.Now - savedTimestamp > new TimeSpan(0, 0, fileExchangeTimeout)) { activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.Start, Strings.Timeout); log.Error("Start: SIRT timeout"); step = Step.ConfirmError; } else if (fileExchangeTimeout != 0) { progressBar1.Value = (int)Math.Round((DateTime.Now - savedTimestamp).TotalSeconds); } else { progressBar1.Visible = false; closeButton.Text = Strings.CloseBtnText; closeButton.Visible = true; retryButton.Visible = true; } } ///-------------------------------------------------------------------------- else if (step == Step.EnterSNs) { /// Don't do anything, move to the next step in closeButton_Click(...) } ///-------------------------------------------------------------------------- else if (step == Step.ConfirmSNsAndRadioAddresses) { if (!areNewSNsAndRadioAddressesAssigned) { AssignNewSNsAndRadioAddresses(optoHeads); closeButton.Visible = true; closeButton.Text = Strings.Continue; } } ///-------------------------------------------------------------------------- else if (step == Step.SaveEndePro) { activityLabel.Text = string.Format("End: SIRT Communication"); log.DebugFormat("Saving '{0}' file", EndFileName); if (debugLevel == DebugMode.Normal) { SaveProFile(Path.Combine(fileExchangePath, EndFileName), S640Activity.End, optoHeads); } SaveProFile(Path.Combine(Constants.SirtLogDir, string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, EndFileName)), S640Activity.Start, optoHeads); savedTimestamp = DateTime.Now; progressBar1.Visible = (fileExchangeTimeout != 0); progressBar1.Minimum = 0; progressBar1.Maximum = Math.Max(fileExchangeTimeout, 1); progressBar1.Value = 0; if (ProcessData.OracleDB != null && ProcessData.OrderDetails != null) { int updatedCount = ProcessData.OracleDB.UpdateOrderDetails(ProcessData.OrderDetails); } step = Step.AwaitResponseToEndePro; } ///-------------------------------------------------------------------------- else if (step == Step.AwaitResponseToEndePro) { if (!File.Exists(Path.Combine(fileExchangePath, EndFileName))) { /// File disappeared in time UpdateFirstTestResult(tests); UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[currentActivityIx], Progress.Completed)); step = Step.Idle; NormalClose(); } else if (File.Exists(Path.Combine(fileExchangePath, ErrorFileName))) { /// Error.dat file detected string destination = Path.Combine(Constants.SirtLogDir, string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, ErrorFileName)); File.Move(Path.Combine(fileExchangePath, ErrorFileName), destination); ParseFileAndDisplayErrors(destination); File.Delete(Path.Combine(fileExchangePath, EndFileName)); activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.End, Strings.Error); step = Step.ConfirmError; } else if (fileExchangeTimeout != 0 && DateTime.Now - savedTimestamp > new TimeSpan(0, 0, fileExchangeTimeout)) { activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.End, Strings.Timeout); log.Error("End: SIRT timeout"); step = Step.ConfirmError; } else if (fileExchangeTimeout != 0) { progressBar1.Value = (int)Math.Round((DateTime.Now - savedTimestamp).TotalSeconds); } else { progressBar1.Visible = false; closeButton.Text = Strings.CloseBtnText; closeButton.Visible = true; retryButton.Visible = true; } } ///-------------------------------------------------------------------------- else if (step == Step.ConfirmError) { progressBar1.Visible = false; retryButton.Visible = true; closeButton.Visible = true; closeButton.Enabled = true; closeButton.Text = Strings.CloseBtnText; } ///-------------------------------------------------------------------------- else if (step == Step.Idle) { /// Just wait until this form is closed } else { /// Invalid step log.ErrorFormat("Unexpected step: activity = {0} step = {1}", activities[currentActivityIx], step); } } bool AssignNewSNsAndRadioAddresses(RegisterReaders.S640Stream.S640Stream[] optoHeads) { TBF.BenchControl.Output.DB.SensusOracle.OrderDetails ord = ProcessData.OrderDetails; /// if (ProcessData.OracleDB == null || ord == null || !ProcessData.OracleDB.ReadOrderDetails(ref ord)) { return false; } if (ord.CurrentSerialNr < ord.FirstSerialNr) { ord.CurrentSerialNr = ord.FirstSerialNr - 1; } for (int i = 0; i < optoHeads.Length; i++) { int currentSerialNr = (ord.CurrentSerialNr < ord.FirstSerialNr) ? ord.FirstSerialNr : ord.CurrentSerialNr + 1; int currentRadioAddress = (ord.CurrentRadioAddress < ord.FirstRadioAddress) ? ord.FirstRadioAddress : ord.CurrentSerialNr + 1; Results.Entities.WaterMeter wm = ProcessData.BatchRslts.Batch.WaterMeters[i]; if (optoHeads[i] != null && optoHeads[i].PcbNumber != 0 && wm != null) { if (wm.PassedFromTests()) { /// Assign numbers wm.RadioAddress = string.Format("{0}{1}{2}", ord.RadioAddressPrefix, currentRadioAddress.ToString("D9"), ord.RadioAddressSuffix); #if ORACLE_DB wm.AssignedSerialNr = currentSerialNr; string assingedSNStr = currentSerialNr.ToString(string.Format("D{0}", ord.SNLength)); wm.Prefix = ord.Prefix; wm.Suffix = ord.Suffix; wm.CompleteSerialNr = string.Format("{0}{1}{2}", wm.Prefix, assingedSNStr, wm.Suffix); messages[i].Text = string.Format("pcb={0} radio={1}->{2} s/n={3}", wm.SerialNrAux, wm.OriRadioAddress, wm.RadioAddress, assingedSNStr); #endif ord.CurrentSerialNr = currentSerialNr; ord.CurrentRadioAddress = currentRadioAddress; } else { /// Red background messages[i].BackColor = Color.Pink; } } } areNewSNsAndRadioAddressesAssigned = true; return true; } void SaveProFile(string filename, S640Activity activity, RegisterReaders.S640Stream.S640Stream[] optoHeads) { /// Variant: 1.from OrderDetails, 2.from Procedure.WatermetersStr, 3.empty string variant = (ProcessData.OrderDetails != null && !string.IsNullOrEmpty(ProcessData.OrderDetails.VariantenCode)) ? ProcessData.OrderDetails.VariantenCode /// 1 : !string.IsNullOrEmpty(ProcessData.BatchRslts.Batch.WatermetersStr) ? ProcessData.BatchRslts.Batch.WatermetersStr /// 2 : string.Empty; /// 3 /// Module parameter string moduleParam = (pPars.ModuleParameter.ToLower().Contains("vt_auftrag_pd") && ProcessData.OrderDetails != null) ? ProcessData.OrderDetails.ModuleParameter : pPars.ModuleParameter; /// Purchase order and water meters count int count = 0; string purchaseOrder = null; for (int i = 0; i < optoHeads.Length; i++) { if (optoHeads[i] != null && optoHeads[i].PcbNumber != 0 && ProcessData.BatchRslts.Batch.WaterMeters[i] != null) { count++; if (purchaseOrder == null && !string.IsNullOrEmpty(ProcessData.BatchRslts.Batch.WaterMeters[i].PurchaseOrder)) { purchaseOrder = ProcessData.BatchRslts.Batch.WaterMeters[i].PurchaseOrder; } } } if (ProcessData.OrderDetails != null) { purchaseOrder = ProcessData.OrderDetails.AuftragsNummer; } using (StreamWriter file = new StreamWriter(filename)) { file.WriteLine(""); file.WriteLine(""); file.WriteLine(string.Format(" {0}", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz"))); file.WriteLine(string.Format(" ", (activity == S640Activity.Start) ? "Start" : "End", count, ProcessData.BenchInfo.TestBenchId, ProcessData.BenchInfo.TestBenchName, "SensusKey")); file.WriteLine(string.Format(" ", variant, (purchaseOrder != null) ? purchaseOrder : string.Empty, moduleParam)); file.WriteLine(" "); for (int i = 0; i < optoHeads.Length; i++) { if (optoHeads[i] != null && optoHeads[i].PcbNumber != 0 && ProcessData.BatchRslts.Batch.WaterMeters[i] != null) { Results.Entities.WaterMeter wm = ProcessData.BatchRslts.Batch.WaterMeters[i]; if (activity == S640Activity.Start) { file.WriteLine(string.Format(" ", wm.RadioAddress, wm.SerialNrAux)); } else if (activity == S640Activity.End) { #if ORACLE_DB file.WriteLine(string.Format(" ", wm.OriRadioAddress, wm.AssignedSerialNr.ToString(), wm.AssignedSerialNr.ToString(), wm.RadioAddress, wm.SerialNrAux)); #endif } } } file.WriteLine(" "); file.WriteLine(string.Format(" ", B2S(pPars.MetroEnable), pPars.PulseRatePiston.ToString("F3", CultureInfo.InvariantCulture), pPars.PulseRateLed.ToString(CultureInfo.InvariantCulture), pPars.OffsetFactor.ToString(CultureInfo.InvariantCulture), pPars.FactoryCalibration, pPars.Units, pPars.MeterSize, pPars.OffsetTime)); file.WriteLine(string.Format(" ", B2S(pPars.NewReadEnable), pPars.NewRead)); file.WriteLine(string.Format(" ", B2S(pPars.TransIntervalEnable), pPars.TransInterval)); file.WriteLine(string.Format(" ", B2S(pPars.LatIntervalEnable), pPars.LatInterval)); file.WriteLine(string.Format(" ", B2S(pPars.ResetAlarmEnable))); file.WriteLine(string.Format(" ", B2S(pPars.MetrologyTestModeEnable), pPars.MetrologyTestModeHours)); file.WriteLine(string.Format(" ", B2S(pPars.OpticalTelegramEnable), pPars.OpticalTelegramMinutes)); file.WriteLine(string.Format(" ", B2S(pPars.ChangeRadioEnable))); file.WriteLine(string.Format(" ", B2S(pPars.ChangeMeterIDEnable))); file.WriteLine(string.Format(" ", B2S(pPars.SoftSealEnable))); file.WriteLine(string.Format(" ", B2S(pPars.GoToSleepEnable))); file.WriteLine(string.Format(" ", B2S(pPars.SaveDBEnable))); file.WriteLine(""); } } /// /// Boolean to lowercase string /// string B2S(bool b) { return b ? "true" : "false"; } void ParseFileAndDisplayErrors(string fileName) { log.ErrorFormat("ParseFileAndDisplayErrors(\"{0}\")", fileName); string message = File.ReadAllText(fileName); responseTextBox.Text = message; } /// /// Update test result representing RFID communication success/failure /// /// void UpdateFirstTestResult(IList tests, bool commFailed = false) { DateTime endTime = DateTime.Now; int testTime = StateMachine.Time - startTimeSec; if (!tests.Contains(StateMachine.TestInstances[0].Test)) { tests.Insert(0, StateMachine.TestInstances[0].Test); /// Add RFID test as the 1st item } foreach (var test in tests) { Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part); if (tstRslt != null) { Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters); /// Auxiliary results ... not required /// Main results tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName; tstRslt.TestDone = true; tstRslt.StartTime = tstRslt.Batch.StartTime; tstRslt.EndTime = endTime; tstRslt.FlowSetTime = 0; tstRslt.MassOfEvapWater = 0; tstRslt.TestTime += testTime; /// [s] total communication time of all tests for (int i = 0; i < textBoxesCount; i++) { Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(test.Name, i, Common.CompoundMeterId.Single); if (meterRslt != null && (i < ProcessData.BatchRslts.Batch.WaterMeters.Count) && ProcessData.BatchRslts.Batch.WaterMeters[i] != null && !ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled) { if ((Program.LocalSettings.OptoHeadsEnabled & (1L << i)) != 0 && optoHeads[i] != null && !commFailed) { meterRslt.TestDone = true; meterRslt.Passed = true; } else { meterRslt.TestDone = true; meterRslt.Passed = false; } } } } } } private void closeButton_Click(object sender, EventArgs e) { if (step == Step.EnterSNsAndAwaitResponseToStartPro) { UpdateSerialNumbers(); step = Step.AwaitResponseToEndePro; closeButton.Visible = false; } else if (step == Step.EnterSNs) { UpdateSerialNumbers(); step = Step.ConfirmSNsAndRadioAddresses; closeButton.Visible = false; } else if (step == Step.ConfirmSNsAndRadioAddresses) { step = Step.SaveEndePro; closeButton.Visible = false; } else { log.Error("User is closing this form, communication failed"); UpdateFirstTestResult(tests, true); UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[currentActivityIx], Progress.Aborted)); NormalClose(); } } private void UpdateSerialNumbers() { /// Update water meter properties for (int i = 0; i < textBoxesCount; i++) { if (i < ProcessData.BatchRslts.Batch.WaterMeters.Count && ProcessData.BatchRslts.Batch.WaterMeters[i] != null && !ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled && serialNumbers[i].Visible) { /// Save brass water meter body serial number ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr = serialNumbers[i].Text; serialNumbers[i].Enabled = false; } } } private void NormalClose() { if (Program.LocalSettings.S640CommFormLeft != Location.X || Program.LocalSettings.S640CommFormTop != Location.Y) { /// Update local settings Program.LocalSettings.S640CommFormLeft = Location.X; Program.LocalSettings.S640CommFormTop = Location.Y; Program.LocalSettings.Save(); } formCompleted = true; DialogResult = DialogResult.OK; Close(); } #region Forced close handling public void StartForceCloseHandler() { UiBridge.Bridge.CloseModelessFormHandler += delegate(object sender, EventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(OnForceClose), sender, args); } else OnForceClose(sender, args); }; } void OnForceClose(object sender, EventArgs args) { forcedClose = true; DialogResult = DialogResult.Cancel; Close(); } #endregion private void S640CommForm_FormClosing(object sender, FormClosingEventArgs e) { if (!forcedClose && !formCompleted) { e.Cancel = true; } } private void retryButton_Click(object sender, EventArgs e) { if (step == Step.ConfirmError) { StartActivity(0); } } private void textBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox1); } private void textBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox2); } private void textBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox3); } private void textBox4_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox4); } private void textBox5_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox5); } private void textBox6_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox6); } private void textBox7_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox7); } private void textBox8_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox8); } private void textBox9_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox9); } private void textBox10_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox10); } private void textBox11_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox11); } private void textBox12_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox12); } private void textBox13_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox13); } private void textBox14_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox14); } private void textBox15_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox15); } private void textBox16_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox16); } private void textBox17_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox17); } private void textBox18_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox18); } private void textBox19_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox19); } private void textBox20_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox20); } private void textBox21_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox21); } private void textBox22_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox22); } private void textBox23_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox23); } private void textBox24_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox24); } private void textBox25_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox25); } private void textBox26_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox26); } private void textBox27_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox27); } private void textBox28_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox28); } private void textBox29_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox29); } private void textBox30_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox30); } private void textBox31_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox31); } private void textBox32_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox32); } private void textBox33_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox33); } private void textBox34_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox34); } private void textBox35_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox35); } private void textBox36_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox36); } private void textBox37_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox37); } private void textBox38_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox38); } private void textBox39_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox39); } private void textBox40_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox40); } /// /// Process a key press within any enabled text boxe /// /// /// /// TextBox control which received the event private void ProcKeyPress(object sender, KeyPressEventArgs e, TextBox currentFocusOwner) { if (e.KeyChar == '\r') { /// Process key ..... Next text field if (textBoxesCount < 2) return; /// There is just one enabled textBox for (int i = 0; i < textBoxesCount; i++) { if (serialNumbers[i] == currentFocusOwner) { int nextIx = i; do { nextIx = (++nextIx) % textBoxesCount; } while (!serialNumbers[nextIx].Visible); /// Change focus to the next enabled text box serialNumbers[nextIx].Focus(); return; } } } } private void checkBoxImage1_Click(object sender, EventArgs e) { fromOptoTextBox1.Text = (textBox1.Visible = checkBoxImage1.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage2_Click(object sender, EventArgs e) { fromOptoTextBox2.Text = (textBox2.Visible = checkBoxImage2.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage3_Click(object sender, EventArgs e) { fromOptoTextBox3.Text = (textBox3.Visible = checkBoxImage3.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage4_Click(object sender, EventArgs e) { fromOptoTextBox4.Text = (textBox4.Visible = checkBoxImage4.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage5_Click(object sender, EventArgs e) { fromOptoTextBox5.Text = (textBox5.Visible = checkBoxImage5.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage6_Click(object sender, EventArgs e) { fromOptoTextBox6.Text = (textBox6.Visible = checkBoxImage6.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage7_Click(object sender, EventArgs e) { fromOptoTextBox7.Text = (textBox7.Visible = checkBoxImage7.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage8_Click(object sender, EventArgs e) { fromOptoTextBox8.Text = (textBox8.Visible = checkBoxImage8.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage9_Click(object sender, EventArgs e) { fromOptoTextBox9.Text = (textBox9.Visible = checkBoxImage9.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage10_Click(object sender, EventArgs e) { fromOptoTextBox10.Text = (textBox10.Visible = checkBoxImage10.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage11_Click(object sender, EventArgs e) { fromOptoTextBox11.Text = (textBox11.Visible = checkBoxImage11.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage12_Click(object sender, EventArgs e) { fromOptoTextBox12.Text = (textBox12.Visible = checkBoxImage12.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage13_Click(object sender, EventArgs e) { fromOptoTextBox13.Text = (textBox13.Visible = checkBoxImage13.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage14_Click(object sender, EventArgs e) { fromOptoTextBox14.Text = (textBox14.Visible = checkBoxImage14.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage15_Click(object sender, EventArgs e) { fromOptoTextBox15.Text = (textBox15.Visible = checkBoxImage15.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage16_Click(object sender, EventArgs e) { fromOptoTextBox16.Text = (textBox16.Visible = checkBoxImage16.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage17_Click(object sender, EventArgs e) { fromOptoTextBox17.Text = (textBox17.Visible = checkBoxImage17.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage18_Click(object sender, EventArgs e) { fromOptoTextBox18.Text = (textBox18.Visible = checkBoxImage18.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage19_Click(object sender, EventArgs e) { fromOptoTextBox19.Text = (textBox19.Visible = checkBoxImage19.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage20_Click(object sender, EventArgs e) { fromOptoTextBox20.Text = (textBox20.Visible = checkBoxImage20.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage21_Click(object sender, EventArgs e) { fromOptoTextBox21.Text = (textBox21.Visible = checkBoxImage21.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage22_Click(object sender, EventArgs e) { fromOptoTextBox22.Text = (textBox22.Visible = checkBoxImage22.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage23_Click(object sender, EventArgs e) { fromOptoTextBox23.Text = (textBox23.Visible = checkBoxImage23.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage24_Click(object sender, EventArgs e) { fromOptoTextBox24.Text = (textBox24.Visible = checkBoxImage24.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage25_Click(object sender, EventArgs e) { fromOptoTextBox25.Text = (textBox25.Visible = checkBoxImage25.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage26_Click(object sender, EventArgs e) { fromOptoTextBox26.Text = (textBox26.Visible = checkBoxImage26.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage27_Click(object sender, EventArgs e) { fromOptoTextBox27.Text = (textBox27.Visible = checkBoxImage27.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage28_Click(object sender, EventArgs e) { fromOptoTextBox28.Text = (textBox28.Visible = checkBoxImage28.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage29_Click(object sender, EventArgs e) { fromOptoTextBox29.Text = (textBox29.Visible = checkBoxImage29.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage30_Click(object sender, EventArgs e) { fromOptoTextBox30.Text = (textBox30.Visible = checkBoxImage30.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage31_Click(object sender, EventArgs e) { fromOptoTextBox31.Text = (textBox31.Visible = checkBoxImage31.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage32_Click(object sender, EventArgs e) { fromOptoTextBox32.Text = (textBox32.Visible = checkBoxImage32.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage33_Click(object sender, EventArgs e) { fromOptoTextBox33.Text = (textBox33.Visible = checkBoxImage33.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage34_Click(object sender, EventArgs e) { fromOptoTextBox34.Text = (textBox34.Visible = checkBoxImage34.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage35_Click(object sender, EventArgs e) { fromOptoTextBox35.Text = (textBox35.Visible = checkBoxImage35.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage36_Click(object sender, EventArgs e) { fromOptoTextBox36.Text = (textBox36.Visible = checkBoxImage36.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage37_Click(object sender, EventArgs e) { fromOptoTextBox37.Text = (textBox37.Visible = checkBoxImage37.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage38_Click(object sender, EventArgs e) { fromOptoTextBox38.Text = (textBox38.Visible = checkBoxImage38.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage39_Click(object sender, EventArgs e) { fromOptoTextBox39.Text = (textBox39.Visible = checkBoxImage39.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } private void checkBoxImage40_Click(object sender, EventArgs e) { fromOptoTextBox40.Text = (textBox40.Visible = checkBoxImage40.Checked) ? string.Empty : Strings.Head_was_disabled_by_the_user; } } }