/// /// Copyright (c) 2018 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Windows.Forms; using log4net; using TBF.Rig.GenericDevices; using TBF.Resources; namespace TBF.Rig.DataEntry.Single { public partial class TestStartEndForm : Form, GenericDevices.IHasCompleted { private static readonly ILog log = LogManager.GetLogger(typeof(TestStartEndForm)); // Set to 'true' when the form closes public bool Completed { get { return completed; } } bool completed; /// Number of text boxes for serial numbers public readonly int WaterMetersCount; readonly IRegReader[] regReaders; readonly bool[] disabled; // To be retrieved after the form closes public double[] WMStartState; // To be retrieved after the form closes public readonly string[] WMStartStateStr; // To be retrieved after the form closes public double[] WMEndState; bool endStates; /// false=start states, true=end states double refVolume; double warningLimLo; /// limit to display exclamation mark, typically 2x errLimLo double warningLimHi; /// limit to display exclamation mark, typically 2x errLimHi bool fixedErrorLimits; /// false in case of calculated error limits Button okButton; Label[] labels; TextBox[] startTextBoxes; TextBox[] endTextBoxes; Label[] exclamations; /// IList enabledTextBoxes; IList enabledWmNrs; public TestStartEndForm() { } /// /// Parameterless constructor initializing common part for start and endstate form /// public TestStartEndForm(int waterMetersCount, int lineSize) { InitializeComponent(); this.Icon = Properties.Resources.TBF_icon; ControlBox = false; WaterMetersCount = waterMetersCount; okButton = new Button() { }; labels = new Label[waterMetersCount]; startTextBoxes = new TextBox[waterMetersCount]; endTextBoxes = new TextBox[waterMetersCount]; exclamations = new Label[waterMetersCount]; for (int i = 0; i < waterMetersCount; i++) { labels[i] = new Label(); startTextBoxes[i] = new TextBox(); endTextBoxes[i] = new TextBox(); exclamations[i] = new Label(); } enabledTextBoxes = new List(); enabledWmNrs = new List(); completed = false; StartForceCloseHandler(); } /// /// Constructor to fill in start states /// /// Number of water meters /// Information from CycleBeginningForm about availability of water meters public TestStartEndForm(int waterMetersCount, int lineSize, IRegReader[] regReaders, bool[] disabled) : this(waterMetersCount, lineSize) { endStates = false; this.WaterMetersCount = waterMetersCount; this.regReaders = regReaders; this.disabled = disabled; WMStartState = new double[waterMetersCount]; WMStartStateStr = new string[waterMetersCount]; } /// /// Constructor to fill in end states /// /// Number of water meters /// Information entered on test start /// Information from CycleBeginningForm about availability of water meters /// Reference volume, it is used to verify the end state, show/hide exclamation if necessary /// Error limit low, it is used to verify the end state, show/hide exclamation if necessary /// Error limit high, it is used to verify the end state, show/hide exclamation if necessary public TestStartEndForm(int waterMetersCount, int lineSize, IRegReader[] regReaders, string[] wmStartStateStr, bool[] disabled, double refVolume, double errLimLo, double errLimHi) : this(waterMetersCount, lineSize) { endStates = true; this.WaterMetersCount = waterMetersCount; this.regReaders = regReaders; if (wmStartStateStr == null || wmStartStateStr.Length != waterMetersCount) throw (new Exception("Invalid 'wmStartStateStr' argument")); this.WMStartStateStr = wmStartStateStr; this.disabled = disabled; this.refVolume = refVolume; this.warningLimLo = 2 * errLimLo; this.warningLimHi = 2 * errLimHi; this.fixedErrorLimits = (errLimHi > errLimLo); WMEndState = new double[waterMetersCount]; } private void CycleEndForm_Load(object sender, EventArgs e) { Localize(); //Height = 115 + 90 * WaterMetersCount; int firstWmIx = -1; if (endStates) { for (int i = 0; i < WaterMetersCount; i++) { if (WMStartStateStr != null && i < WMStartStateStr.Length) { startTextBoxes[i].Text = WMStartStateStr[i]; } if (((i < disabled.Length) && disabled[i]) || ((i < regReaders.Length) && (regReaders[i] == null))) { endTextBoxes[i].Enabled = false; } else { endTextBoxes[i].Enabled = true; enabledTextBoxes.Add(endTextBoxes[i]); enabledWmNrs.Add(i); if (firstWmIx == -1) firstWmIx = i; } } } else { for (int i = 0; i < WaterMetersCount; i++) { if (((i < disabled.Length) && disabled[i]) || ((i < regReaders.Length) && (regReaders[i] == null))) { startTextBoxes[i].Enabled = false; } else { startTextBoxes[i].Enabled = true; enabledTextBoxes.Add(startTextBoxes[i]); enabledWmNrs.Add(i); if (firstWmIx == -1) firstWmIx = i; } } } if (enabledTextBoxes.Count > 0) { enabledTextBoxes[0].Focus(); //largeTextBox.Text = string.Format("{0} {1}: {2}", Strings.Water_Meter, firstWmIx + 1, string.Empty); } } void Localize() { Text = Strings.Water_Meter_States; for (int i = 0; i < WaterMetersCount; i++) { labels[i].Text = string.Format("{0} {1}", Strings.Water_Meter, i + 1); } //startLabel.Text = startLabel2.Text = Strings.Start; //endLabel.Text = endLabel2.Text = Strings.End; okButton.Text = Strings.OkBtnText; } private void okButton_Click(object sender, EventArgs eArgs) { try { if (endStates) { for (int i = 0; i < WaterMetersCount; i++) { if (endTextBoxes[i].Visible && endTextBoxes[i].Enabled) { WMEndState[i] = Utils.ParseUDouble(endTextBoxes[i].Text); } } } else { for (int i = 0; i < WaterMetersCount; i++) { if (startTextBoxes[i].Visible && startTextBoxes[i].Enabled) { WMStartStateStr[i] = startTextBoxes[i].Text; WMStartState[i] = Utils.ParseUDouble(startTextBoxes[i].Text); } } } } catch(Exception e) { log.ErrorFormat("Exception: {0}", e.Message); return; } completed = true; 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) { DialogResult = DialogResult.Cancel; Close(); } #endregion /// /// Calculate the approximate error and verify whether it is within limits. /// Make an exclamation mark visible if out of range. /// Similar event handler is implemented for all endTextBoxes (1..24). /// private void ProcEndTextChanged(object sender, EventArgs e, TextBox endTBox) { int wmIx = -1; for (int i = 0; i < startTextBoxes.Length; i++) { if (endTextBoxes[i] == endTBox) { wmIx = i; break; } } double err = 0; try { double endState = Utils.ParseUDouble(endTextBoxes[wmIx].Text); double startState = Utils.ParseUDouble(startTextBoxes[wmIx].Text); err = 100.0 * (endState - startState - refVolume) / refVolume; } catch { err = 1000.0f; }; bool errorOoR = fixedErrorLimits ? ((err < warningLimLo) || (warningLimHi < err)) : ((err < -6) || (+6 < err)); exclamations[wmIx].Visible = errorOoR; //largeExclamationLabel.Visible = errorOoR; //largeTextBox.Text = string.Format("{0} {1}: {2}", Strings.Water_Meter, wmIx + 1, endTextBoxes[wmIx].Text); } //private void endTextBox1_TextChanged(object sndr, EventArgs e) { ProcEndTextChanged(sndr, e, endTextBox1); } //private void endTextBox2_TextChanged(object sndr, EventArgs e) { ProcEndTextChanged(sndr, e, endTextBox2); } //private void endTextBox3_TextChanged(object sndr, EventArgs e) { ProcEndTextChanged(sndr, e, endTextBox3); } //private void endTextBox1_MouseClick(object sender, MouseEventArgs e) { ProcEndTextChanged(sender, e, endTextBox1); } //private void endTextBox2_MouseClick(object sender, MouseEventArgs e) { ProcEndTextChanged(sender, e, endTextBox2); } //private void endTextBox3_MouseClick(object sender, MouseEventArgs e) { ProcEndTextChanged(sender, e, endTextBox3); } /// /// 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 == '+') { /// Process '+' key ..... Form completed okButton_Click(sender, e); } if (e.KeyChar == '\r') { /// Process key ..... Next text field if (enabledTextBoxes.Count < 2) return; /// There is just one enabled textbox for (int i = 0; i < enabledTextBoxes.Count; i++) { if (enabledTextBoxes[i] == currentFocusOwner) { /// Change focus to the next enabled text box int newTBIdx = (i + 1) % enabledTextBoxes.Count; enabledTextBoxes[newTBIdx].Focus(); //largeTextBox.Text = string.Format("{0} {1}: {2}", Strings.Water_Meter, enabledWmNrs[newTBIdx] + 1, enabledTextBoxes[newTBIdx].Text); //largeExclamationLabel.Visible = false; return; } } } } //private void startTextBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox1); } //private void startTextBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox2); } //private void startTextBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox3); } //private void endTextBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox1); } //private void endTextBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox2); } //private void endTextBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox3); } private void ProcStartTextChanged(object sender, EventArgs e, TextBox startTBox) { int wmIx = -1; for (int i = 0; i < startTextBoxes.Length; i++) { if (startTextBoxes[i] == startTBox) { wmIx = i; break; } } //largeTextBox.Text = string.Format("{0} {1}: {2}", Strings.Water_Meter, wmIx + 1, startTextBoxes[wmIx].Text); //largeExclamationLabel.Visible = false; } //private void startTextBox1_TextChanged(object sender, EventArgs e) { ProcStartTextChanged(sender, e, startTextBox1); } //private void startTextBox2_TextChanged(object sender, EventArgs e) { ProcStartTextChanged(sender, e, startTextBox2); } //private void startTextBox3_TextChanged(object sender, EventArgs e) { ProcStartTextChanged(sender, e, startTextBox3); } //private void startTextBox1_MouseClick(object sender, MouseEventArgs e) { ProcStartTextChanged(sender, e, startTextBox1); } //private void startTextBox2_MouseClick(object sender, MouseEventArgs e) { ProcStartTextChanged(sender, e, startTextBox2); } //private void startTextBox3_MouseClick(object sender, MouseEventArgs e) { ProcStartTextChanged(sender, e, startTextBox3); } } }