using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.IO; using VEPROMS.CSLA.Library; using DevComponents.DotNetBar; using DevComponents.AdvTree; using System.Text.RegularExpressions; using Volian.Base.Library; namespace Volian.Controls.Library { public partial class DisplayReports : UserControl { #region Public Events/Handlers public event DisplayReportsEvent PrintRequest; private void OnPrintRequest(DisplayReportsEventArgs args) { if (PrintRequest != null) PrintRequest(this, args); } #endregion #region Fields // B2022-026 RO Memeory reduction logic change - defined dummy node text variable to ensure consistancy private const string DummyNodeText = "VLN_DUMMY_NODE"; private List lstCheckedDocVersions = new List(); private List lstCheckedROs = new List(); private List lstReportResults = new List(); private List ROList = new List(); private List lstROObj = new List(); private int _MyRODbID; private DocVersionInfo _MyDocVersion; private ROFSTLookup _MyROFSTLookup; private ItemInfoList _ReportResult; private Dictionary AccIDROIDdic = new Dictionary(); static int blankKeyCnt = 0; #endregion #region Properties private string DocVersionList { get { // append list of document versions to search if (lstCheckedDocVersions.Count > 0) { string strRtnStr = ""; // get list of doc versions to search foreach (DocVersionInfo dvi in lstCheckedDocVersions) { strRtnStr += string.Format(",{0}", dvi.VersionID.ToString()); } return strRtnStr.Substring(1); } return ""; } } public DocVersionInfo Mydocversion { get { return _MyDocVersion; } set { if (DesignMode) return; // B2019-043 need to check if we are just saving changes to the user interface _MyDocVersion = value; if (_MyDocVersion != null) { if (_MyDocVersion.DocVersionAssociationCount > 0) { // if the count variable is not consistent with the actual list count, // do a refresh. There was a bug, B2012-040, that was not reproducable.. // so this is an attempt to fix it. if (_MyDocVersion.DocVersionAssociations.Count == 0) { _MyDocVersion.RefreshDocVersionAssociations(); if (_MyDocVersion.DocVersionAssociations.Count == 0) return; } MyROFSTLookup = _MyDocVersion.DocVersionAssociations[0].MyROFst.GetROFSTLookup(_MyDocVersion); _MyRODbID = _MyDocVersion.DocVersionAssociations[0].MyROFst.RODbID; } } } } public ROFSTLookup MyROFSTLookup { get { return _MyROFSTLookup; } set { if (DesignMode) return; // B2019-043 need to check if we are just saving changes to the user interface //if (!Visible) return; // don't reset anything if the form is invisible. _MyROFSTLookup = value; // define the tree nodes based on this rofst advTreeROFillIn(true); //LoadROComboTree(); } } public ItemInfoList ReportResult { get { return _ReportResult; } set { _ReportResult = value; } } #endregion #region Constructors public DisplayReports() { InitializeComponent(); EnableOrDisablePrintButton(); cmbxROUsageSort.SelectedIndex = 0; tabTransitionReports.Visible = false; cbxComplete.Enabled = true; cbxSummary.Enabled = true; if (cbxROUsage.Checked) cbxIncldMissingROs.Text = "Include Missing ROs (red ? in the editor)"; else if (cbxComplete.Checked) cbxIncldMissingROs.Text = "Include Empty RO Fields"; cbxIncldMissingROs.Checked = false;// !cbxSummary.Checked; cbxIncldMissingROs.Visible = cbxROUsage.Checked || cbxComplete.Checked; cbxSortBySetpointID.Checked = false; cbxSortBySetpointID.Visible = cbxComplete.Checked || cbxSummary.Checked; } #endregion #region Public Methods public void SelectReferencedObjectTab() { tabROReports.PerformClick(); } public void advTreeROFillIn(bool blSeachTabClicked) { DevComponents.AdvTree.Node topnode = null; advTreeRO.Nodes.Clear(); if (_MyROFSTLookup == null) return; advTreeRO.BeforeExpand += new AdvTreeNodeCancelEventHandler(advTreeRO_BeforeExpand); advTreeRO.AfterExpand += new AdvTreeNodeEventHandler(advTreeRO_AfterExpandorCollapse); advTreeRO.AfterCollapse += new AdvTreeNodeEventHandler(advTreeRO_AfterExpandorCollapse); topnode = new DevComponents.AdvTree.Node(); topnode.Text = "All Referenced Objects"; topnode.Tag = null; topnode.CheckBoxVisible = true; advTreeRO.Nodes.Add(topnode); ROFSTLookup.rodbi[] dbs = _MyROFSTLookup.GetRODatabaseList(true); if (dbs != null && dbs.Length > 0) { for (int i = 0; i < dbs.Length; i++) { DevComponents.AdvTree.Node tn = new DevComponents.AdvTree.Node(); ROFSTLookup.rodbi db = dbs[i]; tn.Text = db.dbiTitle; tn.Tag = db; tn.CheckBoxVisible = true; topnode.Nodes.Add(tn); AddDummyGroup(db, tn); } } } public void advTreeProcSetsFillIn(bool blSeachTabClicked) { DevComponents.AdvTree.Node topnode = null; int cntnd = 0; VETreeNode vtn = VETreeNode.GetFolder(1); FolderInfo fi = vtn.VEObject as FolderInfo; int fiCount = fi.ChildFolderCount; advTreeProcSets.Nodes.Clear(); lstCheckedDocVersions.Clear(); topnode = new DevComponents.AdvTree.Node(); topnode.Text = "Available Procedure Sets"; topnode.Tag = fi; advTreeProcSets.Nodes.Add(topnode); //advTreeProcSets.AfterNodeInsert += new TreeNodeCollectionEventHandler(advTreeProcSets_AfterNodeInsert); foreach (FolderInfo fic in fi.SortedChildFolders) { DevComponents.AdvTree.Node newnode = new DevComponents.AdvTree.Node(); newnode.Text = fic.ToString(); newnode.Tag = fic; //int tmp; //if (topnode == null) //{ // newnode.Text = "Available Procedure Sets"; // tmp = advTreeProcSets.Nodes.Add(newnode); // topnode = newnode; //} //else //{ // newnode.Selectable = true; // newnode.CheckBoxAlignment = DevComponents.AdvTree.eCellPartAlignment.NearCenter; // newnode.CheckBoxStyle = eCheckBoxStyle.CheckBox; // newnode.CheckBoxThreeState = false; // newnode.CheckBoxVisible = true; // tmp = topnode.Nodes.Add(newnode); //} cntnd++; if (fic.ChildFolderCount > 0 || fic.FolderDocVersionCount > 0) // allow for '+' for tree expansion { DevComponents.AdvTree.Node tnt = new DevComponents.AdvTree.Node(); tnt.Text = DummyNodeText; newnode.Nodes.Add(tnt); topnode.Nodes.Add(newnode); } } // if nothing was added to the tree, just put in the node above the docversions... if (advTreeProcSets.Nodes.Count == 0) { cntnd++; fi = Mydocversion.MyFolder; topnode = new DevComponents.AdvTree.Node(); topnode.Text = fi.ToString(); advTreeProcSets.Nodes.Add(topnode); topnode.Tag = fi; } advTreeProcSets.BeforeExpand += new DevComponents.AdvTree.AdvTreeNodeCancelEventHandler(advTreeProcSets_BeforeExpand); // position to the procedure set in the tree if we have a procedure open if (Mydocversion != null) advTreeProcSetsPreSelect(); else advTreeProcSets.Nodes[0].SelectedCell = advTreeProcSets.Nodes[0].Cells[0]; // select the first node - fixes cosmetic problem //if (blSeachTabClicked) // cbxTextSearchText.Focus(); // set initial focus to enter search text } #endregion #region Private Methods private void GenerateAccIDSortedROList() { //Dictionary AccIDROIDdic = new Dictionary(); List AccPgIDsList = new List(); AccIDROIDdic.Clear(); string rtnStr = ""; ROFSTLookup.rochild[] chld = null; ROFSTLookup.rochild ch; ROList.Clear(); foreach (object rolkup in lstCheckedROs) { if (rolkup == null) // All Referenced Objects selected, return list of RO databases { foreach (ROFSTLookup.rodbi rodbi in _MyROFSTLookup.GetRODatabaseList(true)) { rtnStr = _MyRODbID.ToString() + ":" + string.Format("{0}", rodbi.dbiID.ToString("X4")); if (rodbi.children != null) { foreach (ROFSTLookup.rochild roc in rodbi.children) { PutROChildrenInDictionary(_MyRODbID.ToString() + ":", roc); } } else { ROList.Add(rtnStr); } } continue; } else if (rolkup is ROFSTLookup.rodbi) { ROFSTLookup.rodbi rodbi = (ROFSTLookup.rodbi)rolkup; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (rodbi.children == null || rodbi.children.Length <= 0) rodbi.children = MyROFSTLookup.GetRoChildrenByID(rodbi.ID, rodbi.dbiID, true); if (rodbi.children != null) { foreach (ROFSTLookup.rochild roc in rodbi.children) { PutROChildrenInDictionary(_MyRODbID.ToString() + ":", roc); } } else { ROList.Add(_MyRODbID.ToString() + ":" + string.Format("{0}", rodbi.dbiID.ToString("X4"))); } } else if (rolkup is ROFSTLookup.rochild) { ch = (ROFSTLookup.rochild)rolkup; chld = ch.children; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (ch.children == null || ch.children.Length <= 0) ch.children = MyROFSTLookup.GetRoChildrenByRoid(ch.roid, true); PutROChildrenInDictionary(_MyRODbID.ToString() + ":", rolkup); } } foreach (string k in AccIDROIDdic.Keys) { AccPgIDsList.Add(k); } string[] AccPgIdListArray = AccPgIDsList.ToArray(); Array.Sort(AccPgIdListArray, new AlphanumComparatorFast()); foreach (string accid in AccPgIdListArray) { ROList.Add(AccIDROIDdic[accid]); } } private string GetNextBlankKey() { return string.Format(" _{0}", blankKeyCnt++); } private void PutROChildrenInDictionary(string rodbidPrefix, object roObj) { ROFSTLookup.rochild chld = (ROFSTLookup.rochild)roObj; string rtnstr = rodbidPrefix;// ""; string keystr = ((chld.appid == "") ? GetNextBlankKey() : chld.appid) + chld.roid.Substring(0,4); //Try to lazy load the children - B2022-026 RO Memory Reduction if (chld.children == null || chld.children.Length <= 0) chld.children = MyROFSTLookup.GetRoChildrenByRoid(chld.roid, true); // If still no children - B2022-026 RO Memory Reduction code - check children length if (chld.children == null || chld.children.Length <= 0) // get a single ROID { rtnstr = rodbidPrefix + string.Format("{0}", chld.roid); if (rtnstr.Length == 12) rtnstr += "0000"; // last four digits are used for multiple return values // B2023-094: Don't crash when trying to add another ro if it has same key. Note that this is coming in as an RO but is really a group. if (!AccIDROIDdic.ContainsKey(keystr))AccIDROIDdic.Add(keystr, rtnstr); } else if (!cbxROUsage.Checked && chld.children[0].ParentID == 0) { rtnstr = rodbidPrefix + string.Format("{0},", chld.roid); // doing a RO Summary or RO Complete report - don't want children that are multiple return values AccIDROIDdic.Add(keystr, rtnstr); } else { // spin through the child list and get the ROIDs. // if the child has children, then call this function recursively for (int i = 0; i < chld.children.Length; i++) { ROFSTLookup.rochild roc = chld.children[i]; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (roc.children == null || roc.children.Length <= 0) roc.children = MyROFSTLookup.GetRoChildrenByRoid(roc.roid, true); // Don't get the children if we are doing a RO Summary or RO Complete report & children are the multiple return values if (roc.children != null && roc.children.Length > 0 && (cbxROUsage.Checked || roc.children[0].ParentID != 0)) { PutROChildrenInDictionary(rodbidPrefix, roc); } else if (roc.appid != null && roc.appid != "") { rtnstr = rodbidPrefix + string.Format("{0}", roc.roid); keystr = ((roc.appid == "") ? GetNextBlankKey() : roc.appid) + chld.roid.Substring(0, 4); if (AccIDROIDdic.ContainsKey(keystr)) // For duplicates, append the parent title (B2017-011) so adding to dictionary doesn't crash. { keystr = keystr + "|" + chld.title; } AccIDROIDdic.Add(keystr, rtnstr); } } } } private void GenerateROList() { string rtnStr = ""; ROFSTLookup.rochild[] chld = null; ROFSTLookup.rochild ch; ROList.Clear(); foreach (object rolkup in lstCheckedROs) { if (rolkup == null) // All Referenced Objects selected, return list of RO databases { // B2022-026 RO Memory Reduction code - added flag to load all children foreach (ROFSTLookup.rodbi rodbi in _MyROFSTLookup.GetRODatabaseList(true)) { rtnStr = _MyRODbID.ToString() + ":" + string.Format("{0}", rodbi.dbiID.ToString("X4")); ROList.Add(rtnStr); } continue; } else if (rolkup is ROFSTLookup.rodbi) { rtnStr = _MyRODbID.ToString() + ":" + string.Format("{0}", ((ROFSTLookup.rodbi)rolkup).dbiID.ToString("X4")); } else if (rolkup is ROFSTLookup.rochild) { ch = (ROFSTLookup.rochild)rolkup; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (ch.children == null || ch.children.Length <= 0) ch.children = MyROFSTLookup.GetRoChildrenByRoid(ch.roid, true); chld = ch.children; rtnStr = _MyRODbID.ToString() + ":" + GetROChildren(rolkup).TrimEnd(','); // GetROChildren(rolkup).TrimEnd(',') grabs the children of the selected item } ROList.Add(rtnStr); } } // same function as GetROsToSearch in DisplaySearch.cs private string GetROChildren(object roObj) { ROFSTLookup.rochild chld = (ROFSTLookup.rochild)roObj; string rtnstr = ""; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (chld.children == null || chld.children.Length <= 0) chld.children = MyROFSTLookup.GetRoChildrenByRoid(chld.roid, true); // If still no children if (chld.children == null || chld.children.Length <= 0) // get a single ROID { rtnstr += string.Format("{0}", chld.roid); if (rtnstr.Length == 12) rtnstr += "0000"; // last four digits are used for multiple return values } else if (!cbxROUsage.Checked && chld.children[0].ParentID == 0) { rtnstr += string.Format("{0},", chld.roid); // doing a RO Summary or RO Complete report - don't want children that are multiple return values } else { // spin through the child list and get the ROIDs. // if the child has children, then call this function recursivly foreach (ROFSTLookup.rochild roc in chld.children) { // Don't get the children if we are doing a RO Summary or RO Complete report & children are the multiple return values // B2022-062: Proms crashes on Complete or Summary RO report without 'Sort by SetpointID'. With new ROfst logic, // need to check for children length > 0 also. if (roc.children != null && roc.children.Length > 0 && (cbxROUsage.Checked || roc.children[0].ParentID != 0)) rtnstr += GetROChildren(roc); else rtnstr += string.Format("{0},", roc.roid); } } return rtnstr; } private string GetListOfROs(bool keepRODbID) { string rtnStr = ""; string strRODbID = ""; int cnt = 0; foreach (string rostr in ROList) { int ndxOf = rostr.IndexOf(":"); if (ndxOf > 0) { string tstr = rostr.Substring(0, ndxOf + 1); if (tstr != strRODbID && keepRODbID) { strRODbID = tstr; rtnStr += rostr; } else rtnStr += rostr.Substring(ndxOf + 1); } else rtnStr += rostr; if (rtnStr.EndsWith(",")) rtnStr = rtnStr.Substring(0, rtnStr.Length - 1); if (++cnt < ROList.Count) rtnStr += ","; } return rtnStr; } private void AddSelectedROChildren(DevComponents.AdvTree.NodeCollection chldrn) { if (chldrn.Count > 0) { foreach (DevComponents.AdvTree.Node n in chldrn) { if (n.Checked) lstCheckedROs.Add(n.Tag); else AddSelectedROChildren(n.Nodes); } } } private void BuildCheckedROsList() { lstCheckedROs.Clear(); if (advTreeRO.Nodes.Count == 0) return; DevComponents.AdvTree.Node node = advTreeRO.Nodes[0]; if (node.Checked) // top node (all Referenced Objects) selected lstCheckedROs.Add(node.Tag); else AddSelectedROChildren(node.Nodes); } private void EnableOrDisablePrintButton() { switch (tctrlReports.SelectedTabIndex) { case 0: // Transition Reports btnPrintReport.Enabled = (lstCheckedDocVersions.Count > 0); break; case 1: // Referenced Objects Reports BuildCheckedROsList(); // this list is sent to the report generator if (cbxROUsage.Checked) btnPrintReport.Enabled = (lstCheckedDocVersions.Count > 0 && lstCheckedROs.Count > 0); else btnPrintReport.Enabled = ((cbxComplete.Checked || cbxSummary.Checked) && lstCheckedROs.Count > 0); break; } if (cbxROUsage.Checked) cbxIncldMissingROs.Text = "Include Missing ROs (red ? in the editor)"; else if (cbxComplete.Checked) cbxIncldMissingROs.Text = "Include Empty RO Fields"; //cbxIncldMissingROs.Checked = cbxROUsage.Checked || cbxComplete.Checked; cbxIncldMissingROs.Visible = cbxROUsage.Checked || cbxComplete.Checked; cbxSortBySetpointID.Visible = cbxComplete.Checked || cbxSummary.Checked; labelX1.Visible = cmbxROUsageSort.Visible = !cbxSortBySetpointID.Visible; } private void tabTransitionReports_Click(object sender, EventArgs e) { xpSetToReport.Enabled = true; xpSetToReport.Expanded = true; xpSelROs.Expanded = false; xpSelROs.Enabled = false; EnableOrDisablePrintButton(); } private void tabROReports_Click(object sender, EventArgs e) { xpSetToReport.Enabled = cbxROUsage.Checked; xpSetToReport.Expanded = cbxROUsage.Checked; labelX1.Visible = cmbxROUsageSort.Visible = cbxROUsage.Checked; xpSelROs.Enabled = true; xpSelROs.Expanded = true; cbxIncldMissingROs.Checked = false;// !cbxSummary.Checked; cbxSortBySetpointID.Checked = false; cbxSortBySetpointID.Visible = !cbxROUsage.Checked; EnableOrDisablePrintButton(); } private void cbxROUsage_CheckedChanged(object sender, EventArgs e) { xpSetToReport.Enabled = cbxROUsage.Checked; xpSetToReport.Expanded = cbxROUsage.Checked; labelX1.Visible = cmbxROUsageSort.Visible = cbxROUsage.Checked; // reset the RO tree and clear anything that was selected advTreeROFillIn(true); lstCheckedROs.Clear(); cbxIncldMissingROs.Checked = false;// !cbxSummary.Checked; cbxSortBySetpointID.Checked = false; cbxSortBySetpointID.Visible = !cbxROUsage.Checked; EnableOrDisablePrintButton(); } private void DisplayReports_Load(object sender, EventArgs e) { tabTransitionReports.PerformClick(); } // when a node is checked (selected) then uncheck any of its children private void UncheckChildren(DevComponents.AdvTree.NodeCollection chldrn) { if (chldrn.Count > 0) { foreach (DevComponents.AdvTree.Node n in chldrn) { if (n.Checked) n.Checked = false; else UncheckChildren(n.Nodes); } } } // when a node is checked (selected), uncheck the parents, grand parents, great grand parents, etc. private void UncheckParents(DevComponents.AdvTree.Node pNode) { while (pNode != null) { if (pNode.Checked) pNode.Checked = false; pNode = pNode.Parent; } } private void advTreeRO_AfterCheck(object sender, AdvTreeCellEventArgs e) { DevComponents.AdvTree.Node n = advTreeRO.SelectedNode; if (n.Checked) { UncheckChildren(n.Nodes); UncheckParents(n.Parent); } EnableOrDisablePrintButton(); } private void cbxTransToProcs_CheckedChanged(object sender, EventArgs e) { EnableOrDisablePrintButton(); } private void cbxTransFromProcs_CheckedChanged(object sender, EventArgs e) { EnableOrDisablePrintButton(); } private void cbxComplete_CheckedChanged(object sender, EventArgs e) { cbxIncldMissingROs.Checked = false;// !cbxSummary.Checked; cbxSortBySetpointID.Checked = false; EnableOrDisablePrintButton(); } private void cbxSummary_CheckedChanged(object sender, EventArgs e) { EnableOrDisablePrintButton(); } private string BuildRODataFile(string ROList) { DocVersionInfo MyDVI = Mydocversion; string roDataFile = "PRINT.TMP"; if (VlnSettings.ReleaseMode.Equals("DEMO")) { MessageBox.Show("Referenced Object Reports not available in the Demo version.", "PROMS Demo Version"); return ""; } //string roapp = Environment.GetEnvironmentVariable("roapp"); string roapp = Volian.Base.Library.ExeInfo.GetROEditorPath(); // get the path to the RO Editor Executable if (roapp == null) { MessageBox.Show("Could not find path to Ro Editor, check 'roapp' environment variable"); return ""; } if (MyDVI == null || MyDVI.DocVersionAssociationCount < 1) { MessageBox.Show("Could not find associated path for ro data.", "No RO Data", MessageBoxButtons.OK, MessageBoxIcon.Information); return ""; } //string roloc = "\"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath + "\" " + "\"" + ROList + "\""; if (!Directory.Exists(MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath)) { MessageBox.Show(string.Format("RO Database directory does not exist: {0}", MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath)); return ""; } string cmpRptExePath = roapp.Substring(0, roapp.LastIndexOf("\\")) + "\\CmpRpt.exe "; roDataFile = MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath + "\\" + roDataFile; try { if (File.Exists(roDataFile)) File.Delete(roDataFile); Application.DoEvents(); string fname = VlnSettings.TemporaryFolder + "\\ROCompleteRprt.txt"; FileInfo fi = new FileInfo(fname); using (StreamWriter sw = fi.CreateText()) { sw.Write(ROList); sw.Close(); } string roloc = "\"" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.FolderPath + "\" \"/f=" + fname + "\""; // C2017-003: ro data in sql server, check for sql connection string if (MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString != "cstring") roloc = roloc + " \"/sql=" + MyDVI.DocVersionAssociations[0].MyROFst.MyRODb.DBConnectionString + "\""; // C2021-026 pass in Parent/Child information (list of the children) // B2022-019 look at all DocVersions to find ParentChild information // to ensure we pass in Parent/Child even when not coming from a Parent/Child procedure set DocVersionInfoList dvil = DocVersionInfoList.Get(); foreach (DocVersionInfo dvi in dvil) { DocVersionConfig dvc = dvi.DocVersionConfig as DocVersionConfig; if (dvc != null && dvc.Unit_Name != "" && dvc.Unit_Count > 1) // B2021-089 only pass in applicability info if defined for more than one unit roloc += " \"/PC=" + dvc.Unit_Name + "\""; break; } System.Diagnostics.Process p = System.Diagnostics.Process.Start(cmpRptExePath, roloc); // need to wait, sometimes the Print.tmp file that is generated is not available p.WaitForExit(); // without arguments, this will wait indefinitely Application.DoEvents(); } catch (Exception ex) { while (ex.InnerException != null) ex = ex.InnerException; string tmpmsg = ex.Message; MessageBox.Show(tmpmsg, "RO Report Error: " + ex.GetType().Name); } return roDataFile; } private void btnPrintReport_Click(object sender, EventArgs e) { string paperSize = "Letter"; if (Mydocversion != null && Mydocversion.ActiveFormat != null) paperSize = Mydocversion.ActiveFormat.PlantFormat.FormatData.PDFPageSize.PaperSize; // C2020-002 paper size is now set in the format files //B2019-144 Set the document text color to Red (overlay) or Black (normal) Color lastColor = MSWordToPDF.OverrideColor;// B2019-144 Remember override color if (MSWordToPDF.OverrideColor != Color.Black) MSWordToPDF.OverrideColor = Color.Black; Cursor curcur = Cursor; Cursor = Cursors.WaitCursor; if (cbxSummary.Checked) // RO Summary Report { if (cbxSortBySetpointID.Checked) GenerateAccIDSortedROList(); else GenerateROList(); OnPrintRequest(new DisplayReportsEventArgs("RO Summary Report", "RO Summary Report", MyROFSTLookup, ROList, paperSize)); } else if (cbxComplete.Checked) // Complete RO Report { if (cbxSortBySetpointID.Checked) GenerateAccIDSortedROList(); else GenerateROList(); string ROList = GetListOfROs(false);//don't include the RODbID in the RO list string roDataFile = BuildRODataFile(ROList); // B2023-028: RO report generates report with error when RO path not set. Return if datafile is not set // by BuildRODataFile if (roDataFile == null || roDataFile == "") { Cursor = curcur; // B2023-094: restore cursor (was wait). Not part of bug, found during fix return; } if (Mydocversion != null) OnPrintRequest(new DisplayReportsEventArgs("Complete RO Report", "Complete RO Report", roDataFile, MyROFSTLookup, cbxComplete.Checked, Mydocversion.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, cbxIncldMissingROs.Checked, paperSize)); } else if (cbxROUsage.Checked) { bool usageSortedByProcedure = (cmbxROUsageSort.SelectedIndex == 1); GenerateROList(); string SearchString = GetListOfROs(true);// Include the RODbID in the RO list ItemInfoList SearchResults = ItemInfoList.GetListFromROReport(DocVersionList, "", SearchString, ""); List sortedResults = SearchResults.SortedList(!usageSortedByProcedure); OnPrintRequest(new DisplayReportsEventArgs("Referenced Objects Usage By RO", "RO Usage", sortedResults, usageSortedByProcedure, cbxIncldMissingROs.Checked, paperSize)); } else if (cbxTransFromProcs.Checked) { } else if (cbxTransToProcs.Checked) { } Cursor = curcur; //B2019-144 Set the document text color to Red (overlay) or Black (normal) if (MSWordToPDF.OverrideColor != lastColor)// B2019-144 Restore override color MSWordToPDF.OverrideColor = lastColor; } #region (Procedure List) private DevComponents.AdvTree.Node NewAdvTreeNode(string nodetext, bool selectable, bool chxbxvisable) { DevComponents.AdvTree.Node newnode; newnode = new DevComponents.AdvTree.Node(); newnode.Text = nodetext; newnode.Selectable = selectable; newnode.CheckBoxAlignment = DevComponents.AdvTree.eCellPartAlignment.NearCenter; newnode.CheckBoxStyle = eCheckBoxStyle.CheckBox; newnode.CheckBoxThreeState = false; newnode.CheckBoxVisible = chxbxvisable; return newnode; } private void advTreeProcSets_BeforeExpand(object sender, DevComponents.AdvTree.AdvTreeNodeCancelEventArgs e) { DevComponents.AdvTree.Node par = e.Node; // get first child's text, if it has one & if the text is "VLN_DUMMY_NODE", load children DevComponents.AdvTree.Node tn = null; if (par.Nodes.Count > 0) tn = par.Nodes[0]; if (tn.Text == DummyNodeText) // expand this { par.Nodes.Clear(); Object obj = par.Tag; if (!(obj is FolderInfo)) return; // should always be folderinfo on expand FolderInfo fi = (FolderInfo)obj; if (fi.ChildFolderCount > 0) { foreach (FolderInfo fic in fi.SortedChildFolders) { DevComponents.AdvTree.Node newnode = new DevComponents.AdvTree.Node(); newnode.Text = fic.ToString(); newnode.Tag = fic; par.Nodes.Add(newnode); if (fic.HasChildren) // allow for '+' for tree expansion { DevComponents.AdvTree.Node tnt = new DevComponents.AdvTree.Node(); tnt.Text = DummyNodeText; newnode.Nodes.Add(tnt); } } } else if (fi.FolderDocVersionCount > 0) { foreach (DocVersionInfo dv in fi.FolderDocVersions) { DevComponents.AdvTree.Node newnode = new DevComponents.AdvTree.Node(); newnode.Text = dv.ToString(); newnode.Tag = dv; newnode.Selectable = true; newnode.CheckBoxAlignment = DevComponents.AdvTree.eCellPartAlignment.NearCenter; newnode.CheckBoxStyle = eCheckBoxStyle.CheckBox; newnode.CheckBoxThreeState = false; newnode.CheckBoxVisible = true; par.Nodes.Add(newnode); } } } } private void advTreeProcSets_AfterCheck(object sender, DevComponents.AdvTree.AdvTreeCellEventArgs e) { DevComponents.AdvTree.Node n = advTreeProcSets.SelectedNode; if (n.Checked) { n.Style = DevComponents.AdvTree.NodeStyles.Apple; lstCheckedDocVersions.Add((DocVersionInfo)n.Tag); if (lstCheckedDocVersions.Count == 1)//Mydocversion == null) { Mydocversion = (DocVersionInfo)n.Tag; } } else { n.Style = null; lstCheckedDocVersions.Remove((DocVersionInfo)n.Tag); if (lstCheckedDocVersions.Count == 1) { if (Mydocversion != lstCheckedDocVersions[0]) { Mydocversion = lstCheckedDocVersions[0]; } } else { if (lstCheckedDocVersions.Count == 0) Mydocversion = null; // do this if either none, or more than one procedure set selected //advTreeStepTypes.Nodes.Clear(); //lstCheckedStepTypes.Clear(); //lstCheckedStepTypesStr.Clear(); //Node newnode = new DevComponents.AdvTree.Node(); //newnode.Text = "....select a procedure set for types to appear..."; //advTreeStepTypes.Nodes.Add(newnode); //buildStepTypePannelTitle(); } } //// Enable the RO combo list only if at least one procedure set node //// is selected //cmboTreeROs.Enabled = (lstCheckedDocVersions.Count > 0); //gpFindROs.Enabled = cmboTreeROs.Enabled; //SetupContextMenu(); //buildSetToSearchPanelTitle(); EnableOrDisablePrintButton(); } private void advTreeProcSets_AfterNodeSelect(object sender, AdvTreeNodeEventArgs e) { DevComponents.AdvTree.Node n = advTreeProcSets.SelectedNode; } private void advTreeProcSetsPreSelect() { bool keeplooking = true; //build a stack (bread crumb trail) of where is procedure set came from within the tree. Stack crumbs = new Stack(); crumbs.Push(Mydocversion.Name); // ex: "working draft" crumbs.Push(Mydocversion.MyFolder.Name); // ex: "Emergency Procedures" FolderInfo fi = Mydocversion.MyFolder.MyParent; while (fi != null) { if (fi.MyParent != null) crumbs.Push(fi.Name); fi = fi.MyParent; } crumbs.Push(advTreeProcSets.Nodes[0].Text); //top node of my tree // now walk the tree, looking for the node names we saved in the stack. NodeCollection monkeys = advTreeProcSets.Nodes; while (keeplooking) { Node climber = LookInTree(monkeys, crumbs.Pop()); keeplooking = (climber != null && crumbs.Count > 0); if (keeplooking) monkeys = climber.Nodes; if (!keeplooking && climber != null) { climber.Checked = true; } } } private Node LookInTree(NodeCollection monkeys, string bananna) { Node foundit = null; foreach (Node chimp in monkeys) { if (chimp.Text.Equals(bananna)) { foundit = chimp; // need to select the node (cell) for it to be checked chimp.SelectedCell = chimp.Cells[0]; if (chimp.Nodes.Count > 0) chimp.Expand(); break; } chimp.Collapse(); } return foundit; } #endregion #region (RO Tree) private void AddDummyGroup(ROFSTLookup.rodbi rodbi, DevComponents.AdvTree.Node tn) { if (rodbi.children != null && rodbi.children.Length > 0) { DevComponents.AdvTree.Node tmp = new DevComponents.AdvTree.Node(); tmp.Text = DummyNodeText; tn.Nodes.Add(tmp); } } private void advTreeRO_BeforeExpand(object sender, DevComponents.AdvTree.AdvTreeNodeCancelEventArgs e) { LoadChildren(e.Node); } private void LoadChildren(DevComponents.AdvTree.Node tn) { //Check if node has already been loaded if (tn.HasChildNodes && tn.Nodes[0].Text != DummyNodeText) return; // already loaded. if (tn.HasChildNodes && tn.Nodes[0].Text == DummyNodeText) tn.Nodes[0].Remove(); object tag = tn.Tag; ROFSTLookup.rochild[] chld = null; if (tn.Tag is ROFSTLookup.rodbi) { ROFSTLookup.rodbi db = (ROFSTLookup.rodbi)tn.Tag; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (db.children == null || db.children.Length <= 0) db.children = MyROFSTLookup.GetRoChildrenByID(db.ID, db.dbiID, true); chld = db.children; } else if (tn.Tag is ROFSTLookup.rochild) { ROFSTLookup.rochild ch = (ROFSTLookup.rochild)tn.Tag; //Try to lazy load the children - B2022-026 RO Memory Reduction code if (ch.children == null || ch.children.Length <= 0) ch.children = MyROFSTLookup.GetRoChildrenByRoid(ch.roid, true); chld = ch.children; } else { Console.WriteLine("error - no type"); return; } // if children, add dummy node // B2022-026 RO Memory Reduction code - check child length if (chld != null && chld.Length > 0) { //ProgressBar_Initialize(chld.Length, tn.Text); for (int i = 0; i < chld.Length; i++) { //ProgressBar_SetValue(i); DevComponents.AdvTree.Node tmp = null; // Try to Lazy Load children - B2022-026 RO Memory Reduction code if (chld[i].children == null || chld[i].children.Length <= 0) chld[i].children = MyROFSTLookup.GetRoChildrenByRoid(chld[i].roid, true); // if this is a group, i.e. type 0, add a dummy node if (chld[i].type == 0 && chld[i].children == null) { // Ignore: Junk Scenario continue; } // B2023-094: don't crash if chld[i].children count is 0, signals an empty group else if (chld[i].value == null && (cbxROUsage.Checked || (chld[i].children != null && chld[i].children.Length > 0 && chld[i].children[0].ParentID != 0))) { tmp = new DevComponents.AdvTree.Node(); tmp.Text = chld[i].title; tmp.Tag = chld[i]; tmp.CheckBoxVisible = true; int index = FindIndex(tn.Nodes, tmp.Text); tn.Nodes.Insert(index, tmp); DevComponents.AdvTree.Node sub = new DevComponents.AdvTree.Node(); sub.Text = DummyNodeText; tmp.Nodes.Add(sub); } else { tmp = new DevComponents.AdvTree.Node(); tmp.Text = chld[i].title; tmp.Tag = chld[i]; tmp.CheckBoxVisible = true; int index = FindIndex(tn.Nodes, tmp.Text); tn.Nodes.Insert(index, tmp); } } } } private void advTreeRO_AfterExpandorCollapse(object sender, AdvTreeNodeEventArgs e) { Node bottomNode = BottomTreeNode(advTreeRO.Nodes); Node lastNode = advTreeRO.Nodes[advTreeRO.Nodes.Count - 1]; int top = advTreeRO.Nodes[0].Bounds.Top; int bottom = bottomNode.Bounds.Bottom + 5; int hScrollBarHeight = advTreeRO.HScrollBar != null ? advTreeRO.HScrollBar.Height : 0; bottom = bottomNode.Bounds.Bottom + 5; advTreeRO.Size = new Size(advTreeRO.Size.Width, Math.Min(525, bottom - top + hScrollBarHeight)); if (advTreeRO.VScrollBar != null && bottom < advTreeRO.Size.Height) { int yLookFor = (bottom - advTreeRO.Size.Height) + 2 * hScrollBarHeight; Node topNode = FindTreeNodeAt(advTreeRO.Nodes, yLookFor); if (topNode != null) topNode.EnsureVisible(); } } private Node FindTreeNodeAt(NodeCollection nodes, int y) { foreach (Node node in nodes) { if (node.Bounds.Top <= y && node.Bounds.Bottom >= y) return node; if (node.Bounds.Top > y) { if (node.PrevNode != null && node.PrevNode.Expanded) return FindTreeNodeAt(node.PrevNode.Nodes, y); return node; } } return null; } private Node BottomTreeNode(NodeCollection nodes) { Node bottomNode = nodes[nodes.Count - 1]; // Return bottom node in collection if (bottomNode.Expanded) // If expanded return bottom child return BottomTreeNode(bottomNode.Nodes); return bottomNode; } private int FindIndex(NodeCollection nodes, string value) { int index = 0; foreach (Node node in nodes) { if (GreaterValue(node.Text, value)) return index; index++; } return index; } private bool GreaterValue(string value1, string value2) { return DisplayRO.GreaterValue(value1, value2); } #endregion #endregion } #region DisplayReportsEventArgs Class public class DisplayReportsEventArgs { #region Fields private string _ReportTitle; private string _TypesSelected; private ICollection _MyItemInfoList; private bool _SortUsageByProcedure; private string _RODataFile = ""; private bool _CompleteROReport = true; private ROFSTLookup _rofstLookup; private List _ROListForReport; private bool _IncludeMissingROs = true; private bool _ConvertCaretToDelta = true; private bool _IncludeEmptyROFields = true; private string _PaperSize = "Letter"; #endregion #region Properties public string ReportTitle { get { return _ReportTitle; } set { _ReportTitle = value; } } public string TypesSelected { get { return _TypesSelected; } set { _TypesSelected = value; } } public ICollection MyItemInfoList { get { return _MyItemInfoList; } set { _MyItemInfoList = value; } } public bool SortUsageByProcedure { get { return _SortUsageByProcedure; } set { _SortUsageByProcedure = value; } } public string RODataFile { get { return _RODataFile; } set { _RODataFile = value; } } public bool CompleteROReport { get { return _CompleteROReport; } set { _CompleteROReport = value; } } public ROFSTLookup RofstLookup { get { return _rofstLookup; } set { _rofstLookup = value; } } public List ROListForReport { get { return _ROListForReport; } set { _ROListForReport = value; } } public bool IncludeMissingROs { get { return _IncludeMissingROs; } set { _IncludeMissingROs = value; } } public bool ConvertCaretToDelta { get { return _ConvertCaretToDelta; } set { _ConvertCaretToDelta = value; } } public bool IncludeEmptyROFields { get { return _IncludeEmptyROFields; } set { _IncludeEmptyROFields = value; } } public string PaperSize // C2020-002 paper size is now set in the format files { get { return _PaperSize; } set { _PaperSize = value; } } #endregion #region Constructors /// /// RO Usage Report /// /// /// /// /// /// /// public DisplayReportsEventArgs(string reportTitle, string typesSelected, ICollection myItemInfoList, bool sortByProcedure, bool includeMissingROs, string paperSize) { _ReportTitle = reportTitle; _TypesSelected = typesSelected; _MyItemInfoList = myItemInfoList; _SortUsageByProcedure = sortByProcedure; _IncludeMissingROs = includeMissingROs; _PaperSize = paperSize; // C2020-002 paper size is now set in the format files } /// /// RO Complete /// /// /// /// /// /// /// /// /// public DisplayReportsEventArgs(string reportTitle, string typesSelected, string roDataFile, ROFSTLookup rofstLookUp, bool completeROReport, bool convertCaretToDelta, bool includeEmptyROFields, string paperSize) { _ReportTitle = reportTitle; _TypesSelected = typesSelected; _RODataFile = roDataFile; _CompleteROReport = completeROReport; _ConvertCaretToDelta = convertCaretToDelta; _rofstLookup = rofstLookUp; _IncludeEmptyROFields = includeEmptyROFields; _PaperSize = paperSize; // C2020-002 paper size is now set in the format files } /// /// RO Summary Report /// /// /// /// /// /// public DisplayReportsEventArgs(string reportTitle, string typesSelected, ROFSTLookup rofstLookUp, List roListForReport, string paperSize) { _ReportTitle = reportTitle; _TypesSelected = typesSelected; _rofstLookup = rofstLookUp; _ROListForReport = roListForReport; _PaperSize = paperSize; // C2020-002 paper size is now set in the format files } #endregion } #endregion public delegate void DisplayReportsEvent(object sender, DisplayReportsEventArgs args); #region AlphanumComparatorFast Class public class AlphanumComparatorFast : IComparer { #region Public Methods public List GetList(string s1) { List SB1 = new List(); string st1, st2, st3; st1 = ""; bool flag = char.IsDigit(s1[0]); foreach (char c in s1) { if (flag != char.IsDigit(c) || !(char.IsDigit(c) || char.IsLetter(c)))// || c == '\'') { if (st1 != "") SB1.Add(st1); st1 = ""; flag = char.IsDigit(c); } if (char.IsDigit(c)) { st1 += c; } if (char.IsLetter(c)) { st1 += c; } } SB1.Add(st1); return SB1; } public int Compare(string x, string y) { string s1 = x;// as string; if (s1 == null) { return 0; } string s2 = y;// as string; if (s2 == null) { return 0; } if (s1 == s2) { return 0; } int len1 = s1.Length; int len2 = s2.Length; int marker1 = 0; int marker2 = 0; // Walk through two the strings with two markers. List str1 = GetList(s1); List str2 = GetList(s2); while (str1.Count != str2.Count) { if (str1.Count < str2.Count) { str1.Add(""); } else { str2.Add(""); } } int x1 = 0; int res = 0; int x2 = 0; string y2 = ""; bool status = false; string y1 = ""; bool s1Status = false; bool s2Status = false; //s1status ==false then string ele int; //s2status ==false then string ele int; int result = 0; for (int i = 0; i < str1.Count && i < str2.Count; i++) { status = int.TryParse(str1[i].ToString(), out res); if (res == 0) { y1 = str1[i].ToString(); s1Status = false; } else { x1 = Convert.ToInt32(str1[i].ToString()); s1Status = true; } status = int.TryParse(str2[i].ToString(), out res); if (res == 0) { y2 = str2[i].ToString(); s2Status = false; } else { x2 = Convert.ToInt32(str2[i].ToString()); s2Status = true; } //checking --the data comparision if (!s2Status && !s1Status) //both are strings { result = str1[i].CompareTo(str2[i]); } else if (s2Status && s1Status) //both are intergers { if (x1 == x2) { if (str1[i].ToString().Length < str2[i].ToString().Length) { result = 1; } else if (str1[i].ToString().Length > str2[i].ToString().Length) result = -1; else result = 0; } else { int st1ZeroCount = str1[i].ToString().Trim().Length - str1[i].ToString().TrimStart(new char[] { '0' }).Length; int st2ZeroCount = str2[i].ToString().Trim().Length - str2[i].ToString().TrimStart(new char[] { '0' }).Length; if (st1ZeroCount > st2ZeroCount) result = -1; else if (st1ZeroCount < st2ZeroCount) result = 1; else result = x1.CompareTo(x2); } } else { result = str1[i].CompareTo(str2[i]); } if (result == 0) { continue; } else break; } return result; } #endregion } #endregion }