/// /// Copyright (c) 2013-2019 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using log4net; using NHibernate; using Common; using Common.Forms; using Results; using Results.Forms; using Results.Entities; using TracingDB.Entities; using TBF.Resources; using TBF.UiBridge; namespace TBF.UI.ResultsMI { public partial class ResultsTabPageCtrl : UserControl { static readonly ILog log = LogManager.GetLogger(typeof(ResultsTabPageCtrl)); static readonly Color NotCompletedColor = Color.White; static readonly Color OkColor = Color.LightGreen; static readonly Color NokColor = Color.LightPink; static readonly Color RejectColor = Color.Magenta; static readonly Color ProductionTracing = Color.RoyalBlue; static readonly Color WrongDirection = Color.Gold; static readonly Color WrongQ2FactorsColor = Color.Red; public MetersArrangement MetersArrangement; public TestsArrangement TestsArrangement; public int NrMetersInOneGroup; public bool ShowDisabledPositions; public int MinWidth; public int MinHeight; public IList RsltItems_Screen_SingleWM; public IList RsltItems_Screen_CombinedWM; public IList RsltItems_Screen_HeatM; MetersKind metersKind; IList currentItems; IOneWMResultsCtrl[] wmRsltsCtrl; /// An array of controls with water meter results. IOneWMResultsCtrl firstEnabledControl; DateTime lastRedraw; DateTime lastSizeChange; int metersInOneGroup; int nrGroups; Timer timer; /// /// Constructor /// public ResultsTabPageCtrl() { InitializeComponent(); wmRsltsCtrl = new IOneWMResultsCtrl[0]; /// No water meters displayed => array with zero length firstEnabledControl = null; /// No water meters displayed => firstListView is null currentItems = new List(); nrGroups = 1; metersInOneGroup = 1; if (Program.LocalSettings != null) { MetersArrangement = Program.LocalSettings.ResultsConfigMeters; TestsArrangement = Program.LocalSettings.ResultsConfigTests; NrMetersInOneGroup = Math.Max(1, Program.LocalSettings.ResultsConfigMetersInOneGroup); ShowDisabledPositions = Program.LocalSettings.ShowDisabledPositions; MinWidth = Program.LocalSettings.ResultsConfigMinWidth; MinHeight = Program.LocalSettings.ResultsConfigMinHeight; RsltItems_Screen_SingleWM = WMeterRsltItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Screen_SingleWM); RsltItems_Screen_CombinedWM = WMeterRsltItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Screen_CombinedWM); RsltItems_Screen_HeatM = WMeterRsltItemSpec.FromStrArray(Program.LocalSettings.RsltItems_Screen_HeatM); currentItems = GetRsltItems(metersKind); } Bridge.ProcedureSelectedHandler += delegate(object sender, ProcedureSelectedEventArgs args) { if (InvokeRequired) Invoke(new EventHandler(OnProcedureSelected), sender, args); else OnProcedureSelected(sender, args); }; Bridge.TestCompletedHandler += delegate(object sender, TestCompletedEventArgs args) { if (InvokeRequired) Invoke(new EventHandler(OnTestCompleted), sender, args); else OnTestCompleted(sender, args); }; Bridge.ButtonsEtcHandler += delegate(object sndr, ButtonsEtcEventArgs args) { if (InvokeRequired) Invoke(new EventHandler(OnButtonsEtc), sndr, args); else OnButtonsEtc(sndr, args); }; lastSizeChange = DateTime.Now; /// Create a timer with one second interval. timer = new Timer(); timer.Interval = 1000; /// ms timer.Tick += new EventHandler(OnTimer); timer.Start(); } void OnProcedureSelected(object sender, ProcedureSelectedEventArgs args) { BatchResults batchResults = TBF.Rig.Sequences.ProcessData.BatchRslts; metersKind = batchResults.Batch.Compound ? MetersKind.Combined : (batchResults.Batch.HeatMeter ? MetersKind.HeatMeter : MetersKind.Single); UpdateItems(GetRsltItems(metersKind)); if ((batchResults != null) && (Program.LocalSettings != null)) { Results.Utils.GetCounterStates(batchResults.Batch, Program.LocalSettings.Counters); } if (IsLayoutChangedDueToData(batchResults)) CreateControlsAndFillPanel(batchResults); UpdateResults(batchResults); } void OnTestCompleted(object sender, TestCompletedEventArgs args) { BatchResults batchResults = TBF.Rig.Sequences.ProcessData.BatchRslts; if ((batchResults != null) && (Program.LocalSettings != null)) { Results.Utils.GetCounterStates(batchResults.Batch, Program.LocalSettings.Counters); } if (IsLayoutChangedDueToData(batchResults)) CreateControlsAndFillPanel(batchResults); UpdateResults(TBF.Rig.Sequences.ProcessData.BatchRslts); } void OnButtonsEtc(object sender, UiBridge.ButtonsEtcEventArgs args) { reloadPreviousResultsButton.Enabled = ((args.Flags & UiBridge.ButtonsEtc.ProcedureCmbBoxEn) != 0); #if TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL fixPreviousResultsButton.Visible = ((args.Flags & UiBridge.ButtonsEtc.ProcedureCmbBoxEn) != 0); #endif } private void ResultsTabPageCtrl_Load(object sender, EventArgs e) { // Localization configureButton.Text = Strings.Configure; columnWidthsButton.Text = Strings.Save_column_widths; showPreviousResultsButton.Text = Strings.Previous_results; reloadPreviousResultsButton.Text = Strings.Reload_previous_results; fixPreviousResultsButton.Text = Strings.Fix; pictureBox1.BackColor = OkColor; label1.Text = Strings.Passed; pictureBox2.BackColor = NokColor; label2.Text = Strings.Failed; #if TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL label2.Text += " (zopakovať)"; pictureBox3.BackColor = RejectColor; pictureBox3.Visible = true; label3.Text = "Vyradiť"; label3.Visible = true; pictureBox4.BackColor = WrongDirection; pictureBox4.Visible = true; label4.Text = "Otočiť smer"; label4.Visible = true; pictureBox5.BackColor = ProductionTracing; pictureBox5.Visible = true; label5.Text = "Vrátiť na predch. krok"; label5.Visible = true; #endif if ((TBF.Rig.Sequences.ProcessData.BatchRslts != null) && (Program.LocalSettings != null)) { Results.Utils.GetCounterStates(TBF.Rig.Sequences.ProcessData.BatchRslts.Batch, Program.LocalSettings.Counters); } CreateControlsAndFillPanel(TBF.Rig.Sequences.ProcessData.BatchRslts); UpdateResults(TBF.Rig.Sequences.ProcessData.BatchRslts); } IList GetRsltItems(MetersKind metersKind) { IList srcItems; switch (metersKind) { default: case MetersKind.Single: srcItems = RsltItems_Screen_SingleWM; break; case MetersKind.Combined: srcItems = RsltItems_Screen_CombinedWM; break; case MetersKind.HeatMeter: srcItems = RsltItems_Screen_HeatM; break; } IList copiedItems = new List(); if (srcItems != null) { foreach (var it in srcItems) copiedItems.Add(it.Clone()); } return copiedItems; } /// /// Handle button at the top of this form: Invoke a configuration dialog /// private void configureButton_Click(object sender, EventArgs e) { ResultsArrangementDlg dlg = new ResultsArrangementDlg { MetersKind = metersKind, TestsArrangement = TestsArrangement, MetersArrangement = MetersArrangement, NrMetersInOneGroup = NrMetersInOneGroup, ShowDisabledPositions = ShowDisabledPositions, MinWidth = MinWidth, MinHeight = MinHeight, SelectedItems = GetRsltItems(metersKind) }; DialogResult dr = dlg.ShowDialog(); if (dr == DialogResult.OK && dlg.Unlocked) { bool isLayoutChangedDueToConfig = false; if ((MetersArrangement != dlg.MetersArrangement) || (TestsArrangement != dlg.TestsArrangement) || (NrMetersInOneGroup != dlg.NrMetersInOneGroup) || (ShowDisabledPositions != dlg.ShowDisabledPositions) || (MinWidth != dlg.MinWidth) || (MinHeight != dlg.MinHeight)) { Program.LocalSettings.ResultsConfigMeters = MetersArrangement = dlg.MetersArrangement;; Program.LocalSettings.ResultsConfigTests = TestsArrangement = dlg.TestsArrangement; Program.LocalSettings.ResultsConfigMetersInOneGroup = NrMetersInOneGroup = dlg.NrMetersInOneGroup; Program.LocalSettings.ShowDisabledPositions = ShowDisabledPositions = dlg.ShowDisabledPositions; Program.LocalSettings.ResultsConfigMinWidth = MinWidth = dlg.MinWidth; Program.LocalSettings.ResultsConfigMinHeight = MinHeight = dlg.MinHeight; isLayoutChangedDueToConfig = true; } switch (metersKind) { default: case MetersKind.Single: RsltItems_Screen_SingleWM = dlg.SelectedItems; Program.LocalSettings.RsltItems_Screen_SingleWM = WMeterRsltItemSpec.ToStrArray(RsltItems_Screen_SingleWM); break; case MetersKind.Combined: RsltItems_Screen_CombinedWM = dlg.SelectedItems; Program.LocalSettings.RsltItems_Screen_CombinedWM = WMeterRsltItemSpec.ToStrArray(RsltItems_Screen_CombinedWM); break; case MetersKind.HeatMeter: RsltItems_Screen_HeatM = dlg.SelectedItems; Program.LocalSettings.RsltItems_Screen_HeatM = WMeterRsltItemSpec.ToStrArray(RsltItems_Screen_HeatM); break; } UpdateItems(dlg.SelectedItems); Program.LocalSettings.Save(); if ((TBF.Rig.Sequences.ProcessData.BatchRslts != null) && (Program.LocalSettings != null)) { Results.Utils.GetCounterStates(TBF.Rig.Sequences.ProcessData.BatchRslts.Batch, Program.LocalSettings.Counters); } if (isLayoutChangedDueToConfig) { CreateControlsAndFillPanel(TBF.Rig.Sequences.ProcessData.BatchRslts); } UpdateResults(TBF.Rig.Sequences.ProcessData.BatchRslts); } } /// /// Handle button at the top of this form: Propagate column widths /// private void columnWidthsButton_Click(object sender, EventArgs e) { if (firstEnabledControl == null) return; /// Get column widths from the first control Program.LocalSettings.RsltsClmnWidths = new int[firstEnabledControl.Columns.Count]; for (int i = 0; i < firstEnabledControl.Columns.Count; i++) { Program.LocalSettings.RsltsClmnWidths[i] = firstEnabledControl.Columns[i].Width; } Program.LocalSettings.Save(); if ((TBF.Rig.Sequences.ProcessData.BatchRslts != null) && (Program.LocalSettings != null)) { Results.Utils.GetCounterStates(TBF.Rig.Sequences.ProcessData.BatchRslts.Batch, Program.LocalSettings.Counters); } UpdateColumnWidths(Program.LocalSettings.RsltsClmnWidths); } /// /// Handle other buttons at the top of this form /// private void showPreviousResultsButton_Click(object sender, EventArgs e) { new PreviousResultsDlg().ShowDialog(); } private void reloadPreviousResultsButton_Click(object sender, EventArgs e) { new PreviousResultsDlg(PreviousResultsMode.Reload).ShowDialog(); } private void fixPreviousResultsButton_Click(object sender, EventArgs e) { new PreviousResultsDlg(PreviousResultsMode.Fix).ShowDialog(); } /// /// Handle double-click inside a water meter results control /// void OnDoubleClick(object sender, WaterMeterEventArgs args) { if (TBF.Rig.Sequences.ProcessData.BatchRslts.Batch != null && TBF.Rig.Sequences.ProcessData.BatchRslts.Batch.WaterMeters != null) { foreach (var wm in TBF.Rig.Sequences.ProcessData.BatchRslts.Batch.WaterMeters) { if (wm.WMPosition == args.WMPosition) { ShowMoreWMResults(wm); return; } } } MessageBox.Show(Strings.No_water_meter); } void UpdateColumnWidths(int[] columnWidths) { foreach (var ctrl in wmRsltsCtrl) ctrl.Update(columnWidths); } void UpdateScrollpositions(int scrollStart) { /// TODO } void UpdateItems(IList items) { bool updateItems = false; if (currentItems.Count != items.Count) { /// Current and new item counts are different updateItems = true; } else { /// Current and new item counts are the same for (int i = 0; i < currentItems.Count; i++) { if (currentItems[i] != items[i]) { updateItems = true; break; } } } if (updateItems) { /// Update items in all controls currentItems = items; foreach (var oneCtrl in wmRsltsCtrl) oneCtrl.Update(items); } } bool IsLayoutChangedDueToData(BatchResults results) { if (results == null || results.Batch == null || results.Batch.WaterMeters == null || results.Batch.WaterMeters.Count == 0) { /// 'results' contain no water meters, wmRsltsCtrl.Lenght == 0 expected return (wmRsltsCtrl.Length != 0); /// true when there are currently water meters on screen } /// /// Determine water meter positions count /// int displayedWatermetersCount = 0; for (int i = 0; i < results.Batch.WaterMeters.Count; i++) { if (results.Batch.WaterMeters[i] != null) { if (ShowDisabledPositions || !results.Batch.WaterMeters[i].Disabled) { displayedWatermetersCount++; } } } return (displayedWatermetersCount != wmRsltsCtrl.Length); } /// /// Re-draw the results. Apply new settings if they changed. /// void CreateControlsAndFillPanel(BatchResults results) { if ((results == null) || (results.WMPositionsCount == 0)) { /// There are no water meters at all DeleteHandlers(); flowLayoutPanel.Controls.Clear(); wmRsltsCtrl = new OneWMResultsRowsCtrl[0]; firstEnabledControl = null; return; } /// /// Determine water meter positions count /// int displayedControlsCount = 0; for (int i = 0; i < results.Batch.WaterMeters.Count; i++) { if (results.Batch.WaterMeters[i] != null) { if (ShowDisabledPositions || !results.Batch.WaterMeters[i].Disabled) { displayedControlsCount++; } } } /// /// Calculate geometry /// metersInOneGroup = Math.Max(1, Math.Min(displayedControlsCount, NrMetersInOneGroup)); nrGroups = Math.Max(1, (displayedControlsCount + metersInOneGroup - 1) / metersInOneGroup); int oneWidth; int oneHeight; /// if (MetersArrangement == MetersArrangement.Horizontally) { flowLayoutPanel.FlowDirection = FlowDirection.LeftToRight; oneWidth = Math.Max(MinWidth, flowLayoutPanel.Width / metersInOneGroup - 6); oneHeight = Math.Max(MinHeight, flowLayoutPanel.Height / nrGroups - 6); } else { flowLayoutPanel.FlowDirection = FlowDirection.TopDown; oneWidth = Math.Max(MinWidth, flowLayoutPanel.Width / nrGroups - 6); oneHeight = Math.Max(MinHeight, flowLayoutPanel.Height / metersInOneGroup - 6); } /// /// Create controls and fill the FlowLayoutPanel /// flowLayoutPanel.SuspendLayout(); DeleteHandlers(); flowLayoutPanel.Controls.Clear(); flowLayoutPanel.WrapContents = true; flowLayoutPanel.AutoScroll = true; wmRsltsCtrl = new IOneWMResultsCtrl[displayedControlsCount]; int ix = 0; firstEnabledControl = null; for (int i = 0; i < results.Batch.WaterMeters.Count; i++) { if (results.Batch.WaterMeters[i] != null) { if (!results.Batch.WaterMeters[i].Disabled || ShowDisabledPositions) { /// Create one water meter position / control wmRsltsCtrl[ix] = (TestsArrangement == TestsArrangement.Rows) ? new OneWMResultsRowsCtrl() as IOneWMResultsCtrl : new OneWMResultsColumnsCtrl() as IOneWMResultsCtrl; wmRsltsCtrl[ix].Width = oneWidth; wmRsltsCtrl[ix].Height = oneHeight; wmRsltsCtrl[ix].Update(currentItems); wmRsltsCtrl[ix].WMResultsClickedHandler += HandleDoubleClick; flowLayoutPanel.Controls.Add(wmRsltsCtrl[ix] as UserControl); if ((firstEnabledControl == null) && !results.Batch.WaterMeters[i].Disabled) firstEnabledControl = wmRsltsCtrl[ix]; ix++; } } } UpdateColumnWidths(Program.LocalSettings.RsltsClmnWidths); flowLayoutPanel.ResumeLayout(); } void HandleDoubleClick(object s, WaterMeterEventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(OnDoubleClick), s, args); } else { OnDoubleClick(s, args); } } /// /// Delete handler subscriptions from controls (memory leak if not done???). /// To be done before flowLayoutPanel.Controls.Clear(). /// void DeleteHandlers() { foreach (var ctrl in flowLayoutPanel.Controls) { if (ctrl is IOneWMResultsCtrl) { (ctrl as IOneWMResultsCtrl).WMResultsClickedHandler -= HandleDoubleClick; } } } void UpdateResults(BatchResults batchResults) { if (batchResults != null && batchResults.Batch != null && batchResults.Batch.WaterMeters != null) { int ctrlIx = 0; for (int i = 0; i < batchResults.Batch.WaterMeters.Count; i++) { if (!batchResults.Batch.WaterMeters[i].Disabled || ShowDisabledPositions) { if (ctrlIx < wmRsltsCtrl.Length) wmRsltsCtrl[ctrlIx++].Update(batchResults.Batch.WaterMeters[i]); } } } } void ShowMoreWMResults(WaterMeter wm) { if ((TracingDB.DB.SessionFactory == null) || string.IsNullOrEmpty(wm.SerialNr)) { new MoreWMResultsDlg(wm, null).ShowDialog(); } else { using (ISession session = TracingDB.DB.SessionFactory.OpenSession()) { IList refRecords = session.QueryOver() .Where(x => (x.Code == wm.SerialNr)) .OrderBy(x => x.TimeStamp).Desc .List(); for (int i = 0; i < refRecords.Count; i++) { ReferenceRecord refR = refRecords[i]; if ((refR.Records != null) && (refR.Records.Count > 0)) { /// Reference record has additional records/parts (i.e. it is PCB assembly workflow step) /// foreach (var rec in refR.Records) { if (!string.IsNullOrEmpty(rec.Part.OraDBType) && rec.Part.OraDBType.ToLower().Contains("flowtube")) { /// rec.Part is a flowtube /// IList flowtubeRRs = session.QueryOver() .Where(x => (x.Code == rec.Code)) .OrderBy(x => x.TimeStamp).Desc .List(); foreach (var rr in flowtubeRRs) refRecords.Add(rr); break; } } } } new MoreWMResultsDlg(wm, refRecords).ShowDialog(); } } } private void flowLayoutPanel_SizeChanged(object sender, EventArgs e) { lastSizeChange = DateTime.Now; } private void OnTimer(object source, EventArgs e) { if (DateTime.Compare(lastSizeChange, lastRedraw) > 0) { /// The last size change was more recent then the last redraw DateTime now = DateTime.Now; if (DateTime.Compare(lastSizeChange + new TimeSpan(0, 0, 1), now) < 0) { /// More then 1 second since the last panel size change /// Calculate geometry int oneWidth; int oneHeight; /// if (MetersArrangement == MetersArrangement.Horizontally) { flowLayoutPanel.FlowDirection = FlowDirection.LeftToRight; oneWidth = Math.Max(MinWidth, flowLayoutPanel.Width / metersInOneGroup - 6); oneHeight = Math.Max(MinHeight, flowLayoutPanel.Height / nrGroups - 6); } else { flowLayoutPanel.FlowDirection = FlowDirection.TopDown; oneWidth = Math.Max(MinWidth, flowLayoutPanel.Width / nrGroups - 6); oneHeight = Math.Max(MinHeight, flowLayoutPanel.Height / metersInOneGroup - 6); } /// Update size of controls flowLayoutPanel.SuspendLayout(); /// foreach (var oneCtrl in wmRsltsCtrl) { oneCtrl.Width = oneWidth; oneCtrl.Height = oneHeight; } /// flowLayoutPanel.ResumeLayout(); } } } private void deleteFromOracleButton_Click(object sender, EventArgs e) { var dlg = new DeleteFromOracleForm(); GID[] rqrdGroupMembership = new GID[] { GID.TraceabilityManagement }; /// Restricted access to Delete from Oracle Form if ((new Users.Forms.LoginDlg(Users.CurrentUser.UserName(), rqrdGroupMembership, dlg)).ShowDialog() == DialogResult.OK) { if (dlg.ShowDialog() == DialogResult.OK) MessageBox.Show("Successfully deleted from Oracle"); } } } }