tbf/TBF/UI/Bench/Metrology/MetrologyDlgFlowMeterTab.cs

455 lines
17 KiB
C#

///
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using log4net;
using Common;
using Common.Forms;
using Config.Entities;
using TBF.Resources;
using TBF.UI.Shared;
namespace TBF.UI.Bench.Metrology
{
public partial class MetrologyDlgFlowMeterTab : UserControl, IMetrologyDlgTab
{
static readonly ILog log = LogManager.GetLogger(typeof(MetrologyDlgFlowMeterTab));
public const int SignifDigits = 5;
/// <summary>
/// Component entity that has a list of 'measurement-correction' pairs
/// to be updated in the database on OK.
/// </summary>
Component meterEntity;
public Component MeterEntity
{
get { return meterEntity; }
set { meterEntity = value; }
}
/// <summary>
/// Calibration information configuration
/// </summary>
public Rig.GenericDevices.ICalibRangesCfg CalibInfoCfg;
/// <summary>
/// A list of 'measurement-correction' pairs to be deleted from the database on OK.
/// </summary>
public IList<MeasurementCorrection> ToBeRemoved
{
get { return toBeRemoved; }
set { toBeRemoved = value; }
}
IList<MeasurementCorrection> toBeRemoved;
MetrologyDlg parent;
bool unlocked;
Control measurementTextBox;
Control correctionTextBox;
Control errorTextBox;
readonly int rangeIx; /// 0 (no range) or 1..5 (range #)
readonly bool isLastFlowMeterRange; /// true when this is the last range of this flow meter.
/// This is to prevent double saving of the meter entity to a DB
Unit currentUnit;
public MetrologyDlgFlowMeterTab() : this(0, true) {}
public MetrologyDlgFlowMeterTab(int rangeIx1, bool isLastFlowMeterRange)
{
InitializeComponent();
calibDateTimePicker.CustomFormat = Constants.DateFormat;
calibDateTimePicker.MinDate = Constants.MinDate;
calibExpirationDateTimePicker.CustomFormat = Constants.DateFormat;
calibExpirationDateTimePicker.MinDate = Constants.MinDate;
this.rangeIx = rangeIx1;
this.isLastFlowMeterRange = isLastFlowMeterRange;
toBeRemoved = new List<MeasurementCorrection>();
unlocked = false;
}
private void MetrologyDlgFlowMeterTab_Load(object sender, System.EventArgs e)
{
if (meterEntity == null) return;
parent = ParentForm as MetrologyDlg;
Localize();
/// Panel1
if (rangeIx == 0)
{
cmpntNameLabel.Text = meterEntity.Name;
}
else
{
cmpntNameLabel.Text = string.Format("{0} Range {1}", meterEntity.Name, rangeIx);
tempFromToLabel.Text = string.Format("{0} {1} {2} {3} °C", Strings.from, CalibInfoCfg.GetTempLo(rangeIx), Strings.to, CalibInfoCfg.GetTempHi(rangeIx));
pressFromToLabel.Text = string.Format("{0} {1} {2} {3} bar", Strings.from, CalibInfoCfg.GetPressLo(rangeIx), Strings.to, CalibInfoCfg.GetPressHi(rangeIx));
}
for (Unit u = 0; u < Unit.Count; u++)
if (Units.IsFlow(u))
unitComboBox.Items.Add(u.ToDescription());
/// Panel2
this.Controls.Add(measurementTextBox = new TextBox());
this.Controls.Add(correctionTextBox = new TextBox());
this.Controls.Add(errorTextBox = new TextBox());
currentUnit = TBF.Rig.Sequences.ProcessData.FlowUnit;
unitComboBox.Text = currentUnit.ToDescription();
InitializeColumns(listViewEx, currentUnit);
RefreshAll(rangeIx);
listViewEx.SubItemClicked += new SubItemEventHandler(listViewEx_SubItemClicked);
listViewEx.SubItemEndEditing += new SubItemEndEditingEventHandler(listViewEx_SubItemEndEditing);
unitComboBox.SelectedIndexChanged += new System.EventHandler(unitComboBox_SelectedIndexChanged);
}
void InitializeColumns(ListView lv, Unit unit)
{
lv.Columns.Clear();
lv.Columns.Add(new ColumnHeader() { Text = Strings.Nr, Width = 40 });
lv.Columns.Add(new ColumnHeader() { Text = string.Format("{0} [{1}]", Strings.Flow, unit.ToDescription()), Width = 120 });
lv.Columns.Add(new ColumnHeader() { Text = string.Format("{0} [{1}]", Strings.Correction, unit.ToDescription()), Width = 150 });
lv.Columns.Add(new ColumnHeader() { Text = string.Format("{0} [%]", Strings.Error), Width = 100 });
measuredLabel.Text = string.Format("{0} [{1}]:", Strings.Measured, unit.ToDescription());
correctedLabel.Text = string.Format("{0} [{1}]:", Strings.Corrected, unit.ToDescription());
measuredTextBox.Text = string.Empty;
correctedTextBox.Text = string.Empty;
}
void Localize()
{
nameGroupBox.Text = Strings.Component;
calibrationGroupBox.Text = Strings.Calibration;
calibCertificateNrLabel.Text = Strings.Certificate;
calibDateLabel.Text = Strings.Date;
calibValidDateLabel.Text = Strings.Valid_until;
testGroupBox.Text = Strings.Test_measured_corrected;
}
void RefreshAll(int rangeIx1)
{
if (CalibInfoCfg != null)
{
calibCertificateNrTextBox.Text = CalibInfoCfg.GetCalibCertificate(rangeIx1);
calibDateTimePicker.Value = (CalibInfoCfg.GetCalibDate(rangeIx1) < Constants.MinDate) ? Constants.MinDate : CalibInfoCfg.GetCalibDate(rangeIx1);
calibExpirationDateTimePicker.Value = (CalibInfoCfg.GetCalibValidDate(rangeIx1) < Constants.MinDate) ? Constants.MinDate : CalibInfoCfg.GetCalibValidDate(rangeIx1);
}
listViewEx.Items.Clear();
foreach (var corr in MeterEntity.Corrections)
{
if (corr.RangeIx == rangeIx) AddOneLVI(corr);
}
}
void AddOneLVI(MeasurementCorrection corr)
{
int nr = listViewEx.Items.Count + 1;
ListViewItem lvi = new ListViewItem(nr.ToString());
lvi.Tag = corr;
lvi.SubItems.Add(Units.ConvertTo(currentUnit, corr.Measurement).ToString());
double trueValue = corr.Measurement + corr.Correction;
double difference = Units.IsDefaultUnit(currentUnit)
? corr.Correction
: Units.ConvertTo(currentUnit, trueValue) - Units.ConvertTo(currentUnit, corr.Measurement);
lvi.SubItems.Add(Common.Utils.ToNiceString(difference, SignifDigits));
if (corr.Measurement == 0)
{
lvi.SubItems.Add(Strings.NaN);
}
else
{
double error = Config.Formulas.ErrorFromVolumes(corr.Measurement, trueValue);
lvi.SubItems.Add(Common.Utils.ToNiceString(error, SignifDigits));
}
listViewEx.Items.Add(lvi);
}
void listViewEx_SubItemClicked(object sender, SubItemEventArgs e)
{
if (unlocked && e.SubItem == 1)
{
listViewEx.StartEditing(measurementTextBox, e.Item, e.SubItem);
}
else if (unlocked && e.SubItem == 2)
{
listViewEx.StartEditing(correctionTextBox, e.Item, e.SubItem);
}
else if (unlocked && e.SubItem == 3)
{
listViewEx.StartEditing(correctionTextBox, e.Item, e.SubItem);
}
}
void listViewEx_SubItemEndEditing(object sender, SubItemEndEditingEventArgs e)
{
if (ParseItem(e.Item, e.SubItem, e.DisplayText)) return;
/// New value is NOK, revert the original text
e.DisplayText = e.Item.Text;
e.Cancel = true;
}
/// <summary>
/// Parse text of a ListViewItem
/// </summary>
/// <returns>true = value parsed OK</returns>
bool ParseItem(ListViewItem item, int subItem, string strValue)
{
double oriMeasurement; /// Measurement in selected units
double measurement; /// Measurement in default units
double difference; /// Correction in selected unit
double correction; /// Correction in default unit
double error = 0;
if (subItem == 1 && Utils.TryParseEDouble(strValue, out oriMeasurement) && (measurement = Units.ConvertFrom(currentUnit, oriMeasurement)) >= 0)
{
(item.Tag as MeasurementCorrection).Measurement = measurement;
/// Update error (if possible)
if (Utils.TryParseEDouble(item.SubItems[2].Text, out difference) && (measurement != 0))
{
correction = Units.IsDefaultUnit(currentUnit) ? difference
: Units.ConvertFrom(currentUnit, oriMeasurement + difference) - Units.ConvertFrom(currentUnit, oriMeasurement);
error = Config.Formulas.ErrorFromVolumes(measurement, measurement + correction);
item.SubItems[3].Text = Common.Utils.ToNiceString(error, SignifDigits);
}
else
{
item.SubItems[3].Text = Strings.NaN;
}
return true;
}
else if (subItem == 2 && Utils.TryParseEDouble(strValue, out difference))
{
if (Utils.TryParseEDouble(item.SubItems[1].Text, out oriMeasurement))
{
measurement = Units.ConvertFrom(currentUnit, oriMeasurement);
correction = Units.IsDefaultUnit(currentUnit) ? difference
: Units.ConvertFrom(currentUnit, oriMeasurement + difference) - Units.ConvertFrom(currentUnit, oriMeasurement);
(item.Tag as MeasurementCorrection).Correction = correction;
/// Update error (if possible)
if (measurement != 0)
{
error = Config.Formulas.ErrorFromVolumes(measurement, measurement + correction);
item.SubItems[3].Text = Common.Utils.ToNiceString(error, SignifDigits);
}
else
{
item.SubItems[3].Text = Strings.NaN;
}
return true;
}
else
{
return false;
}
}
else if (subItem == 3 && ((strValue == Strings.NaN) || Utils.TryParseEDouble(strValue, out error)))
{
if (strValue == Strings.NaN)
{
}
else
{
if (Utils.TryParseEDouble(item.SubItems[1].Text, out oriMeasurement) && (measurement = Units.ConvertFrom(currentUnit, oriMeasurement)) != 0)
{
correction = Config.Formulas.CorrectionFromError(measurement, error);
(item.Tag as MeasurementCorrection).Correction = correction;
difference = Units.IsDefaultUnit(currentUnit)
? correction
: Units.ConvertTo(currentUnit, measurement + correction) - oriMeasurement;
item.SubItems[2].Text = Common.Utils.ToNiceString(difference, SignifDigits);
}
}
return true;
}
else
{
return false;
}
}
public void Unlock()
{
unlocked = true;
calibCertificateNrTextBox.Enabled = true;
calibDateTimePicker.Enabled = true;
calibExpirationDateTimePicker.Enabled = true;
if (listViewEx.SelectedItems.Count == 1)
{
int ix = listViewEx.SelectedIndices[0];
listViewEx.Focus();
listViewEx.Items[ix].Selected = true;
listViewEx.Items[ix].EnsureVisible();
}
}
public void OkBtnClicked()
{
if (CalibInfoCfg != null)
{
try
{
CalibInfoCfg.SetCalibCertificate(rangeIx, calibCertificateNrTextBox.Text);
CalibInfoCfg.SetCalibDate(rangeIx, calibDateTimePicker.Value.Date);
CalibInfoCfg.SetCalibValidDate(rangeIx, calibExpirationDateTimePicker.Value.Date);
}
catch
{
MessageBox.Show(Strings.Invalid_calib_info_Correct_pls,
Strings.Error,
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
}
public void CancelBtnClicked()
{
}
public void AddOne()
{
MeasurementCorrection corr = new MeasurementCorrection(rangeIx);
MeterEntity.Corrections.Add(corr);
AddOneLVI(corr);
listViewEx.Focus();
listViewEx.SelectedItems.Clear();
listViewEx.Items[listViewEx.Items.Count - 1].Selected = true;
listViewEx.Items[listViewEx.Items.Count - 1].EnsureVisible();
}
public void RemoveSelected()
{
if (listViewEx.SelectedItems.Count != 1) return;
int removeItemNr = listViewEx.SelectedIndices[0];
MeasurementCorrection selected = (MeasurementCorrection)listViewEx.SelectedItems[0].Tag;
if (selected.Id != 0) toBeRemoved.Add(selected);
MeterEntity.Corrections.RemoveAt(removeItemNr);
RefreshAll(rangeIx);
if (removeItemNr < listViewEx.Items.Count)
{
listViewEx.Focus();
listViewEx.Items[removeItemNr].Selected = true;
listViewEx.Items[removeItemNr].EnsureVisible();
}
else
{
parent.UpdateButtonStates(SharedButtons.SelectedItemPos.None);
}
}
public void MoveUpSelected()
{
}
public void MoveDownSelected()
{
}
/// <summary>
/// Event handler that indicates the selected item position
/// and updates 'Remove', 'Up' and 'Down' buttons in the parent dialog.
/// </summary>
private void listViewEx_SelectedIndexChanged(object sender, EventArgs e)
{
if (listViewEx.SelectedItems.Count != 1)
{
parent.UpdateButtonStates(SharedButtons.SelectedItemPos.None);
}
else if (listViewEx.Items.Count == 1)
{
parent.UpdateButtonStates(SharedButtons.SelectedItemPos.FirstAndLast);
}
else if (listViewEx.SelectedIndices[0] == 0)
{
parent.UpdateButtonStates(SharedButtons.SelectedItemPos.First);
}
else if (listViewEx.SelectedIndices[0] == (listViewEx.Items.Count - 1))
{
parent.UpdateButtonStates(SharedButtons.SelectedItemPos.Last);
}
else
{
parent.UpdateButtonStates(SharedButtons.SelectedItemPos.Middle);
}
}
private void measuredTextBox_TextChanged(object sender, EventArgs e)
{
double measured;
if (double.TryParse(measuredTextBox.Text,
NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent,
CultureInfo.CurrentCulture,
out measured) ||
double.TryParse(measuredTextBox.Text,
NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent,
CultureInfo.InvariantCulture,
out measured))
{
var corrections = new List<MeasurementCorrection>();
foreach (var c in meterEntity.Corrections) if (c.RangeIx == rangeIx) corrections.Add(c);
corrections.Sort();
double corrected = MeasurementCorrection.CorrectedValue(Units.ConvertFrom(currentUnit, measured), corrections);
correctedTextBox.Text = Units.ConvertTo(currentUnit, corrected).ToString();
}
}
public string GetWarningsBeforeSaving(ref Dictionary<string, string> renmInfo)
{
return string.Empty;
}
public void UpdateRelatedItems(Dictionary<string, string> renameInfo)
{
}
public void SaveEntityToDB(NHibernate.ISession session)
{
if (isLastFlowMeterRange)
{
Component modified = CalibInfoCfg.CreateDbEntity();
MeterEntity.Parameters = modified.Parameters;
session.SaveOrUpdate(MeterEntity);
}
}
private void unitComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
for (Unit u = 0; u < Unit.Count; u++)
{
if (u.ToDescription() == unitComboBox.Text)
{
currentUnit = u;
break;
}
}
InitializeColumns(listViewEx, currentUnit);
RefreshAll(rangeIx);
}
}
}