/// /// Copyright (c) 2013-2017 Sensus Metering Systems /// using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; using log4net; using NHibernate; using Config.Entities; using Common.Forms; using TBF.Rig.Generic; using TBF.Rig.GenericDevices; using TBF.Resources; using TBF.UI.Shared; namespace TBF.UI.Bench.Transitions { public partial class TransitionsDlg : Form, IParentOfListViewEx { static readonly ILog log = LogManager.GetLogger(typeof(TransitionsDlg)); /// Used when re-scaling the dialog: 100% = 96dpi, 125% = 120dpi, 150% = 144dpi public readonly int Dpi; /// /// Fluent-NHibernate database session /// public ISession Session; IList procedures; IList tests; Dictionary renameInfo; /// Pairs original name / new name /// /// Transition sequences to be updated by this dialog. /// Set by the constructor or updated by the parent after creation and before loading. /// public IList TransitionSequences; public IList RemovedTransitionSequences; /// /// Virtual bench sequences to be updated by this dialog. /// Set by the constructor or updated by the parent after creation and before loading. /// public IList VirtualBenchSequences; public IList RemovedVirtualBenchSequences; /// Auxiliary public lists used also by user controls in tab pages public IList TbfComponents; public IList Valves; public IList RegulValves; IList seqStepsCtrls; public TransitionsDlg() { /// Detect display setting: 100% = 96dpi, 125% = 120dpi, 150% = 144dpi. Dpi = (int)this.CreateGraphics().DpiX; InitializeComponent(); /// SharedDlgButtons configuration sharedButtons.ParentForm = this; sharedButtons.RequiredGroupMembership = new Common.GID[] { Common.GID.Metrologists }; sharedButtons.OptionalButtons = SharedButtons.Buttons.Add | SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down | SharedButtons.Buttons.Export | SharedButtons.Buttons.Import | SharedButtons.Buttons.Compare | SharedButtons.Buttons.NewTab | SharedButtons.Buttons.RenameTab | SharedButtons.Buttons.RemoveTab; sharedButtons.Unlocked += Unlocked; sharedButtons.OKClicked += okButton_Click; sharedButtons.CancelClicked += cancelButton_Click; sharedButtons.AddClicked += addButton_Click; sharedButtons.RemoveClicked += removeButton_Click; sharedButtons.UpClicked += upButton_Click; sharedButtons.DownClicked += downButton_Click; sharedButtons.ExportClicked += exportButton_Click; sharedButtons.ImportClicked += importButton_Click; sharedButtons.CompareClicked += compareButton_Click; sharedButtons.NewTabClicked += newTabButton_Click; sharedButtons.RenameTabClicked += renameTabButton_Click; sharedButtons.RemoveTabClicked += removeTabButton_Click; seqStepsCtrls = new List(); /// Open the database Session = TBF.DB.CreateSession(Common.DBKind.Config); /// Prepare a list of components and a list of all valves in the test bench TbfComponents = Rig.TbfComponents.LoadComponentsFromDB(Session); Valves = Rig.GenericDevices.ValveBase.MasterValves(TbfComponents); RegulValves = new List(); foreach (var cmpnt in TbfComponents) { if ((cmpnt is IRegValve) && !(cmpnt is Rig.Elde.RegulValveTandem.RegulValveTandem)) { RegulValves.Add(cmpnt as IRegValve); } } /// Load the sequences /// Note: Each sequence (in both sequences together) has a unique ItemNr (0 .. N-1) TransitionSequences = Session.QueryOver().OrderBy(x => x.ItemNr).Asc.List(); VirtualBenchSequences = Session.QueryOver().OrderBy(x => x.ItemNr).Asc.List(); procedures = Session.QueryOver().List(); tests = Session.QueryOver().List(); RemovedTransitionSequences = new List(); RemovedVirtualBenchSequences = new List(); /// Create a tab with sequence steps for each sequence ordered by ItemNr. foreach (var transSeq in TransitionSequences) { transSeq.OriName = transSeq.Name; AddTransitionSeqTab(transSeq); } foreach (var vBenchSeq in VirtualBenchSequences) { vBenchSeq.OriName = vBenchSeq.Name; AddVirtualBenchSeqTab(vBenchSeq); } } void AddTransitionSeqTab(TransitionSequence sequence) { TabPage nwTab = new TabPage(sequence.Name); nwTab.Tag = sequence; TransitionStepsCtrl newCtrl = new TransitionStepsCtrl(); seqStepsCtrls.Add(newCtrl); nwTab.Controls.Add(newCtrl); tabControl.TabPages.Add(nwTab); newCtrl.Initialize(sequence, this, tabControl.TabPages[tabControl.TabPages.Count - 1]); newCtrl.SelectedIndexChanged += new System.EventHandler(SelectedIndexChanged); } void AddVirtualBenchSeqTab(VirtualBenchSequence sequence) { TabPage nwTab = new TabPage(sequence.Name); nwTab.Tag = sequence; VirtualBenchStepsCtrl newCtrl = new VirtualBenchStepsCtrl(); seqStepsCtrls.Add(newCtrl); nwTab.Controls.Add(newCtrl); tabControl.TabPages.Add(nwTab); newCtrl.Initialize(sequence, this, tabControl.TabPages[tabControl.TabPages.Count - 1]); newCtrl.SelectedIndexChanged += new System.EventHandler(SelectedIndexChanged); } private void TransitionsDlg_Load(object sender, EventArgs e) { Localize(); LoadUISettings(); /// Now refresh the content of the dialog RefreshAllTabs(); } void Localize() { Text = Strings.Transitions; } void RefreshAllTabs() { foreach (var ctrl in seqStepsCtrls) (ctrl as ListViewEx).Refresh(); } private void Unlocked(object sender, EventArgs e) { foreach (var ctrl in seqStepsCtrls) ctrl.Unlock(); } private void newTabButton_Click(object sender, EventArgs e) { TabNameDlg dlg; bool nameUsed; int tabId = TransitionSequences.Count + VirtualBenchSequences.Count; do { /// Find an unused procedure name string newName; for (int nameId = 1; true; nameId++) { newName = "Tr" + nameId.ToString(); nameUsed = false; foreach (var seq in TransitionSequences) if (seq.Name.Equals(newName)) nameUsed = true; if (!nameUsed) break; } dlg = new TabNameDlg(); dlg.TabNameLabel = Strings.New_transition_name; dlg.TabName = newName; if (DialogResult.OK != dlg.ShowDialog()) return; foreach (var seq in TransitionSequences) if (seq.Name.Equals(dlg.TabName)) nameUsed = true; if (nameUsed) MessageBox.Show(Strings.Please_choose_another_transition_sequence_name, Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Information); } while (nameUsed); if (dlg.IsVirtualBenchSeq) { VirtualBenchSequence sequence = new VirtualBenchSequence(dlg.TabName, tabId); VirtualBenchSequences.Add(sequence); AddVirtualBenchSeqTab(sequence); seqStepsCtrls[tabId].Unlock(); } else { TransitionSequence sequence = new TransitionSequence(dlg.TabName, tabId); TransitionSequences.Add(sequence); AddTransitionSeqTab(sequence); seqStepsCtrls[tabId].Unlock(); } tabControl.SelectTab(tabId); } private void renameTabButton_Click(object sender, EventArgs e) { TabPage tabPage = tabControl.SelectedTab; TransitionSequence transitionSeq = tabPage.Tag as TransitionSequence; VirtualBenchSequence virtualBenchSeq = tabPage.Tag as VirtualBenchSequence; TabNameDlg dlg = new TabNameDlg(true); dlg.TabNameLabel = Strings.New_transition_name; if (dlg.ShowDialog() == DialogResult.OK) { bool nameUsed = false; foreach (var seq in TransitionSequences) if (seq != transitionSeq && seq.Name == dlg.TabName) nameUsed = true; foreach (var seq in VirtualBenchSequences) if (seq != virtualBenchSeq && seq.Name == dlg.TabName) nameUsed = true; if (nameUsed) { MessageBox.Show(Strings.Please_choose_another_transition_sequence_name, Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Information); } else { if (transitionSeq != null) { transitionSeq.Name = dlg.TabName; tabPage.Text = dlg.TabName; } else if (virtualBenchSeq != null) { virtualBenchSeq.Name = dlg.TabName; tabPage.Text = dlg.TabName; } } } } private void removeTabButton_Click(object sender, EventArgs e) { TabPage tabPage = tabControl.SelectedTab; TransitionSequence transitionSeq = tabPage.Tag as TransitionSequence; VirtualBenchSequence virtualBenchSeq = tabPage.Tag as VirtualBenchSequence; if (DialogResult.Yes == MessageBox.Show(string.Format(Strings.Do_you_really_want_to_delete_sequence_0, tabPage.Text), Strings.Warning, MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { if (transitionSeq != null) { RemovedTransitionSequences.Add(transitionSeq); TransitionSequences.Remove(transitionSeq); tabControl.TabPages.Remove(tabPage); } else if (virtualBenchSeq != null) { RemovedVirtualBenchSequences.Add(virtualBenchSeq); VirtualBenchSequences.Remove(virtualBenchSeq); tabControl.TabPages.Remove(tabPage); } } } void RetrieveData() { if (seqStepsCtrls.Count > slctdTab) seqStepsCtrls[slctdTab].OkBtnClicked(); } string GetWarningsBeforeSaving(ref Dictionary renmInfo) { string warnings = string.Empty; renmInfo = new Dictionary(); foreach (var seq in RemovedTransitionSequences) { if (!string.IsNullOrEmpty(seq.OriName)) { int occurances = 0; foreach (var test in tests) { if (!string.IsNullOrEmpty(test.TransBefore) && test.TransBefore == seq.OriName) occurances++; if (!string.IsNullOrEmpty(test.TransAfter) && test.TransAfter == seq.OriName) occurances++; } foreach (var proc in procedures) { if (!string.IsNullOrEmpty(proc.TransitionStart) && proc.TransitionStart == seq.OriName) occurances++; if (!string.IsNullOrEmpty(proc.TransitionEnd) && proc.TransitionEnd == seq.OriName) occurances++; } if (occurances > 0) { warnings += string.Format("Deleting transition sequence {0} used in {1} tests and procedures{2}", seq.OriName, occurances, Environment.NewLine); renmInfo.Add(seq.OriName, string.Empty); } } } foreach (var seq in RemovedVirtualBenchSequences) { if (!string.IsNullOrEmpty(seq.OriName)) { int occurances = 0; foreach (var test in tests) { if (!string.IsNullOrEmpty(test.TransBefore) && test.TransBefore == seq.OriName) occurances++; if (!string.IsNullOrEmpty(test.TransAfter) && test.TransAfter == seq.OriName) occurances++; } foreach (var proc in procedures) { if (!string.IsNullOrEmpty(proc.TransitionStart) && proc.TransitionStart == seq.OriName) occurances++; if (!string.IsNullOrEmpty(proc.TransitionEnd) && proc.TransitionEnd == seq.OriName) occurances++; } if (occurances > 0) { warnings += string.Format("Deleting virtual bench sequence {0} used in {1} tests and procedures{2}", seq.OriName, occurances, Environment.NewLine); renmInfo.Add(seq.OriName, string.Empty); } } } foreach (var seq in TransitionSequences) { if (!string.IsNullOrEmpty(seq.OriName) && seq.OriName != seq.Name) { int occurances = 0; foreach (var test in tests) { if (!string.IsNullOrEmpty(test.TransBefore) && test.TransBefore == seq.OriName) occurances++; if (!string.IsNullOrEmpty(test.TransAfter) && test.TransAfter == seq.OriName) occurances++; } foreach (var proc in procedures) { if (!string.IsNullOrEmpty(proc.TransitionStart) && proc.TransitionStart == seq.OriName) occurances++; if (!string.IsNullOrEmpty(proc.TransitionEnd) && proc.TransitionEnd == seq.OriName) occurances++; } if (occurances > 0) { warnings += string.Format("Renaming transition sequence {0} used in {1} tests and procedures{2}", seq.OriName, occurances, Environment.NewLine); renmInfo.Add(seq.OriName, seq.Name); } } } foreach (var seq in VirtualBenchSequences) { if (!string.IsNullOrEmpty(seq.OriName) && seq.OriName != seq.Name) { int occurances = 0; foreach (var test in tests) { if (!string.IsNullOrEmpty(test.TransBefore) && test.TransBefore == seq.OriName) occurances++; if (!string.IsNullOrEmpty(test.TransAfter) && test.TransAfter == seq.OriName) occurances++; } foreach (var proc in procedures) { if (!string.IsNullOrEmpty(proc.TransitionStart) && proc.TransitionStart == seq.OriName) occurances++; if (!string.IsNullOrEmpty(proc.TransitionEnd) && proc.TransitionEnd == seq.OriName) occurances++; } if (occurances > 0) { warnings += string.Format("Renaming virtual bench sequence {0} used in {1} tests and procedures{2}", seq.OriName, occurances, Environment.NewLine); renmInfo.Add(seq.OriName, seq.Name); } } } return warnings; } private void okButton_Click(object sender, EventArgs e) { RetrieveData(); string warnings = GetWarningsBeforeSaving(ref renameInfo); bool updateRelatedItems = false; if (!string.IsNullOrEmpty(warnings)) { string message = string.Format("{0}{1}{2}", warnings, Environment.NewLine, Strings.Do_you_want_to_update_related_tests_and_procedures); DialogResult dr = MessageBox.Show(message, Strings.Warning, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation); if (dr == DialogResult.Cancel) { DialogResult = DialogResult.Cancel; return; } else if (dr == DialogResult.Yes) { updateRelatedItems = true; } } Cursor.Current = Cursors.WaitCursor; using (var transaction = Session.BeginTransaction()) { try { if (updateRelatedItems) { foreach (var ri in renameInfo) { var tests = Session.QueryOver() .Where(x => (x.TransBefore == ri.Key)) .List(); foreach (var t in tests) { t.TransBefore = ri.Value; Session.Update(t); } tests = Session.QueryOver() .Where(x => (x.TransAfter == ri.Key)) .List(); foreach (var t in tests) { t.TransAfter = ri.Value; Session.Update(t); } var procedures = Session.QueryOver() .Where(x => (x.TransitionStart == ri.Key)) .List(); foreach (var p in procedures) { p.TransitionStart = ri.Value; Session.Update(p); } procedures = Session.QueryOver() .Where(x => (x.TransitionEnd == ri.Key)) .List(); foreach (var p in procedures) { p.TransitionEnd = ri.Value; Session.Update(p); } } } foreach (var transSeq in RemovedTransitionSequences) { foreach (var step in transSeq.TransitionSteps) Session.Delete(step); Session.Delete(transSeq); } foreach (var vBnchSeq in RemovedVirtualBenchSequences) { foreach (var step in vBnchSeq.VirtualBenchSteps) Session.Delete(step); Session.Delete(vBnchSeq); } int itemNr = 0; foreach (var transSeq in TransitionSequences) { transSeq.ItemNr = itemNr++; Session.SaveOrUpdate(transSeq); } itemNr = 0; foreach (var vBnchSeq in VirtualBenchSequences) { vBnchSeq.ItemNr = itemNr++; Session.SaveOrUpdate(vBnchSeq); } transaction.Commit(); } catch (Exception e2) { transaction.Rollback(); Cursor.Current = Cursors.Default; MessageBox.Show(Strings.Cannot_save_changes, Strings.Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); log.ErrorFormat("Update of sequences in the database failed: {0}", e2.Message); } } Cursor.Current = Cursors.Default; SaveUISettings(); DialogResult = DialogResult.OK; Close(); return; } private void cancelButton_Click(object sender, EventArgs e) { SaveUISettings(); DialogResult = DialogResult.Cancel; Close(); return; } private void SaveUISettings() { /// Obtain TransitionsDlg dimensions, etc. bool isMaximized = (WindowState == FormWindowState.Maximized); int left = (WindowState == FormWindowState.Normal) ? Location.X : RestoreBounds.Left; int top = (WindowState == FormWindowState.Normal) ? Location.Y : RestoreBounds.Top; int width = (WindowState == FormWindowState.Normal) ? Size.Width : RestoreBounds.Width; int height = (WindowState == FormWindowState.Normal) ? Size.Height : RestoreBounds.Height; LocalSettings ls = Program.LocalSettings; if (ls != null && (ls.TransitionsDlgMaximized != isMaximized || ls.TransitionsDlgLeft != left || ls.TransitionsDlgTop != top || ls.TransitionsDlgWidth != width || ls.TransitionsDlgHeight != height)) { /// At least one TransitionsDlg dimension differs => Update local settings and save them ls.TransitionsDlgMaximized = isMaximized; ls.TransitionsDlgLeft = left; ls.TransitionsDlgTop = top; ls.TransitionsDlgWidth = width; ls.TransitionsDlgHeight = height; ls.Save(); } } private void LoadUISettings() { TBF.LocalSettings ls = Program.LocalSettings; WindowState = (ls.TransitionsDlgMaximized ? FormWindowState.Maximized : FormWindowState.Normal); Width = (ls.TransitionsDlgWidth > 0) ? ls.TransitionsDlgWidth : 1050; Height = (ls.TransitionsDlgHeight > 0) ? ls.TransitionsDlgHeight : 650; Left = (ls.TransitionsDlgLeft != 0) ? ls.TransitionsDlgLeft : 100; Top = (ls.TransitionsDlgTop != 0) ? ls.TransitionsDlgTop : 100; } int slctdTab; private void tabControl_SelectedIndexChanged(object sender, EventArgs e) { if (seqStepsCtrls.Count > slctdTab) { seqStepsCtrls[slctdTab].OkBtnClicked(); } slctdTab = tabControl.SelectedIndex; sharedButtons.EnableButtons(SharedButtons.Buttons.Add); sharedButtons.DisableButtons(SharedButtons.Buttons.Remove); RefreshAllTabs(); } private void addButton_Click(object sender, EventArgs e) { if (seqStepsCtrls.Count > slctdTab) seqStepsCtrls[slctdTab].AddOne(); } private void removeButton_Click(object sender, EventArgs e) { if (seqStepsCtrls.Count > slctdTab) seqStepsCtrls[slctdTab].RemoveSelected(); } private void upButton_Click(object sender, EventArgs e) { if (seqStepsCtrls.Count > slctdTab) seqStepsCtrls[slctdTab].MoveUpSelected(); } private void downButton_Click(object sender, EventArgs e) { if (seqStepsCtrls.Count > slctdTab) seqStepsCtrls[slctdTab].MoveDownSelected(); } public void UpdateButtonStates(SharedButtons.SelectedItemPos selectedItemPos) { if (selectedItemPos == SharedButtons.SelectedItemPos.None) { sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down); } else if (selectedItemPos == SharedButtons.SelectedItemPos.First) { sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Down); sharedButtons.DisableButtons(SharedButtons.Buttons.Up); } else if (selectedItemPos == SharedButtons.SelectedItemPos.Last) { sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up); sharedButtons.DisableButtons(SharedButtons.Buttons.Down); } else if (selectedItemPos == SharedButtons.SelectedItemPos.FirstAndLast) { sharedButtons.EnableButtons(SharedButtons.Buttons.Remove); sharedButtons.DisableButtons(SharedButtons.Buttons.Up | SharedButtons.Buttons.Down); } else { sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down); } } /// /// Common part for three xxxListViewEx_SelectedIndexChanged event handlers /// /// void SelectedIndexChanged(object sender, EventArgs e) { ListViewEx listViewEx = sender as ListViewEx; if (listViewEx.SelectedItems.Count != 1) { UpdateButtonStates(SharedButtons.SelectedItemPos.None); } else if (listViewEx.Items.Count == 1) { UpdateButtonStates(SharedButtons.SelectedItemPos.FirstAndLast); } else if (listViewEx.SelectedIndices[0] == 0) { UpdateButtonStates(SharedButtons.SelectedItemPos.First); } else if (listViewEx.SelectedIndices[0] == (listViewEx.Items.Count - 1)) { UpdateButtonStates(SharedButtons.SelectedItemPos.Last); } else { UpdateButtonStates(SharedButtons.SelectedItemPos.Middle); } } private void exportButton_Click(object sender, EventArgs e) { TabPage tabPage = tabControl.SelectedTab; TransitionSequence transitionSeq = tabPage.Tag as TransitionSequence; VirtualBenchSequence virtualBenchSeq = tabPage.Tag as VirtualBenchSequence; SaveFileDialog dlg = new SaveFileDialog(); if (dlg.ShowDialog() == DialogResult.OK) { if (transitionSeq != null) { /// export transition sequence transitionSeq.Export(new StreamWriter(dlg.FileName, false, System.Text.Encoding.UTF8)); } else if (virtualBenchSeq != null) { /// export virtual sequence virtualBenchSeq.Export(new StreamWriter(dlg.FileName, false, System.Text.Encoding.UTF8)); } } } private void importButton_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); if (dlg.ShowDialog() != DialogResult.OK) return; /// Import a procedure from a file int tabId = TransitionSequences.Count + VirtualBenchSequences.Count; TransitionSequence newSequence = TransitionSequence.Import(new StreamReader(dlg.FileName, System.Text.Encoding.UTF8)); newSequence.ItemNr = tabId; /// Find an unused procedure name string newName; bool nameUsed; for (int nameId = 1; true; nameId++) { newName = string.Format("{0} imported{1}", newSequence.Name, (nameId == 1) ? string.Empty : string.Format("({0})", nameId)); nameUsed = false; foreach (var seq in TransitionSequences) if (seq.Name.Equals(newName)) nameUsed = true; if (!nameUsed) break; } newSequence.Name = newName; TransitionSequences.Add(newSequence); AddTransitionSeqTab(newSequence); seqStepsCtrls[tabId].Unlock(); tabControl.SelectTab(tabId); } private void compareButton_Click(object sender, EventArgs e) { MessageBox.Show("Comparing sequences in not implemented yet"); } private void TransitionsDlg_FormClosing(object sender, FormClosingEventArgs e) { if (Users.CurrentUser.Restore(this)) Program.MainWnd.UpdateUser(); } } }