using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.IO; using System.Windows.Forms; using VEPROMS.CSLA.Library; using XYPlots; using DevComponents.DotNetBar; using System.Text.RegularExpressions; using Volian.Base.Library; using JR.Utils.GUI.Forms; using System.Linq; namespace Volian.Controls.Library { public partial class DisplayRO : UserControl { #region Log4Net private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion #region Fields private const string DummyNodeText = "VLN_DUMMY_NODE"; private const int MaxNumSearchRecords = 1000; // B2019-161 When tracking timing time this action private static VolianTimer _timeActivity = new VolianTimer("DisplayRO MyRTB_SelectionChanged", 117); private static Regex _regExGetNumber = new Regex(@"^ *[+-]?[.,0-9/]+(E[+-]?[0-9]+)?"); private static UserInfo _myUserInfo = null; private Timer _searchTimer = null; private string _lastSearchValue = string.Empty; private ProgressBarItem _progressBar; private DisplayTabControl _tabControl; private StepRTB _myRTB; private string _selectedRoidBeforeRoEditor = null; private ROFstInfo _myROFST; private DocVersionInfo _docVersionInfo; private RoUsageInfo _savCurROLink; private E_ROValueType _roTypeFilter = E_ROValueType.All; //private ROFstInfo _curROFST = null; private int? _currRofstID = null; private int? _currDocVersionID = null; private RoUsageInfo _curROLink; private E_ROValueType _curROTypeFilter = E_ROValueType.All; private ROFSTLookup.rochild selectedChld; private DisplayTags displayTags; #endregion #region Properties public ProgressBarItem ProgressBar { get { return _progressBar; } set { _progressBar = value; } } public DisplayTabControl TabControl { get { return _tabControl; } set { _tabControl = value; } } public bool IsRofstValid { get { return (_myROFST != null && _myROFST.ROFstAssociations != null && _myROFST.ROFstAssociationCount > 0); } } public bool RoTreeNeedsReloaded { get { return (MyROFST != null && _currRofstID != null && MyROFST.ROFstID != (int)_currRofstID) || (MyDvi != null && _currDocVersionID != null && MyDvi.VersionID != (int)_currDocVersionID) || // B2022-142 check if we went from a RO Table or RO Figure step type to a regular step type // or if we went from a regular step type to a RO Table or RO Figure step type (_myRTB != null && (_myRTB.IsRoTable != lastRTBwasROTable || _myRTB.IsRoFigure != lastRTBwasROFigure)); } } public ROFstInfo MyROFST { get { return _myROFST; } set { // Define the tree nodes based on this rofst/docversion // Rofst is required, DocVersion can be null. If Rofst is null then make DocVersion null if (_myROFST != value) { if (value == null) { _myROFST = null; MyDvi = null; } else { _myROFST = value; if (MyDvi == null) { MyDvi = (IsRofstValid) ? _myROFST.ROFstAssociations[0].MyDocVersion : null; } } // B2022-123: RO Tab Treeview not showing correct RO values when switching between procedures. _currRofstID = (IsRofstValid) ? (int?)_myROFST.ROFstID : null; } } } public DocVersionInfo MyDvi { // B2022-135 Submitted for Admin Tools (Check RO Links tool) get { return (_myRTB != null) ? _myRTB.MyDVI : _docVersionInfo; } set { // B2022-135 Submitted for Admin Tools (Check RO Links tool) if (_docVersionInfo == null || _docVersionInfo != value || _docVersionInfo.VersionID != value.VersionID) { _docVersionInfo = value; if (_myRTB != null && (_docVersionInfo == null || _docVersionInfo.VersionID != _myRTB.MyDVI.VersionID)) { _docVersionInfo = _myRTB.MyDVI; } } // B2022-123: RO Tab Treeview not showing correct RO values when switching between procedures. _currDocVersionID = (_docVersionInfo != null) ? (int?)_docVersionInfo.VersionID : null; } } public ROFSTLookup MyROFSTLookup { get { return (_myROFST != null) ? new ROFSTLookup(_myROFST.ROFstID, _docVersionInfo) : null;} } public E_ROValueType ROTypeFilter { get { return _roTypeFilter; } set {_roTypeFilter = value; } } public RoUsageInfo CurROLink { get { return _curROLink; } set { // Volian.Base.Library.vlnStackTrace.ShowStack("value={0} MyRTB={1}", value, ((MyRTB != null) ? MyRTB.SelectedText : "" )); // modify - set the controls to the current ro if (value != null) { if (_curROLink != value) { _curROLink = value; _savCurROLink = _curROLink; // B2022-088: [JPR] Find Doc Ro button not working in Word Sections // B2022-098: [JPR] ROs not being resolved in Word Sections string roid = ROFSTLookup.FormatRoidKey(_curROLink.ROID, true); ExpandNode(roid); } } else // if (_curROLink != null) // insert - clear out controls { _curROLink = value; tvROFST.SelectedNode = null; ResetSearch(); } } } // B2022-142 added this local variables to keep flag if the last step type was a RO Table or a RO Figure // this is used to determin if we need to re-load the RO tree private bool lastRTBwasROTable = false; private bool lastRTBwasROFigure = false; public StepRTB MyRTB { get { return _myRTB; } set { if (value == null) { _myRTB = value; MyROFST = null; // B2022-088: [JPR] Find Doc Ro button not working in Word Sections // B2022-098: [JPR] ROs not being resolved in Word Sections CurROLink = null; _savCurROLink = null; } else if(_myRTB != value) { if (_myRTB != null) { lastRTBwasROTable = _myRTB.IsRoTable; // B2022-141 save whether last RTB was a RO Table lastRTBwasROFigure = _myRTB.IsRoFigure; // B2022-141 save whether last RTB was a RO Figure } _myRTB = value; MyRTB.LinkChanged += new StepRTBLinkEvent(MyRTB_LinkChanged); MyRTB.SelectionChanged += new EventHandler(MyRTB_SelectionChanged); if (string.IsNullOrEmpty(MyRTB.MyLinkText)) { CurROLink = null; _savCurROLink = null; } // B2023-004 assign the doc version info associated with the current RTB (rich text box) // this fixes an issue where unit designators could not be linked in the step edit (BNPP data) MyDvi = _myRTB.MyItemInfo.MyDocVersion; MyROFST = (_myRTB.MyItemInfo.MyDocVersion.DocVersionAssociationCount > 0) ? _myRTB.MyItemInfo.MyDocVersion.DocVersionAssociations[0].MyROFst : null; } } } public bool IsEnhancedStep { get { return (MyRTB != null && MyRTB.MyItemInfo != null && MyRTB.MyItemInfo.IsEnhancedStep); } } public bool IsNotStep { get { return (MyRTB != null && MyRTB.MyItemInfo != null && (MyRTB.MyItemInfo.IsProcedure || MyRTB.MyItemInfo.IsSection)); } } public bool IsInWordDoc { get { return (TabControl != null && TabControl.SelectedDisplayTabItem != null && TabControl.SelectedDisplayTabItem.MyDSOTabPanel != null); } } public static UserInfo MyUserInfo { get { return _myUserInfo; } set { _myUserInfo = value; } } #endregion #region Constructors public DisplayRO() { InitializeComponent(); panelRoValue.BackColor = Color.Cornsilk; panelValue.BackColor = Color.Cornsilk; _currRofstID = null; _currDocVersionID = null; if (_searchTimer == null) { _searchTimer = new Timer(); _searchTimer.Interval = 1000; _searchTimer.Tick += new EventHandler(SelectionTimer_Tick); _searchTimer.Stop(); } // Initialize the DisplayTags object displayTags = new DisplayTags(); _progressBar = null; } #endregion #region Event Handlers #region (Progress Bar) private void ProgressBar_Initialize(int max, string desc) { if (_progressBar != null) { _progressBar.Maximum = max; _progressBar.Text = desc; _progressBar.TextVisible = true; } } private void ProgressBar_SetValue(int curval) { if (_progressBar != null) { _progressBar.Value = curval; } } private void ProgressBar_Clear() { if (_progressBar != null) { _progressBar.Text = string.Empty; _progressBar.Maximum = 0; _progressBar.Value = 0; } } #endregion #region (RTB) public void MyRTB_LinkChanged(object sender, StepPanelLinkEventArgs args) { CurROLink = null; if (MyRTB.MyLinkText != null) CurROLink = args.MyLinkText.MyRoUsageInfo; } public void MyRTB_SelectionChanged(object sender, EventArgs e) { _timeActivity.Open(); // B2022-088: [JPR] Find Doc Ro button not working in Word Sections // B2022-098: [JPR] ROs not being resolved in Word Sections // Need to call Stop then Start just in case the uses has changed their selection // before the timer.Tick event fires. Calling Stop/Start is the same as Reset for the timer _searchTimer.Stop(); _searchTimer.Start(); _timeActivity.Close(); } private void SelectionTimer_Tick(object sender, EventArgs e) { // Stop the timer _searchTimer.Stop(); // Process RO Value Search if (MyRTB != null && !MyRTB.IsDisposed) { ProcessSearch(MyRTB.SelectedText, (int)ROFSTLookup.SearchTypes.StartsWith); } } #endregion #region (Tree Node) private void tvROFST_DoubleClick(object sender, EventArgs e) { // B2016-132: don't process a double click on an RO if on an enhanced step: if (!IsEnhancedStep) { SaveRO(); } } private void tvROFST_BeforeExpand(object sender, TreeViewCancelEventArgs e) { LoadChildren(e.Node); } private void tvROFST_AfterSelect(object sender, TreeViewEventArgs e) { // B2022-088: [JPR] Find Doc Ro button not working in Word Sections // B2022-098: [JPR] ROs not being resolved in Word Sections if (e.Node.Tag is ROFSTLookup.rochild) { ROFSTLookup.rochild chld = (ROFSTLookup.rochild)e.Node.Tag; selectedChld = chld; if (chld.value != null) { RoUsageInfo SavROLink = null; if (_savCurROLink != null) SavROLink = _savCurROLink; // Set the Display Text to the AccPageID lbROId.Text = chld.appid; //B2017-245 Disable SaveRO button for Procedures and Sections //B2020-049: Save button not enabled on Word docs, only if a procedure was opened first and immediately after the word document // section is opened (added 'IsInWorDoc') btnSaveRO.Enabled = (IsInWordDoc || (!IsNotStep && !IsEnhancedStep)) && UserInfo.CanEdit(MyUserInfo, MyDvi) && ((SavROLink == null) || !(chld.roid.Equals(SavROLink.ROID.ToUpper()))); //added security check (UserInfo.CanEdit) btnCancelRO.Enabled = (_savCurROLink != null && (SavROLink != null && chld.roid != SavROLink.ROID.ToUpper())); btnGoToRO.Enabled = UserInfo.CanEditROs(MyUserInfo, MyDvi); // Writers and Reviewers cannot edit ROs (run the RO Editor) switch (chld.type) { case 1: // standard (regular) text RO type tbROValue.Text = chld.value; btnPreviewRO.Enabled = false; if (chld.roid.StartsWith("FFFF")) btnGoToRO.Enabled = false; break; case 2: // Table RO type case 3: // This is type 3 when part of a multiple return value tbROValue.Text = "(Table)"; btnPreviewRO.Enabled = true; break; case 4: // X/Y Plot RO type tbROValue.Text = "(Graph)"; btnPreviewRO.Enabled = true; break; case 8: // Integrated Graphics RO type tbROValue.Text = "(Image)"; btnPreviewRO.Enabled = true; break; } } } else { // B2022-088: [JPR] Find Doc Ro button not working in Word Sections // B2022-098: [JPR] ROs not being resolved in Word Sections ResetSearch(); } } #endregion #region (Buttons) private void btnSaveRO_Click(object sender, EventArgs e) { SaveRO(); } private void btnCancelRO_Click(object sender, EventArgs e) { _curROLink = _savCurROLink; btnCancelRO.Enabled = false; ExpandNode(_curROLink.ROID); } private void btnPreviewRO_Click(object sender, EventArgs e) { if (selectedChld.type == 8) // integrated graphic { string fname = selectedChld.value.Substring(0, selectedChld.value.IndexOf('\n')); int thedot = fname.LastIndexOf('.'); ROImageInfo tmp = null; if (thedot == -1 || (thedot != (fname.Length - 4))) { tmp = ROImageInfo.GetByROFstID_FileName(MyROFST.ROFstID, fname); fname += string.Format(".{0}", MyROFST.MyRODb.RODbConfig.GetDefaultGraphicExtension()); } if (tmp == null) tmp = ROImageInfo.GetByROFstID_FileName(MyROFST.ROFstID, fname); if (tmp == null) tmp = MyROFST.GetROImageByFilename(fname, null); if (tmp != null) { ROImageConfig rc = new ROImageConfig(tmp); int size = Convert.ToInt32(rc.Image_Size); PreviewROImage pvROImg = new PreviewROImage(ROImageInfo.Decompress(tmp.Content, size), selectedChld.title); pvROImg.ShowDialog(); } else { FlexibleMessageBox.Show(string.Format("Cannot Find Image Data: {0}, {1}", MyROFST.ROFstID, fname)); } } else if (selectedChld.type == 2) // table { PreviewMultiLineRO pmlROTable = new PreviewMultiLineRO(selectedChld.value, selectedChld.title); pmlROTable.ShowDialog(); } else if (selectedChld.type == 4) // x/y plot { frmXYPlot plot = new frmXYPlot(selectedChld.appid + " - " + selectedChld.title, selectedChld.value); plot.Show(); } } private void btnGoToRO_Click(object sender, EventArgs e) { if (tvROFST.SelectedNode == null) return; RunRoEditor(); } private void btnFindDocRO_Click(object sender, EventArgs e) { // C2016-044: support click of the 'Find Doc RO' button: DisplayTabItem dti = (_tabControl == null) ? null : _tabControl.SelectedDisplayTabItem; if (dti != null && dti.MyDSOTabPanel != null) { // the currently selected tab control is a word document - see if it has an // active selection. If not, tell the user that text needs to be selected before the ro can be found. string mytext = dti.MyDSOTabPanel.GetSelectedString(); if (string.IsNullOrEmpty(mytext)) { FlexibleMessageBox.Show(this, "Text must be selected in the document in order for an RO find to be performed.", "Select Text", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } ProcessSearch(mytext, (int)ROFSTLookup.SearchTypes.StartsWith); } } #endregion #region (Labels) private void lbROId_DoubleClick(object sender, EventArgs e) { if (tvROFST.SelectedNode == null) return; // do not allow writers and reviews to run the RO Editor if (!UserInfo.CanEditROs(MyUserInfo, MyDvi)) return; if (VlnSettings.ReleaseMode.Equals("DEMO")) { FlexibleMessageBox.Show("Referenced Object Editor not available in the Demo version.", "PROMS Demo Version"); return; } string roapp = Volian.Base.Library.ExeInfo.GetROEditorPath(); // get the path to the RO Editor Executable object obj = tvROFST.SelectedNode.Tag; if (obj is ROFSTLookup.rochild) { ROFSTLookup.rochild roch = (ROFSTLookup.rochild)obj; _selectedRoidBeforeRoEditor = roch.roid; string args = "\"" + MyROFST.MyRODb.FolderPath + "\" " + roch.roid.Substring(0,12).ToLower(); // C2017-003: ro data in sql server, check for sql connection string if (MyROFST.MyRODb.DBConnectionString != "cstring") args = args + " \"" + 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 // B2022-073 Break out of the foreach when we find a set with parent/child information DocVersionInfoList dvil = DocVersionInfoList.Get(); foreach (DocVersionInfo dvi in dvil) { DocVersionConfig dvc = dvi.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 { args += " \"PC=" + dvc.Unit_Name + "\""; break; } } System.Diagnostics.Process.Start(roapp, args); } } private void lbFound_SelectedValueChanged(object sender, EventArgs e) { if (lbFound.Visible && lbFound.SelectedIndex >= 0 && lbFound.SelectedValue != null) { ExpandNode(Convert.ToString(lbFound.SelectedValue)); } } #endregion #endregion #region Public Methods public void LoadTree(bool forceReload = false) { if (MyROFST == null) { tvROFST.Nodes.Clear(); lbFound.Visible = false; return; } if (forceReload || RoTreeNeedsReloaded || tvROFST.Nodes == null || tvROFST.Nodes.Count <= 0) { ROFSTLookup.rodbi[] dbs = MyROFSTLookup.GetRODatabaseList(true); // B2022-123: RO Tab Treeview not showing correct RO values when switching between procedures. // Added optional parameter "forceReload" and cleared out any existing nodes before reloading the tree // the clear nodes code below has to be after the GetRODatabaseList database call because of races conditions in the code tvROFST.Nodes.Clear(); ResetSearch(); //B2023-050 need to reset the SaveRO, and any RO info that was selected last time the tree was loaded for (int i = 0; i < dbs.Length; i++) { ROFSTLookup.rodbi db = dbs[i]; TreeNode tn = new TreeNode(db.dbiTitle); tn.Tag = db; tvROFST.Nodes.Add(tn); AddDummyGroup(db, tn); } _currRofstID = (int?)MyROFST.ROFstID; _currDocVersionID = null; if(_docVersionInfo != null) _currDocVersionID = (int?)_docVersionInfo.VersionID; } var unitInfoNode = tvROFST.Nodes.Cast().Where(x => x.Text == "Unit Information").FirstOrDefault(); if ((ROTypeFilter == E_ROValueType.Text || ROTypeFilter == E_ROValueType.All) && this.MyDvi != null && this.MyDvi.MultiUnitCount > 1) { // Add Unit Information Database if it doesn't exist if (unitInfoNode == null) { TreeNode tnn = tvROFST.Nodes.Add("Unit Information"); TreeNode cn = null; ROFSTLookup.rochild roc = MyROFSTLookup.GetRoChild("FFFF00000001"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000002"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000003"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000004"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000005"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000006"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000007"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; roc = MyROFSTLookup.GetRoChild("FFFF00000008"); cn = tnn.Nodes.Add(roc.title); cn.Tag = roc; } } else if (unitInfoNode != null) // Add Unit Information Database if it doesn't exist [Not Multi-Unit DocVersion] { tvROFST.Nodes.Remove(unitInfoNode); } _curROTypeFilter = _roTypeFilter; } public void SetFindDocROButton(bool enabled) { this.btnFindDocRO.Enabled = enabled; } public static bool GreaterValue(string value1, string value2) { Match match1 = _regExGetNumber.Match(value1); Match match2 = _regExGetNumber.Match(value2); if (match1.Success && !match1.Value.Contains("/") && match2.Success && !match2.Value.Contains("/")) // Compare the numeric value? { double dbl1; double dbl2; //B2017-232 changed from Parse to TryParse. AEP had figure title that had a number containing two periods which caused Parse to error? if (double.TryParse(match1.ToString(), out dbl1) && double.TryParse(match2.ToString(), out dbl2)) { if (dbl1 != dbl2) //B2021-144 if the numerical is identical default to the string comparison? return dbl1 > dbl2; } } return string.Compare(value1, value2, true) > 0; } #endregion #region Private Methods private void LoadChildren(TreeNode tn) { //Check if node has already been loaded if (tn.FirstNode != null && tn.FirstNode.Text != DummyNodeText) return; if (tn.FirstNode != null && tn.FirstNode.Text == DummyNodeText) tn.FirstNode.Remove(); //object tag = tn.Tag; ROFSTLookup.rochild[] children = null; if (tn.Tag is ROFSTLookup.rodbi) { ROFSTLookup.rodbi db = (ROFSTLookup.rodbi)tn.Tag; MyROFSTLookup.LoadChildren(ref db); children = db.children; } else if (tn.Tag is ROFSTLookup.rochild) { ROFSTLookup.rochild ch = (ROFSTLookup.rochild)tn.Tag; MyROFSTLookup.LoadChildren(ref ch); children = ch.children; } // if children, add dummy node if (children != null && children.Length > 0) { for (int i = 0; i < children.Length; i++) { TreeNode tmp = null; ROFSTLookup.rochild roc = children[i]; // if this is a group, i.e. type 0, add a dummy node if (roc.type == 0 && !MyROFSTLookup.HasChildren(ref roc)) { continue; // Ignore: Junk Scenario } else if (ROTypeFilter != E_ROValueType.All && (roc.type & (uint)ROTypeFilter) == 0) { continue; // Ignore: Filter Doesn't Match } else if (!string.IsNullOrEmpty(roc.appid)) { MyROFSTLookup.LoadChildren(ref roc); if (roc.children.Length == 1 && roc.children.First().roid.Length == 16) { roc.appid = roc.children.First().appid; roc.roid = roc.children.First().roid; roc.value = roc.children.First().value; roc.children = new List().ToArray(); } } if (roc.value == null) { tmp = new TreeNode(roc.title); tmp.Tag = roc; int index = FindIndex(tn.Nodes, tmp.Text); tn.Nodes.Insert(index, tmp); TreeNode sub = new TreeNode(DummyNodeText); tmp.Nodes.Add(sub); } else { tmp = new TreeNode(roc.title); tmp.Tag = roc; if (roc.roid.Length == 16) { tn.Nodes.Add(tmp); } else { int index = FindIndex(tn.Nodes, tmp.Text); tn.Nodes.Insert(index, tmp); } } } } } private void AddDummyGroup(ROFSTLookup.rodbi rodbi, TreeNode tn) { if (MyROFSTLookup.HasChildren(ref rodbi)) { TreeNode tmp = new TreeNode(DummyNodeText); tn.Nodes.Add(tmp); } } private void ExpandNode(string roid) { // Clean-up Roid if necessary roid = ROFSTLookup.FormatRoidKey(roid); bool multValSel = (roid.Length == 16) ? true : false; string db = roid.Substring(0, 4); int dbiID = MyROFSTLookup.GetRODatabaseTitleIndex(roid); ROFSTLookup.rochild rochld = MyROFSTLookup.GetRoChild(roid.Substring(0, 12).ToUpper()); // use this to walk up tree until database - this is used to expand tree. List path = new List(); int myid = rochld.ID; while (myid >= 0) { path.Insert(0, myid); myid = rochld.ParentID; string pROID = string.Format("{0:X04}{1:X08}", db, myid); rochld = MyROFSTLookup.GetRoChild(pROID); if (rochld.ID == -1) myid = -1; } TreeNode tnExpand = null; //Find Database Node First TreeNode dbNode = null; if (roid.StartsWith("FFFF")) dbNode = tvROFST.Nodes.Cast().Where(x => (x.Tag.Equals(null)) && (x.Text.Equals("Unit Information"))).FirstOrDefault(); else dbNode = tvROFST.Nodes.Cast().Where(x => (x.Tag is ROFSTLookup.rodbi) && ((ROFSTLookup.rodbi)x.Tag).dbiID == dbiID).FirstOrDefault(); if (dbNode != null) { LoadChildren(dbNode); tnExpand = dbNode; } if (tnExpand != null) { // use the path id list to load/find the treeview's nodes. foreach (int citm in path) { LoadChildren(tnExpand); tnExpand.Expand(); TreeNode chldNode = tnExpand.Nodes.Cast().Where(x => (x.Tag is ROFSTLookup.rochild) && ((ROFSTLookup.rochild)x.Tag).ID == citm).FirstOrDefault(); if (chldNode != null) { tnExpand = chldNode; } } } if (tnExpand != null) { // If a multiple return value, try to select the proper node if (multValSel) { LoadChildren(tnExpand); tnExpand.Expand(); TreeNode chldNode = tnExpand.Nodes.Cast().Where(x => ((ROFSTLookup.rochild)x.Tag).roid.ToUpper() == roid.ToUpper()).FirstOrDefault(); if (chldNode != null) { tnExpand = chldNode; } } } tvROFST.SelectedNode = tnExpand; } private int FindIndex(TreeNodeCollection nodes, string value) { int index = 0; foreach (TreeNode node in nodes) { if (GreaterValue(node.Text, value)) return index; index++; } return index; } private void SaveRO() { //Check if an RO Node is selected from the TreeView if (string.IsNullOrEmpty(tbROValue.Text)) { FlexibleMessageBox.Show("Must select an RO Value from the tree."); return; } Object obj = tvROFST.SelectedNode.Tag; if (obj is ROFSTLookup.rochild) { ROFSTLookup.rochild roc = (ROFSTLookup.rochild)obj; DisplayTabItem dti = TabControl.SelectedDisplayTabItem; //.OpenItem(_ItemInfo); // open the corresponding procedure text if (dti.MyDSOTabPanel != null) // A Word Document tab is the active tab { string accPageID = string.Format("<{0}>", roc.appid.ToUpper()); // Insert the RO text at the current cursor position in the word document // NOTE: assuming any type of RO can be put in an Accessory (MSWord) Document if (dti.MyDSOTabPanel != null) { dti.MyDSOTabPanel.InsertText(accPageID); } } else if (MyRTB != null) // a Procedure Steps section tab is active { if (CheckROSelection(roc)) // check for RO type is valid for this type of step/substep { // Pad to 16 to store in the RoUsage table. string padroid = ROFSTLookup.FormatRoidKey(roc.roid, true); string linktxt = string.Format(@"#Link:ReferencedObject: {0} {1}", padroid, MyROFST.RODbID); // Resolve symbols and scientific notation in the RO return value string valtxt = MyROFSTLookup.GetTranslatedRoValue(padroid, MyRTB.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta, MyRTB.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.UseTildaPoundCharsForSuperSubScriptInROValues, false, MyRTB.MyItemInfo); MyRTB.OnRoInsert(this, new StepRTBRoEventArgs(valtxt, selectedChld.value, linktxt, padroid, MyROFST.RODbID)); } } btnGoToRO.Enabled = false; btnSaveRO.Enabled = false; btnCancelRO.Enabled = false; btnPreviewRO.Enabled = false; CurROLink = null; _savCurROLink = null; } } private bool CheckROSelection(ROFSTLookup.rochild selectedRO) { bool goodToGo = true; bool replacingRO = (_savCurROLink != null); string insrpl = (replacingRO) ? "Cannot Replace" : "Cannot Insert"; string errormsg = string.Empty; switch (selectedRO.type) { case 1: // regular text RO if (MyRTB.MyItemInfo.IsFigure) { errormsg = (replacingRO) ? "a Figure with a non-figure." : "a text RO in a Figure type."; goodToGo = false; } break; case 2: // table RO if (MyRTB.MyItemInfo.IsFigure) { errormsg = (replacingRO) ? "a Figure with a non-figure." : "a table into a Figure type."; goodToGo = false; } else if (!MyRTB.MyItemInfo.IsTable) { errormsg = (replacingRO) ? "a non-table RO with a Table RO." : "a table into a non-table type."; //TODO: Prompt user to insert a new Table substep type and place this RO into it goodToGo = false; } break; case 4: // X/Y Plot RO type if (!MyRTB.MyItemInfo.IsAccPages) { errormsg = (replacingRO) ? "a non-X/Y Plot RO with an X/Y Plot RO." : "an X/Y Plot RO in an non-Accessory Page type."; //TODO: Prompt user to insert a new substep type that handles x/y Plots and place this RO into it goodToGo = false; } break; case 8: // figure (intergrated graphics) if (!MyRTB.MyItemInfo.IsFigure && !MyRTB.MyItemInfo.IsAccPages) { errormsg = (replacingRO) ? "a graphics RO with a non-graphcis RO." : "a Graphics RO in an non-Figure or a non-Accessory Page type."; //TODO: Prompt user to insert a new substep type that handles x/y Plots and place this RO into it goodToGo = false; } break; } if (!goodToGo) { FlexibleMessageBox.Show(string.Format("{0} {1}", insrpl, errormsg), (replacingRO) ? "Invalid RO Replacement" : "Invalid RO Insert"); } return goodToGo; } private void RunRoEditor() { if (VlnSettings.ReleaseMode.Equals("DEMO")) { FlexibleMessageBox.Show("Referenced Object Editor not available in the Demo version.", "PROMS Demo Version"); return; } string roapp = Volian.Base.Library.ExeInfo.GetROEditorPath(); // get the path to the RO Editor Executable Object obj = tvROFST.SelectedNode.Tag; if (obj is ROFSTLookup.rochild) { ROFSTLookup.rochild roc = (ROFSTLookup.rochild)obj; _selectedRoidBeforeRoEditor = roc.roid; string args = "\"" + _myROFST.MyRODb.FolderPath + "\" " + roc.roid.ToLower(); if (!Directory.Exists(_myROFST.MyRODb.FolderPath)) { FlexibleMessageBox.Show(string.Format("RO Database directory does not exist: {0}", _myROFST.MyRODb.FolderPath)); return; } // C2017-003: ro data in sql server, check for sql connection string if (_myROFST.MyRODb.DBConnectionString != "cstring") args = args + " \"" + _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 // B2022-073 Break out of the foreach when we find a set with parent/child information DocVersionInfoList dvil = DocVersionInfoList.Get(); foreach (DocVersionInfo dvi in dvil) { DocVersionConfig jdvc = dvi.DocVersionConfig; if (jdvc != null && jdvc.Unit_Name != "" && jdvc.Unit_Count > 1) // B2021-089 only pass in applicability info if defined for more than one unit { args += " \"PC=" + jdvc.Unit_Name + "\""; break; } } System.Diagnostics.Process.Start(roapp, args); } } private void ProcessSearch(string searchValue, int searchTypeID) { // Jake [2022.05.11]: Added try catch to prevent unhandled exception when the timer ticks and // tries to process a search while the main tab/procedure is closing try { // B2022-124: [JPR] Blank RO Values (All Spaces) printing as "?" if (!string.IsNullOrEmpty(searchValue)) { searchValue = searchValue.Replace('\u2011', '-'); searchValue = searchValue.Replace(@"\u9586?", @"\\"); if (searchValue.Replace(" ", string.Empty).Length > 0) searchValue = searchValue.Trim(); } if (this.Enabled && !string.IsNullOrEmpty(searchValue) && searchValue.Length >= 2 && !searchValue.Contains("#Link:Transition")) { Dictionary dicRoVals = new Dictionary(); // B2022-088: [JPR] Find Doc Ro button not working in Word Sections // B2022-098: [JPR] ROs not being resolved in Word Sections if (searchValue.StartsWith("<") && searchValue.EndsWith(">")) // RO Link (accPageID) { ROFSTLookup.rochild roc = MyROFSTLookup.GetROChildByAccPageID(searchValue); // If RO is valid then select node in tree view if (roc.ID >= 0 && !string.IsNullOrEmpty(roc.value)) { ExpandNode(roc.roid); } lbFound.DataSource = null; lbFound.Visible = false; _lastSearchValue = searchValue; } else if (searchValue.Contains("#Link:ReferencedObject")) // RO Link (roid) { searchValue = searchValue.Replace("1[END>", string.Empty).Trim(); string roid = ROFSTLookup.FormatRoidKey(searchValue.Substring(searchValue.LastIndexOf(" ")), true); if (roid != selectedChld.roid) { ROFSTLookup.rochild roc = MyROFSTLookup.GetRoChild(roid); ExpandNode(roc.roid); } lbFound.DataSource = null; lbFound.Visible = false; _lastSearchValue = searchValue; } else // if (searchValue != _lastSearchValue) { dicRoVals = MyROFSTLookup.Search(searchValue, searchTypeID, false, MaxNumSearchRecords); if (dicRoVals.Count > 0) { lbFound.SelectedValueChanged -= new EventHandler(lbFound_SelectedValueChanged); lbFound.DataSource = new BindingSource(dicRoVals, null); lbFound.ValueMember = "Key"; // roid lbFound.DisplayMember = "Value"; // default value lbFound.SelectionMode = SelectionMode.One; lbFound.SelectedIndex = -1; lbFound.Visible = true; lbFound.SelectedValueChanged += new EventHandler(lbFound_SelectedValueChanged); if (lbFound.Items != null && lbFound.Items.Count == 1) lbFound.SelectedIndex = 0; } else { lbFound.DataSource = null; lbFound.Visible = false; } _lastSearchValue = searchValue; } } else { _lastSearchValue = string.Empty; lbFound.DataSource = null; lbFound.Visible = false; } } catch { } } private void ResetSearch() { // Clear the Display/Info for Prev Selected RO Child tbROValue.Text = null; lbROId.Text = string.Empty; // Disable all buttons by default btnGoToRO.Enabled = false; btnSaveRO.Enabled = false; btnCancelRO.Enabled = false; btnPreviewRO.Enabled = false; } #endregion } }