tbf/TBF/Rig/Uni/SharedDialogs/SmartMetersCommunication/SmartCommunicationForm.cs
Michal Buzik f1e6e94450 work backup
- Register Reader Poseidon works
- Smart Form - wrong functionality
- refactoring
2025-11-06 14:11:13 +01:00

641 lines
27 KiB
C#

///
/// Copyright (c) 2015-2023 Sensus Slovensko a.s.
///
//#define VERIFY_ACTIVE_MODE
//#define VERIFY_Q2_CORR_RESET
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Config.Entities;
using log4net;
using TBF.Resources;
using TBF.Rig.Generic;
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
using TBF.Rig.Sequences;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations;
using CheckBoxImage = TBF.Boxes.CheckBoxImage;
//using TestMethodCfg = TBF.Rig.RegisterReaders.iPerlReaderUNI.TestMethodCfg;
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
{
public enum CommErr
{
None = 0,
CommFailed, /// 1
OpenPort, /// 2
Read, /// 3
Read1, /// 4
Read2, /// 5
Read3, /// 6
Read4, /// 7
Write, /// 8
ReadAfterWrite, /// 9
CmdActive, /// 0AH = 10
CmdTest, /// 0BH = 11
Verify, /// 0CH = 12
WrongIPerlType, /// 0DH = 13
OutOfRange, /// 0EH = 14
Q2OutOfRange, /// 0FH = 15
MissingTest, /// 10H = 16
RFPowerRecordMissing, /// 11H = 17
HeadDisabledByUser, /// 12H = 18
WrongArguments, /// 13H = 19
}
public partial class SmartCommunicationForm : Form, GenericDevices.IHasCompleted
{
private static readonly ILog log = LogManager.GetLogger(typeof(SmartCommunicationForm));
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
readonly bool checkBoxesEditMode;
// Set to 'true' when the form closes
public bool Completed { get { return formCompleted; } }
bool formCompleted;
bool forcedClose; /// Set in the forced close handler
/// <summary> Number of text boxes for serial numbers </summary>
public int WaterMetersCount;
const int MaxTextBoxesCount = 48;
int textBoxesCount;
Label[] labels;
PictureBox[] counters;
TextBox[] messages;
CheckBoxImage[] checkBoxes;
static int[] ckbIndex;
static bool[] ckbState;
static IList<ISmartReader> iperlHeads;
static IList<int> waterMeterPositions0; /// keeps original 0-based indices in RegisterReaders list
static int commonWMType;
///
/// RFID multiplexer PCB / RFID serial port and worker thread related variables
///
private static ICorrections _corrections;
private static ICorrections GetNewCorrections(SmartCommunicationForm form)
{
Object version = new IPerlCorrections(form, log, rfidDataLogger);
//TODO BUMI - work with !!!!!!!!!!!!!! ProcessData.IperlHeads;
if (version is IPerlCorrections)
return new IPerlCorrections(form, log, rfidDataLogger);
else
return new PoseidonCorrections(form, log, rfidDataLogger);
}
public static ITestMethodCfg? TestMethodCfg
{
get
{
return _corrections != null?
_corrections.Cfg :
null;
}
set
{
// Add null check for the value being set
if (value == null)
{
// Log or handle null case
return;
}
if (_corrections == null)
{
_corrections = GetNewCorrections(null);
}
_corrections.Cfg = value;
}
}
static int currentActivityStep;
static int currentGroup; /// form -> worker thread (0 = none)
static int lastGroup;
static int completedCommCount; /// Number of completed communication steps
/// <summary> Parameterless constructor (without watermeters, threads) </summary>
public SmartCommunicationForm()
{
InitializeComponent();
}
/// <summary>
/// Constructor for checkBox states (active/inactive iPerl head) editing.
/// </summary>
/// <param name="checkBoxes">Initial check box states</param>
public SmartCommunicationForm(bool isCheckBoxesEditMode)
: this()
{
//TODO get corrections based on defined meter
_corrections = new IPerlCorrections(this, log, rfidDataLogger); // default iPerl Head communication params
if (isCheckBoxesEditMode)
{
checkBoxesEditMode = true;
saveButton.Visible = true;
activityLabel.Text = Strings.Optical_heads;
ShuffleTextBoxes(ProcessData.WMsCount, ProcessData.LineSize);
this.ContextMenu = _corrections.GetContextMenu();
}
}
/// <summary>
/// Constructor for one iPerlCommunication 'test'
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public SmartCommunicationForm(Generic.IComponent componentBase, Test test, ITestParams testParams)
: this(componentBase, new List<Test> { test }, new List<ITestParams> { testParams })
{
}
/// <summary>
/// Constructor for multiple iPerlCommunication 'tests'
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public SmartCommunicationForm(Generic.IComponent componentBase, IList<Test> tests, IList<ITestParams> multiTestParams)
: this()
{
checkBoxesEditMode = false;
//TODO get corrections based on defined meter
_corrections = new PoseidonCorrections(this, log, rfidDataLogger, componentBase as ISmartTestMethod,componentBase.Cfg as TestMethodCfg,tests,multiTestParams);
if (multiTestParams.Count > 0)
{
ProcessData.RegisterReaders = StateMachine.GetMetersPath(tests[0]).RegisterReaders;
activityLabel.Text = multiTestParams[0].Activity;
foreach (var p in multiTestParams)
{
if (p.Activity.ToLower() == iPerlCommunicationConstants.GetDefaultQ2CorrectionsStr.ToLower())
{
/// Reset IsQ2PreCorrectionCalculated that is used for synchronization/to prevent double REST call
ProcessData.IsQ2PreCorrectionCalculated = false;
commonWMType = 0;
break;
}
}
}
/// Attach to 'CommCompleted' handler
SmartCommunicationForm.CommCompletedHandler += delegate(object sender, CommCompletedEventArgs args)
{
if (InvokeRequired)
{
Invoke(new EventHandler<CommCompletedEventArgs>(DoOnCommCompleted), sender, args);
}
else DoOnCommCompleted(sender, args);
};
/// Attach to 'AllCompleted' handler
SmartCommunicationForm.AllCompletedHandler += delegate(object sender, AllCompletedEventArgs args)
{
if (InvokeRequired)
{
Invoke(new EventHandler<AllCompletedEventArgs>(DoOnAllCompleted), sender, args);
}
else DoOnAllCompleted(sender, args);
};
formCompleted = false;
StartForceCloseHandler();
iperlHeads = new List<ISmartReader>();
waterMeterPositions0 = new List<int>();
///
for (int wmPos = 0; wmPos < ProcessData.RegisterReaders.Length; wmPos++)
{
ISmartReader iperlHead = ProcessData.RegisterReaders[wmPos] as ISmartReader;
if (iperlHead != null)
{
iperlHeads.Add(iperlHead);
waterMeterPositions0.Add(wmPos);
}
}
WaterMetersCount = iperlHeads.Count;
ShuffleTextBoxes(WaterMetersCount, ProcessData.LineSize);
_corrections.PrepareForTestsActivities();
}
/// <summary>
/// Called when communication with all watermeters is completed
/// </summary>
static void OnAllCompleted(object sender, AllCompletedEventArgs data)
{
if ( AllCompletedHandler == null) return;
try { AllCompletedHandler(sender, data); }
catch (Exception e) { log.Error("AllCompletedHandler(...) failed", e); }
}
private void DoOnCommCompleted(object sender, CommCompletedEventArgs data)
{
_corrections.DoOnCommCompleted(sender, data, waterMeterPositions0);
}
/// <summary>
/// Make sure the layout of labels/text boxes on the screen
/// corresponds to the layout of watermeters of the test bench.
/// </summary>
/// <param name="wmsCount">Number of watermeters</param>
/// <param name="lineSize">Number of watermeters in one line</param>
void ShuffleTextBoxes(int wmsCount, int lineSize)
{
labels = new Label[MaxTextBoxesCount]
{
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,
wmLabel41, wmLabel42, wmLabel43, wmLabel44, wmLabel45, wmLabel46, wmLabel47, wmLabel48,
};
counters = new PictureBox[MaxTextBoxesCount]
{
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,
pictureBox41, pictureBox42, pictureBox43, pictureBox44, pictureBox45, pictureBox46, pictureBox47, pictureBox48,
};
messages = new TextBox[MaxTextBoxesCount]
{
wmTextBox1, wmTextBox2, wmTextBox3, wmTextBox4, wmTextBox5, wmTextBox6, wmTextBox7, wmTextBox8, wmTextBox9, wmTextBox10,
wmTextBox11, wmTextBox12, wmTextBox13, wmTextBox14, wmTextBox15, wmTextBox16, wmTextBox17, wmTextBox18, wmTextBox19, wmTextBox20,
wmTextBox21, wmTextBox22, wmTextBox23, wmTextBox24, wmTextBox25, wmTextBox26, wmTextBox27, wmTextBox28, wmTextBox29, wmTextBox30,
wmTextBox31, wmTextBox32, wmTextBox33, wmTextBox34, wmTextBox35, wmTextBox36, wmTextBox37, wmTextBox38, wmTextBox39, wmTextBox40,
wmTextBox41, wmTextBox42, wmTextBox43, wmTextBox44, wmTextBox45, wmTextBox46, wmTextBox47, wmTextBox48,
};
checkBoxes = new CheckBoxImage[MaxTextBoxesCount]
{
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,
checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45, checkBoxImage46, checkBoxImage47, checkBoxImage48,
};
ckbIndex = new int[MaxTextBoxesCount];
ckbState = new bool[MaxTextBoxesCount];
textBoxesCount = MaxTextBoxesCount;
///
if (wmsCount < textBoxesCount && lineSize > 0)
{
int nrLines = (wmsCount + lineSize - 1) / lineSize;
int gap = (textBoxesCount - wmsCount) / nrLines;
for (int i = 0; i < ckbIndex.Length; i++)
{
ckbIndex[i] = -1; /// Initialize with invalid indices
}
int dest = 0;
for (int l = 0; l < nrLines; l++)
{
for (int i = 0; i < lineSize; i++)
{
int origin = l * lineSize + l * gap + i;
labels[dest] = labels[origin];
counters[dest] = counters[origin];
messages[dest] = messages[origin];
checkBoxes[dest] = checkBoxes[origin];
ckbIndex[origin] = dest;
dest++;
}
}
textBoxesCount = wmsCount;
}
int count = checkBoxesEditMode ? textBoxesCount : Math.Min(textBoxesCount, _corrections.GetHeadsCount());
for (int j = 0; j < count; j++)
{
labels[j].Text = (j + 1).ToString();
}
ResizeDlgToFitEnabledControls();
}
void ResizeDlgToFitEnabledControls()
{
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 + 50;
Height = yMax + 60;
}
void Localize()
{
Text = checkBoxesEditMode ? Strings.Optical_heads : Strings.Water_Meter_States;
saveButton.Text = Strings.Save;
sampleLabel1.Text = Strings.Direction_and_pulses_are_OK;
sampleLabel2.Text = Strings.There_are_no_opto_pulses;
sampleLabel3.Text = Strings.Direction_is_NOK;
samplePictureBox1.BackColor = iPerlCommunicationConstants.OptoAndDirOKColor;
samplePictureBox2.BackColor = iPerlCommunicationConstants.OptoNokColor;
samplePictureBox3.BackColor = iPerlCommunicationConstants.DirNokColor;
}
private void iPerlCommunicationForm_Load(object sender, EventArgs e)
{
Localize();
if (checkBoxesEditMode)
{
/// Check box edit mode => Hide explanation of activity colours
sampleLabel1.Visible = false;
sampleLabel2.Visible = false;
sampleLabel3.Visible = false;
samplePictureBox1.Visible = false;
samplePictureBox2.Visible = false;
samplePictureBox3.Visible = false;
}
_corrections.Load(labels,counters,messages,checkBoxes,ckbIndex,ckbState, iperlHeads,textBoxesCount,checkBoxesEditMode );
///
/// Set location and checkbox states to values stored in local settings
///
TBF.LocalSettings ls = Program.LocalSettings;
Left = (ls.iPerlCommunicationsFormLeft != 0) ? ls.iPerlCommunicationsFormLeft : 150;
Top = (ls.iPerlCommunicationsFormTop != 0) ? ls.iPerlCommunicationsFormTop : 150;
SetCheckBoxStates(ls.OptoHeadsEnabled);
if (!checkBoxesEditMode)
{
/// Regular activity (not a checkbox edit mode invoked from TBF menu)
/// Reset opto-data indication
for (int i = 0; i < _corrections.GetHeadsCount(); i++)
{
counters[i].BackColor = iPerlCommunicationConstants.OptoNokColor;
}
/// Start communication process by incrementing 'currentGroup'.
currentGroup++;
int wtId = 0;
foreach (var wt in _corrections.GetAllThreads())
{
wt.Start(new Boxes.IntBox(wtId++)); /// Start worker threads !!!
}
}
}
#region Forced close handling
public void StartForceCloseHandler()
{
UiBridge.Bridge.CloseModelessFormHandler += delegate(object sender, EventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<EventArgs>(OnForceClose), sender, args); }
else OnForceClose(sender, args);
};
}
void OnForceClose(object sender, EventArgs args)
{
CommCompletedHandler = null;
AllCompletedHandler = null;
_corrections?.StopWorkerThreads(true);
forcedClose = true;
DialogResult = DialogResult.Cancel;
Close();
}
#endregion
/// <summary>
/// Worker thread
/// </summary>
/// <param name="threadData">Thread ID (integer) wrapped into IntBox</param>
void Worker(object threadData)
{
if (_corrections != null)
{
_corrections.Worker(threadData);
}
}
void StartDataStreamProcessingForActiveMeters(int iMultiTestParamsItem)
{
_corrections.StartDataStreamProcessingForActiveMeters(iMultiTestParamsItem);
}
/// <summary>
/// Called when communication with one watermeter is completed
/// </summary>
public static void OnCommCompleted(object sender, CommCompletedEventArgs data)
{
if (CommCompletedHandler == null) return;
try { CommCompletedHandler(sender, data); }
catch (Exception e) { log.Error("CommCompletedHandler(...) failed", e); }
}
public static event EventHandler<CommCompletedEventArgs> CommCompletedHandler;
public static event EventHandler<AllCompletedEventArgs> AllCompletedHandler;
void DoOnAllCompleted(object sender, AllCompletedEventArgs data)
{
Text = data.CommMessage;
}
#region Check boxes edit mode support
private void checkBoxImage1_Click(object sender, EventArgs e) { ckbState[ckbIndex[0]] = checkBoxImage1.Checked; }
private void checkBoxImage2_Click(object sender, EventArgs e) { ckbState[ckbIndex[1]] = checkBoxImage2.Checked; }
private void checkBoxImage3_Click(object sender, EventArgs e) { ckbState[ckbIndex[2]] = checkBoxImage3.Checked; }
private void checkBoxImage4_Click(object sender, EventArgs e) { ckbState[ckbIndex[3]] = checkBoxImage4.Checked; }
private void checkBoxImage5_Click(object sender, EventArgs e) { ckbState[ckbIndex[4]] = checkBoxImage5.Checked; }
private void checkBoxImage6_Click(object sender, EventArgs e) { ckbState[ckbIndex[5]] = checkBoxImage6.Checked; }
private void checkBoxImage7_Click(object sender, EventArgs e) { ckbState[ckbIndex[6]] = checkBoxImage7.Checked; }
private void checkBoxImage8_Click(object sender, EventArgs e) { ckbState[ckbIndex[7]] = checkBoxImage8.Checked; }
private void checkBoxImage9_Click(object sender, EventArgs e) { ckbState[ckbIndex[8]] = checkBoxImage9.Checked; }
private void checkBoxImage10_Click(object sender, EventArgs e) { ckbState[ckbIndex[9]] = checkBoxImage10.Checked; }
private void checkBoxImage11_Click(object sender, EventArgs e) { ckbState[ckbIndex[10]] = checkBoxImage11.Checked; }
private void checkBoxImage12_Click(object sender, EventArgs e) { ckbState[ckbIndex[11]] = checkBoxImage12.Checked; }
private void checkBoxImage13_Click(object sender, EventArgs e) { ckbState[ckbIndex[12]] = checkBoxImage13.Checked; }
private void checkBoxImage14_Click(object sender, EventArgs e) { ckbState[ckbIndex[13]] = checkBoxImage14.Checked; }
private void checkBoxImage15_Click(object sender, EventArgs e) { ckbState[ckbIndex[14]] = checkBoxImage15.Checked; }
private void checkBoxImage16_Click(object sender, EventArgs e) { ckbState[ckbIndex[15]] = checkBoxImage16.Checked; }
private void checkBoxImage17_Click(object sender, EventArgs e) { ckbState[ckbIndex[16]] = checkBoxImage17.Checked; }
private void checkBoxImage18_Click(object sender, EventArgs e) { ckbState[ckbIndex[17]] = checkBoxImage18.Checked; }
private void checkBoxImage19_Click(object sender, EventArgs e) { ckbState[ckbIndex[18]] = checkBoxImage19.Checked; }
private void checkBoxImage20_Click(object sender, EventArgs e) { ckbState[ckbIndex[19]] = checkBoxImage20.Checked; }
private void checkBoxImage21_Click(object sender, EventArgs e) { ckbState[ckbIndex[20]] = checkBoxImage21.Checked; }
private void checkBoxImage22_Click(object sender, EventArgs e) { ckbState[ckbIndex[21]] = checkBoxImage22.Checked; }
private void checkBoxImage23_Click(object sender, EventArgs e) { ckbState[ckbIndex[22]] = checkBoxImage23.Checked; }
private void checkBoxImage24_Click(object sender, EventArgs e) { ckbState[ckbIndex[23]] = checkBoxImage24.Checked; }
private void checkBoxImage25_Click(object sender, EventArgs e) { ckbState[ckbIndex[24]] = checkBoxImage25.Checked; }
private void checkBoxImage26_Click(object sender, EventArgs e) { ckbState[ckbIndex[25]] = checkBoxImage26.Checked; }
private void checkBoxImage27_Click(object sender, EventArgs e) { ckbState[ckbIndex[26]] = checkBoxImage27.Checked; }
private void checkBoxImage28_Click(object sender, EventArgs e) { ckbState[ckbIndex[27]] = checkBoxImage28.Checked; }
private void checkBoxImage29_Click(object sender, EventArgs e) { ckbState[ckbIndex[28]] = checkBoxImage29.Checked; }
private void checkBoxImage30_Click(object sender, EventArgs e) { ckbState[ckbIndex[29]] = checkBoxImage30.Checked; }
private void checkBoxImage31_Click(object sender, EventArgs e) { ckbState[ckbIndex[30]] = checkBoxImage31.Checked; }
private void checkBoxImage32_Click(object sender, EventArgs e) { ckbState[ckbIndex[31]] = checkBoxImage32.Checked; }
private void checkBoxImage33_Click(object sender, EventArgs e) { ckbState[ckbIndex[32]] = checkBoxImage33.Checked; }
private void checkBoxImage34_Click(object sender, EventArgs e) { ckbState[ckbIndex[33]] = checkBoxImage34.Checked; }
private void checkBoxImage35_Click(object sender, EventArgs e) { ckbState[ckbIndex[34]] = checkBoxImage35.Checked; }
private void checkBoxImage36_Click(object sender, EventArgs e) { ckbState[ckbIndex[35]] = checkBoxImage36.Checked; }
private void checkBoxImage37_Click(object sender, EventArgs e) { ckbState[ckbIndex[36]] = checkBoxImage37.Checked; }
private void checkBoxImage38_Click(object sender, EventArgs e) { ckbState[ckbIndex[37]] = checkBoxImage38.Checked; }
private void checkBoxImage39_Click(object sender, EventArgs e) { ckbState[ckbIndex[38]] = checkBoxImage39.Checked; }
private void checkBoxImage40_Click(object sender, EventArgs e) { ckbState[ckbIndex[39]] = checkBoxImage40.Checked; }
private void checkBoxImage41_Click(object sender, EventArgs e) { ckbState[ckbIndex[40]] = checkBoxImage41.Checked; }
private void checkBoxImage42_Click(object sender, EventArgs e) { ckbState[ckbIndex[41]] = checkBoxImage42.Checked; }
private void checkBoxImage43_Click(object sender, EventArgs e) { ckbState[ckbIndex[42]] = checkBoxImage43.Checked; }
private void checkBoxImage44_Click(object sender, EventArgs e) { ckbState[ckbIndex[43]] = checkBoxImage44.Checked; }
private void checkBoxImage45_Click(object sender, EventArgs e) { ckbState[ckbIndex[44]] = checkBoxImage45.Checked; }
private void checkBoxImage46_Click(object sender, EventArgs e) { ckbState[ckbIndex[45]] = checkBoxImage46.Checked; }
private void checkBoxImage47_Click(object sender, EventArgs e) { ckbState[ckbIndex[46]] = checkBoxImage47.Checked; }
private void checkBoxImage48_Click(object sender, EventArgs e) { ckbState[ckbIndex[47]] = checkBoxImage48.Checked; }
/// <summary>
/// Get states of checkboxes as one bitfield (long)
/// </summary>
/// <returns>Long bitfield</returns>
public long GetCheckBoxStates()
{
long result = 0;
for (int i = 0; i < 48; i++)
{
int wmNr0 = ckbIndex[i];
if (wmNr0 >= 0 && ckbState[wmNr0])
{
result += (1L << wmNr0);
}
}
return result;
}
/// <summary>
/// Set checkboxes to states stored in a bitfield (long)
/// </summary>
private void SetCheckBoxStates(long state)
{
CheckBoxImage[] chkBoxes = new CheckBoxImage[48]
{
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,
checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45,
checkBoxImage46, checkBoxImage47, checkBoxImage48,
};
for (int i = 0; i < 48; i++)
{
int wmNr0 = ckbIndex[i];
if (wmNr0 >= 0)
{
chkBoxes[i].Checked = ckbState[wmNr0] = ((state & (1L << wmNr0)) != 0);
}
}
}
private void saveButton_Click(object sender, EventArgs e)
{
Program.LocalSettings.OptoHeadsEnabled = GetCheckBoxStates();
Program.LocalSettings.Save();
DialogResult = DialogResult.OK;
Close();
}
#endregion
private void SmartCommunicationForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (!forcedClose && !formCompleted && !checkBoxesEditMode)
{
e.Cancel = true;
}
}
public void NormalClose()
{
CommCompletedHandler = null;
AllCompletedHandler = null;
_corrections?.NormalClose(waterMeterPositions0);
long checkboxStates = GetCheckBoxStates();
if (Program.LocalSettings.iPerlCommunicationsFormLeft != Location.X ||
Program.LocalSettings.iPerlCommunicationsFormTop != Location.Y ||
Program.LocalSettings.OptoHeadsEnabled != checkboxStates)
{
/// Update local settings
Program.LocalSettings.iPerlCommunicationsFormLeft = Location.X;
Program.LocalSettings.iPerlCommunicationsFormTop = Location.Y;
Program.LocalSettings.OptoHeadsEnabled = checkboxStates;
Program.LocalSettings.Save();
}
formCompleted = true;
DialogResult = DialogResult.OK;
Close();
}
}
}