using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Text.RegularExpressions; using AT.STO.UI.Win; using VEPROMS.CSLA.Library; namespace Volian.Controls.Library { public partial class DisplayTransition : UserControl { private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #region Properties private int _TranFmtIndx = -1; // stores selected transition format private ItemInfo _CurItemFrom; // stores what item transition is 'from' private TransitionInfo _CurTrans; // if modify, this is transition to modify public TransitionInfo CurTrans { get { return _CurTrans; } set { if (!Visible) return; if (value == null) // Insert a transition { if (MyRTB == null) return; if (_CurTrans == value && _CurItemFrom == MyRTB.MyItemInfo) return; _CurItemFrom = MyRTB.MyItemInfo; _TranFmtIndx = 0; btnTranSave.Enabled = btnTranCancel.Enabled = true; } else // Modify a transition { if (_CurTrans == value) return; _TranFmtIndx = value.TranType; _CurItemFrom = MyRTB.MyItemInfo; btnTranSave.Enabled = btnTranCancel.Enabled = false; } _CurTrans = value; _SavCurItemFrom = _CurItemFrom; _SavTranFmtIndx = _TranFmtIndx; TransitionFillIn(); } } // use the following if user selects 'cancel' button private ItemInfo _SavCurItemFrom; private int _SavTranFmtIndx; private bool _DoingRange = false; // flags if in 'range' transition mode private VETreeNode _RangeNode1; private VETreeNode _RangeNode2; // Use _RangeColor to show highlighting for steps selected in range. This is set from // calling methods from application settings. If not default to aquamarine. private Color _RangeColor = Color.LightGray; public Color RangeColor { get { return _RangeColor; } set { _RangeColor = value; } } private StepRTB _MyRTB; // Current MyDisplayRTB, i.e. insert transition to it. public StepRTB MyRTB { get { return _MyRTB; } set { if (!Visible) return; // add or remove events for if (_MyRTB != null) _MyRTB.LinkChanged -= new StepRTBLinkEvent(_MyRTB_LinkChanged); if (value == null) return; _MyRTB = value; _MyRTB.LinkChanged += new StepRTBLinkEvent(_MyRTB_LinkChanged); if (_MyRTB.MyLinkText == null) { CurTrans = null; } } } void _MyRTB_LinkChanged(object sender, StepPanelLinkEventArgs args) { //if (_MyRTB.MyLinkText == null) // CurTrans = null; //else //{ // StepPanelLinkEventArgs tmp = new StepPanelLinkEventArgs(null, e); CurTrans = args.MyLinkText.MyTransitionInfo; //} } private ItemInfo _CurrentItemProcedure; // the selected item's procedure private ItemInfo _CurrentToProcedure; // the 'to' location's procedure (may be same as _CurrentItemProcedure) private ItemInfo _CurrentProcedure; // current procedure used to set all of the controls (may switch between above two) private int _CurrentProcIndex; private bool _AlwaysDisableSets; // true if there is only 1 item in tree/combo for sets private Color _OrigGroupPanelSets; private Color _OrigGroupPanelProcs; private Color _OrigGroupPanelSects; private Color _OrigGroupPanelSteps; #endregion #region Constructors public DisplayTransition() { InitializeComponent(); } #endregion #region LoadControlData // TransitionFillIn uses other methods to fill in all controls on the transition tab. private bool _InitializingTrans; private void TransitionFillIn() { _InitializingTrans = true; if (_RangeNode1 != null || _RangeNode2 != null) ClearRangeTransition(); InitControls(); btnTranCancel.Enabled = false; _InitializingTrans = false; } private void InitControls() { _OrigGroupPanelSets = groupPanelTransitionSets.Style.BackColor; _OrigGroupPanelProcs = groupPanelTransitionProcs.Style.BackColor; _OrigGroupPanelSects = groupPanelTransitionSect.Style.BackColor; _OrigGroupPanelSteps = groupPanelTranstionSteps.Style.BackColor; ListBoxTranFmtFillIn(); // if new, use _CurItemFrom to setup the initial selections in the controls, // if modify, use the first transition to, _CurTrans // This item will be either a procedure, section or step, never a docversion ItemInfo selitm = _CurTrans==null?_CurItemFrom:_CurTrans.MyItemToID; // If this points to an invalid transtion, make it point to itself. if (selitm.PreviousID == null && selitm.ItemPartCount == 0 && selitm.ItemDocVersionCount == 0) { selitm = _CurItemFrom; } ItemInfo tmpitm = selitm; ItemInfo secitm = null; // Find the procedure level first. while (tmpitm.MyContent.Type != 0) { if (tmpitm.MyContent.Type >=10000 && tmpitm.MyContent.Type<20000) secitm = tmpitm; tmpitm = tmpitm.MyParent; } _CurrentProcedure = tmpitm; _CurrentToProcedure = _CurrentProcedure; if (_CurTrans == null) _CurrentItemProcedure = _CurrentProcedure; else { // use the transition from to get the procedure 'from'.... ItemInfo curfrom = _CurItemFrom; while (curfrom.MyContent.Type != 0) curfrom = curfrom.MyParent; _CurrentItemProcedure = curfrom; } // set other procedure related private variables. vlnTreeComboSetsFillIn(_CurrentProcedure); cbTranProcsFillIn(_CurrentProcedure); if (_CurrentProcedure.Sections != null) { cbTranSectsFillIn(secitm, secitm == null ? -1 : secitm.ItemID); // Fill step items, passing in the active step to the selected item, or the first // step if the selection was not at the step level. ItemInfo stpitm = null; if (selitm.MyContent.Type >= 20000) { if (_DoingRange) { tvInitHiliteRange(); //rangeSameLevel, stpitm, rngitm, (i1 < i2) ? i2 : i1); } else stpitm = selitm; } else if (secitm != null && secitm.Steps != null && secitm.Steps.Count > 0) stpitm = selitm.Steps[0]; if (!_DoingRange) tvTranFillIn(stpitm); // range code fills in tree. //if (_DoingRange) tvInitHiliteRange(rangeSameLevel, stpitm, rngitm, (i1 < i2) ? i2 : i1); } else { cbTranSects.Items.Clear(); tvTran.Nodes.Clear(); } SetControlsEnabling(); } private void tvInitHiliteRange() //bool rangeSameLevel, ItemInfo stpitm, ItemInfo rngitm, int uplevel) { ItemInfo toItm = _CurTrans.MyItemToID; ItemInfo rngItm = null; // figure out whether at same level, have same parent and have same HLS: ItemInfo itm1 = _CurTrans.MyItemToID; ItemInfo itm2 = _CurTrans.MyItemRangeID; bool samHLS = itm1.MyHLS.ItemID == itm2.MyHLS.ItemID; int lev1 = 0; int lev2 = 0; while (!itm1.IsHigh) { lev1++; itm1 = itm1.MyParent; } while (!itm2.IsHigh) { lev2++; itm2 = itm2.MyParent; } bool samLevel = lev1 == lev2; // For each range item, go to common level's parent. int cnt = lev1+1; ItemInfo sameParent1 = _CurTrans.MyItemToID; ItemInfo sameParent2 = _CurTrans.MyItemRangeID; while (cnt != 0) { if (sameParent1.IsHigh) break; sameParent1 = sameParent1.MyParent; } cnt = lev2+1; while (cnt != 0) { if (sameParent2.IsHigh) break; sameParent2 = sameParent2.MyParent; } tvTranFillIn(sameParent1); // if HLS, fill in from there, or it will fill in from common parent // now add nodes for the subtrees so that highlighting can be done. Do 'to' item // first. If 'range' item is at same level, won't need to do anymore processing. ItemInfo toItem = sameParent1.Ordinal<=sameParent2.Ordinal?_CurTrans.MyItemToID:_CurTrans.MyItemRangeID; ItemInfo rngItem = sameParent1.Ordinal<=sameParent2.Ordinal?_CurTrans.MyItemRangeID:_CurTrans.MyItemToID; List path = new List(); ItemInfo parRng = toItem; for (int i = 0; i < lev1+1; i++) { path.Insert(i, parRng); parRng = (ItemInfo)parRng.ActiveParent; } // Find sameParent1 in tree, expand down to toItem: tvFillInRangeNodes(path, (VETreeNode)tvTran.Nodes[0], lev1, true); path.Clear(); parRng = rngItem; for (int i = 0; i < lev2 + 1; i++) { path.Insert(i, parRng); parRng = (ItemInfo)parRng.ActiveParent; } tvFillInRangeNodes(path, (VETreeNode)tvTran.Nodes[0], lev2, false); tvTranRangeHilites(true, _RangeNode1, _RangeNode2); tvTran.SelectedNode = _RangeNode1; } private void tvFillInRangeNodes(List path, VETreeNode tn, int level, bool to) { VETreeNode tnExpand = null; while (tnExpand == null && tn != null) { ItemInfo ii = (ItemInfo)tn.VEObject; if (ii.ItemID == path[level].ItemID) tnExpand = tn; tn = (VETreeNode)tn.NextNode; } tnExpand.LoadChildren(false); if (level > 0) { tnExpand.Expand(); tvFillInRangeNodes(path, (VETreeNode)tnExpand.Nodes[0], level - 1, to); } else { if (to) _RangeNode1 = tnExpand; else _RangeNode2 = tnExpand; } } private void vlnTreeComboSetsFillIn(ItemInfo prcitm) { // from this procedure, walk up the tree storing the FolderInfos. This is done // so that the tree can be expanded highlighting (selecting) the current set. List filist = new List(); DocVersionInfo mydocversion = prcitm.ActiveParent as DocVersionInfo; FolderInfo tmpfi = mydocversion.ActiveParent as FolderInfo; while (tmpfi != null) { if (tmpfi.FolderID != 1) filist.Add(tmpfi); // don't add top folder tmpfi = tmpfi.ActiveParent as FolderInfo; } // Now start at the top folder. Continue to get children using the filist to determine // the expanded part of the tree. Note that if there is only 1 item at a level, // the level is not added to the tree, except if there are no sub-folders, i.e. // right before the docversion. Also note that docversions are not displayed // (at least for now - as of 2/14/08), this may change and if so uncomment (& fix/test) // the next section of code where docversions are processed. FolderInfo fi = FolderInfo.GetTop(); DropDownNode topnode = null; int cntnd = 0; while (fi.ChildFolderCount > 0) { // if there is more than 1 child, add this level of children to the // to the tree. The second part of the 'if' covers the last level of // folder. if ((fi.ChildFolders.Count > 1) || (fi.ChildFolders.Count==1 && fi.ChildFolders[0].FolderDocVersionCount>0)) { int indx = -1; int pathid = filist[filist.Count - 1].FolderID; foreach (FolderInfo fic in fi.ChildFolders) { DropDownNode newnode = new DropDownNode(fic.FolderID, fic.ToString()); int tmp = topnode==null?vlnTreeComboSets.DropDownControl.Nodes.Add(newnode):topnode.Nodes.Add(newnode); cntnd++; newnode.Tag = fic; if (fic.FolderID == pathid) indx = tmp; // flag the path to expand. else if (fic.ChildFolderCount > 0) // allow for '+' for tree expansion { DropDownNode tnt = new DropDownNode(0, "VLN_DUMMY"); newnode.Nodes.Add(tnt); } } topnode = topnode==null?(DropDownNode)vlnTreeComboSets.DropDownControl.Nodes[indx]:(DropDownNode)topnode.Nodes[indx]; } fi = (filist.Count > 0) ? FolderInfo.Get(filist[filist.Count - 1].FolderID) : null; if (filist.Count > 0) filist.RemoveAt(filist.Count - 1); } // if nothing was added to the tree, just put in the node above the docversions... if (vlnTreeComboSets.DropDownControl.Nodes.Count == 0) { cntnd++; fi = mydocversion.MyFolder; topnode = new DropDownNode(fi.FolderID, fi.ToString()); vlnTreeComboSets.DropDownControl.Nodes.Add(topnode); topnode.Tag = fi; } // if there is only one node in entire tree, disable selection... if (cntnd == 1) _AlwaysDisableSets = true; else _AlwaysDisableSets = false; // the following selects the set & displays its value in the combo box portion // of the tree combo control. vlnTreeComboSets.Value = topnode; vlnTreeComboSets.DropDownControl.SelectedNode = topnode; vlnTreeComboSets.DropDownControl.BeforeExpand += new TreeViewCancelEventHandler(vlnTreeComboSets_BeforeExpand); #region CheckIfNeeded Commented Out //vlnTreeComboSets.DropDownControl. = vlnTreeComboSets.Width; // The DropDownNode should be at a DocVersion now. The expanded DocVersion // is the one that matches mydocversion //tmpfi = mydocversion.ActiveParent as FolderInfo; //DocVersionInfoList dvlist = tmpfi.FolderDocVersions; //DropDownNode tnDV = null; // Once at a docversions, only allow working // draft sets. Use DocVersion that we're in, to expand it showing the active procedure. // first count how many versions can be displayed, i.e. only workingdraft? // if more than one, put out a tree node for them. //int cntdocv = 0; //foreach (DocVersionInfo dv in dvlist) //{ // if ((VersionTypeEnum)dv.VersionType == VersionTypeEnum.WorkingDraft) cntdocv++; //} //if (cntdocv>1) //{ // foreach (DocVersionInfo dv in dvlist) // { // if ((VersionTypeEnum)dv.VersionType == VersionTypeEnum.WorkingDraft) // { // DropDownNode tn = new DropDownNode(dv.VersionID, dv.ToString()); // tn.Tag = dv; // if (topnode != null) // topnode.Nodes.Add(tn); // else // vlnTreeComboSets.DropDownControl.Nodes.Add(tn); // if (dv.VersionID == mydocversion.VersionID) // { // tnDV = tn; // vlnTreeComboSets.Value = tnDV; // vlnTreeComboSets.DropDownControl.SelectedNode = tnDV; // } // //else if (dv.HasChildren) // allow for '+' for tree expansion // //{ // // DropDownNode tnt = new DropDownNode(0,"VLN_DUMMY"); // // tn.Nodes.Add(tnt); // //} // } // } //} #endregion } private void ListBoxTranFmtFillIn() { TransTypeList ttl = _CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList; listBoxTranFmt.Items.Clear(); for (int i = 0; i < ttl.Count; i++) listBoxTranFmt.Items.Add(ttl[i].TransFormat.Replace("?.","")); listBoxTranFmt.SelectedIndex = _TranFmtIndx; groupPanelTranFmt.Style.BackColor = (_CurTrans == null && _TranFmtIndx==0) ? Color.Yellow : Color.Orange; E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[_TranFmtIndx].TransUI; _DoingRange = (etm & E_TransUI.StepLast) == E_TransUI.StepLast; } private void tvTranFillIn(ItemInfo startitm) { tvTran.Nodes.Clear(); groupPanelTranstionSteps.Style.BackColor = _OrigGroupPanelSteps; if (startitm == null) return; // if the transition to point is a section or procedure, just return if (startitm.MyContent.Type < 20000) return; groupPanelTranstionSteps.Style.BackColor = Color.Cornsilk; // For the tree view, use parent, unless already at HLS. If at HLS, use this level. ItemInfo selitm = startitm.MyHLS; //if (_CurTrans == null)selitm = startitm.MyHLS; E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[listBoxTranFmt.SelectedIndex].TransUI; if (startitm.IsInRNO) startitm = selitm.FirstSibling; // if in RNO tree, start out with HLS else startitm = selitm!=null? selitm.FirstSibling:startitm.FirstSibling; bool setsel = false; while (startitm != null) { VETreeNode tvn = new VETreeNode(startitm, false); tvn.Tag = startitm; int active = this.tvTran.Nodes.Add(tvn); if (startitm.ItemID == selitm.ItemID) { tvTran.SelectedNode = tvTran.Nodes[active]; setsel = true; } startitm = (startitm.NextItemCount > 0 ? startitm.NextItems[0] : null); } if (!setsel) tvTran.SelectedNode = tvTran.Nodes[0]; tvTran.BeforeExpand += new TreeViewCancelEventHandler(tvTran_BeforeExpand); // bug fix. TreeView needs the next two lines to properly display the bottom node. jsj 01/08/2010 tvTran.ItemHeight++; tvTran.ItemHeight--; } private void cbTranSectsFillIn(ItemInfo secitm, int secstart) { cbTranSects.Items.Clear(); // if the transition points 'to' procedure, don't list the sections yet. if (secitm == null || secitm.MyContent.Type < 10000) return; // if sectstart is not -1, then use this as the section to select, otherwise // use the id for the item passed in. int startitm = secstart; if (secstart < 0) secstart = secitm.ItemID; ItemInfo selitm = secitm; // this is the selected 'section' secitm = secitm.FirstSibling; while (secitm != null) { // if the selected transition format requires a step be selected (show only step sections), only add step sections E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[listBoxTranFmt.SelectedIndex].TransUI; if (((!((etm & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone)) && secitm.IsStepSection) || ((etm & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone)) { int active = cbTranSects.Items.Add(secitm); if (secitm.ItemID == secstart) cbTranSects.SelectedIndex = active; } secitm = (secitm.NextItemCount > 0 ? secitm.NextItems[0] : null); } } private void cbTranProcsFillIn(ItemInfo prcitm) { cbTranProcs.Items.Clear(); ItemInfo selitm = prcitm; // this is the selected 'section' prcitm = prcitm.FirstSibling; while (prcitm != null) { int active = cbTranProcs.Items.Add(prcitm); if (_CurrentProcedure.ContentID == prcitm.MyContent.ContentID) _CurrentProcIndex = active; if (prcitm.MyContent.ContentID == selitm.MyContent.ContentID) cbTranProcs.SelectedIndex = active; prcitm = (prcitm.NextItemCount > 0 ? prcitm.NextItems[0] : null); } } private void SetControlsEnabling() { groupPanelTransitionSets.Style.BackColor = _OrigGroupPanelSets; groupPanelTransitionProcs.Style.BackColor = _OrigGroupPanelProcs; groupPanelTransitionSect.Style.BackColor = _OrigGroupPanelSects; // Based on selection & enum representing the transition format, determine the enabling of associated controls if (_CurItemFrom == null) return; int indx = listBoxTranFmt.SelectedIndex; if (listBoxTranFmt.SelectedIndex < 0 || listBoxTranFmt.SelectedIndex > listBoxTranFmt.Items.Count) indx = 0; E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[indx].TransUI; // do the set tree/combo & procedure combo. in 16-bit system it was types 0, 3, 5 vlnTreeComboSets.Enabled = false; if ((etm & E_TransUI.ProcMenu) == E_TransUI.ProcMenu) { if (!_AlwaysDisableSets) { vlnTreeComboSets.Enabled = true; groupPanelTransitionSets.Style.BackColor = Color.Cornsilk; } cbTranProcs.Enabled = true; groupPanelTransitionProcs.Style.BackColor = Color.Cornsilk; } else { cbTranProcs.SelectedIndex = _CurrentProcIndex > 0 ? _CurrentProcIndex : 0; cbTranProcs.Enabled = false; } // Do section combo, in 16-bit system it was types 0, 3, 4, 5 if (cbTranSects.Items.Count > 0 && ( //((etm & E_TransUI.SectDefault) == E_TransUI.SectDefault) || ((etm & E_TransUI.SectMenuAny) == E_TransUI.SectMenuAny) || ((etm & E_TransUI.SectMenuStep) == E_TransUI.SectMenuStep))) { cbTranSects.Enabled = true; groupPanelTransitionSect.Style.BackColor = Color.Cornsilk; } else { cbTranSects.Enabled = false; } // check for range - if no range, then range button/label & step tree selections should be // 'cleared/invisble'. btnTranRangeClear.Visible = _DoingRange; lblxTranRangeTip.Visible = _DoingRange; if (_DoingRange) { lblxTranRangeTip.BackColor = Color.Yellow; } // if any previous nodes selected for range - clear them here if (!_DoingRange && _RangeNode1 != null) ClearRangeTransition(); // Always allow for step selection if there are items. if (tvTran.Nodes.Count > 0) tvTran.Enabled = true; // if a step doesn't need to be specified, then show the cbIncStepNum which allows // user to define whether a step number is to be included in transition. if ((etm & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone) { cbIncStepNum.Visible = true; // may or may not allow steps to be selected, i.e. if this is checked then enable // tree view for step selection: cbIncStepNum.Checked = true; if (_CurTrans != null && _CurTrans.MyItemToID.MyContent.Type < 20000) { cbIncStepNum.Checked = false; tvTran.Enabled = false; } // the following test is for Section/Optional Step (type 4 and related). If is a step section and its // the only step section in the procedure then a step number must be selected. int cntsect = 0; foreach (ItemInfo ii in _CurItemFrom.MyProcedure.Sections) if (ii.IsStepSection) cntsect++; if (((etm & E_TransUI.ProcCur) == E_TransUI.ProcCur) && ((etm & E_TransUI.SectMenuAny) == E_TransUI.SectMenuAny) && cntsect==1) { tvTran.Enabled = true; cbIncStepNum.Visible = false; } } else cbIncStepNum.Visible = false; } #endregion #region Events private void vlnTreeComboSets_BeforeExpand(object sender, TreeViewCancelEventArgs e) { DropDownNode par = ((DropDownNode)e.Node); // get first child's text, if it has one & if the text is VLN_DUMMY, load children DropDownNode tn = null; if (par.Nodes.Count > 0) tn = (DropDownNode)par.Nodes[0]; if (tn.Text == "VLN_DUMMY") // 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.ChildFolders) { DropDownNode newnode = new DropDownNode(fic.FolderID, fic.ToString()); par.Nodes.Add(newnode); newnode.Tag = fic; if (fic.HasChildren) // allow for '+' for tree expansion { DropDownNode tnt = new DropDownNode(0, "VLN_DUMMY"); newnode.Nodes.Add(tnt); } } } else if (fi.FolderDocVersionCount > 0) { foreach (DocVersionInfo dv in fi.FolderDocVersions) { if ((VersionTypeEnum)dv.VersionType == VersionTypeEnum.WorkingDraft) { DropDownNode newnode = new DropDownNode(dv.VersionID, dv.ToString()); newnode.Tag = dv; par.Nodes.Add(newnode); } } } } vlnTreeComboSets.Value = par; vlnTreeComboSets.DropDownControl.SelectedNode = par; } private void DropDown_FinishEditing(object sender, DropDownValueChangedEventArgs e) { DropDownNode selnd = (DropDownNode)vlnTreeComboSets.DropDownControl.SelectedNode; Object obj = selnd.Tag; // only allow selections from proc, sect & step controls if the user has // selected a folder with only 1 working draft docversion or has // selected the docversion itself.... bool defines_set = false; FolderInfo fi = null; if (obj is FolderInfo) { fi = (FolderInfo)obj; if (fi.ChildFolderCount == 0) { // note that the folder may contain more than one docversion, check for // only 1 working draft. int cntwd = 0; foreach (DocVersionInfo dvt in fi.FolderDocVersions) { if ((VersionTypeEnum)dvt.VersionType == VersionTypeEnum.WorkingDraft) cntwd++; } if (cntwd == 1) defines_set = true; } } else if (obj is DocVersionInfo) defines_set = true; if (!defines_set) { MessageBox.Show("Based on your selection, cannot get list of procedures, narrow the procedure set selection."); // disable ALL other controls cbTranProcs.Enabled = false; cbTranSects.Enabled = false; tvTran.Enabled = false; return; } // get to DocVersion node, if at folder... If there are no procedures, notify // the user and return (a transition must at least go to a procedure). // Otherwise, enable/disable controls based on format type of transition. DocVersionInfo dv = null; if (fi != null) { foreach (DocVersionInfo dvt in fi.FolderDocVersions) { if ((VersionTypeEnum)dvt.VersionType == VersionTypeEnum.WorkingDraft) { dv = dvt; break; } } } else dv = (DocVersionInfo)obj; if (dv.Procedures.Count < 1) { MessageBox.Show("There are no procedures in this set. Cannot insert a transition within it."); cbTranProcs.Enabled = false; cbTranSects.Enabled = false; tvTran.Enabled = false; return; } cbTranProcsFillIn(dv.Procedures[0]); cbTranProcs.SelectedIndex = 0; SetControlsEnabling(); } private void listBoxTranFmt_Click(object sender, EventArgs e) { if (_InitializingTrans) return; if (listBoxTranFmt.SelectedIndex == _TranFmtIndx) return; if (_RangeNode1 != null) ClearRangeTransition(); // if this selection needs a step, but not a procedure, use the current procedure & the section list may need to updated // with step only section. List the step sections of the current procedure..... E_TransUI etmprev = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[_TranFmtIndx].TransUI; E_TransUI etmnew = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[listBoxTranFmt.SelectedIndex].TransUI; if (((etmnew & E_TransUI.ProcCur) == E_TransUI.ProcCur) && ((etmprev & E_TransUI.ProcCur) == E_TransUI.ProcCur) != ((etmnew & E_TransUI.ProcCur) == E_TransUI.ProcCur)) { _CurrentProcedure = _CurrentItemProcedure; cbTranProcsFillIn(_CurrentProcedure); int sectstartid = FindSectionStart(_CurrentProcedure); IList chldrn = _CurrentProcedure.GetChildren(); if (chldrn != null && chldrn.Count > 0) cbTranSectsFillIn((ItemInfo)chldrn[0], sectstartid); } _TranFmtIndx = listBoxTranFmt.SelectedIndex; groupPanelTranFmt.Style.BackColor = (_CurTrans == null && _TranFmtIndx == 0) ? Color.Yellow : Color.Orange; E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[_TranFmtIndx].TransUI; _DoingRange = (etm & E_TransUI.StepLast) == E_TransUI.StepLast; // get section selected and if it's a step section, fill in the treeview of steps if (cbTranSects.Items.Count > 0) { ItemInfo secitm = (ItemInfo) cbTranSects.SelectedItem; if (secitm == null || !secitm.IsStepSection) { tvTran.Nodes.Clear(); tvTran.Enabled = false; } else { _InitializingTrans = true; // just initializing now, don't set any ranges, etc. tvTranFillIn(secitm.Steps[0]); tvTran.Enabled = true; _InitializingTrans = false; } } SetControlsEnabling(); // if doing a 'new' range, no node is selected in tree. Without this, the first node in the // tree was the selected node which was throwing off the logic for defining the _RangeNode1 // and _RangeNode2 if (_DoingRange) tvTran.SelectedNode = null; } //private void btnUp1_Click(object sender, EventArgs e) //{ // // if StepAllowNone, then use the second node in the tree view. // int indx = 0; // if (tvTran.Nodes[0].Tag == null) indx = 1; // // if at HLS, don't do anything. // ItemInfo curitm = (ItemInfo)((VETreeNode)tvTran.Nodes[indx]).VEObject; // if (curitm.IsHigh) return; // tvTranFillIn(curitm); //} private void tvTran_BeforeExpand(object sender, TreeViewCancelEventArgs e) { VETreeNode tn = ((VETreeNode)e.Node); // true fixes empty expand, but allows for transitions 'way down' in RNO tree. HVJ & PAL wanted to // allow this (12/2/09). Note that this was changed to not allow transitions // to RNOs (10/2010), this 'feature' will be added at some later date. tn.ChildrenLoaded = false; tn.LoadChildren(false); } private void cbTranSects_SelectedIndexChanged(object sender, EventArgs e) { if (_InitializingTrans) return; // a different section was selected, if step section, update step list, otherwise, empty // it & disable. ItemInfo secitm = (ItemInfo)cbTranSects.SelectedItem; if (!secitm.IsStepSection) { tvTran.Nodes.Clear(); tvTran.Enabled = false; // Set Save & Cancel enabling, depending on whether section can be an endpoint. E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[_TranFmtIndx].TransUI; bool noStepNeeded = (etm & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone; SaveCancelEnabling(noStepNeeded, secitm); } else { _InitializingTrans = true; // just initializing now, don't set any ranges, etc. tvTranFillIn(secitm.Steps[0]); tvTran.Enabled = true; // if doing a 'new' range, no node is selected in tree. Without this, the first node in the // tree was the selected node which was throwing off the logic for defining the _RangeNode1 // and _RangeNode2 if (_DoingRange) tvTran.SelectedNode = null; _InitializingTrans = false; } } private int FindSectionStart(ItemInfo prcitm) { ProcedureConfig pc = (ProcedureConfig)prcitm.MyConfig; int sectstartid = -1; string ss = pc == null ? null : pc.SectionStart; if (ss != null) sectstartid = System.Convert.ToInt32(ss); return sectstartid; } private void cbTranProcs_SelectedIndexChanged(object sender, EventArgs e) { if (_InitializingTrans) return; ItemInfo prcitm = (ItemInfo)cbTranProcs.SelectedItem; if (prcitm == null || prcitm.Sections == null || prcitm.Sections.Count < 1) { cbTranSects.Items.Clear(); tvTran.Nodes.Clear(); return; } int sectstartid = FindSectionStart(prcitm); IList chldrn = prcitm.GetChildren(); cbTranSectsFillIn((ItemInfo)chldrn[0], sectstartid); } private void tvTran_AfterSelect(object sender, TreeViewEventArgs e) { if (_InitializingTrans) return; E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[listBoxTranFmt.SelectedIndex].TransUI; if ((etm & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone && tvTran.SelectedNode.Tag==null) { btnTranSave.Enabled = true; return; } // check if node is a true end-point, i.e. not a 'part' node. If part node, don't // allow selection. bool allowSave = false; VETreeNode vt = tvTran.SelectedNode as VETreeNode; ItemInfo selii = vt.VEObject as ItemInfo; if (vt != null) { if (selii != null) allowSave = true; } if (!_DoingRange) { SaveCancelEnabling(allowSave, selii); return; } if (!allowSave) { MessageBox.Show("Must select a valid step, not a grouping part such as 'RNO', 'Steps', etc"); return; } if (_DoingRange) { if (_RangeNode1 == null || (_RangeNode1 != null && _RangeNode2 != null)) { if (_RangeNode1 != null) tvTranRangeHilites(false, _RangeNode1, _RangeNode2); tvTran.SelectedNode.BackColor = _RangeColor; _RangeNode1 = (VETreeNode)tvTran.SelectedNode; _RangeNode2 = null; lblxTranRangeTip.Text = "Select Last Step \r\nfor Range"; lblxTranRangeTip.BackColor = Color.LightPink; btnTranSave.Enabled = false; } else { if (_RangeNode2 != null) tvTranRangeHilites(false, _RangeNode1, _RangeNode2); _RangeNode2 = (VETreeNode)tvTran.SelectedNode; tvTran.SelectedNode.BackColor = _RangeColor; tvTranRangeHilites(true, _RangeNode1, _RangeNode2); lblxTranRangeTip.Text = "Select First Transition\r\nfor Range"; lblxTranRangeTip.BackColor = Color.Yellow; btnTranSave.Enabled = true; } } } private void SaveCancelEnabling(bool allowSave, ItemInfo selii) { btnTranSave.Enabled = allowSave; if (CurTrans != null) { if (CurTrans.ToID == selii.ItemID) btnTranCancel.Enabled = btnTranSave.Enabled = false; else { btnTranCancel.Enabled = true; btnTranSave.Enabled = allowSave; } } else btnTranSave.Enabled = allowSave; } private void btnTranCancel_Click(object sender, EventArgs e) { btnTranSave.Enabled = false; btnTranCancel.Enabled = false; _CurItemFrom = _SavCurItemFrom; _TranFmtIndx = _SavTranFmtIndx; TransitionFillIn(); } private void btnTranRangeClear_Click(object sender, EventArgs e) { ClearRangeTransition(); } private void btnTranSave_Click(object sender, EventArgs e) { string trantxt = "(Resolved Transition Text)"; string linktxt = null; E_TransUI etm = (E_TransUI)_CurItemFrom.ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[listBoxTranFmt.SelectedIndex].TransUI; // if must have a step, test for this first. if (!((etm & E_TransUI.StepAllowNone) == E_TransUI.StepAllowNone)) // _tranitem1 is set from step tree node. { if (tvTran.SelectedNode==null) { MessageBox.Show("Must 'Select Step' for transition 'to'"); return; } } ItemInfo toItem = null; ItemInfo rangeItem = null; if ((etm & E_TransUI.StepLast) == E_TransUI.StepLast) //range { if (_RangeNode1==null) { MessageBox.Show("Must 'Select Step' for transition 'to'"); return; } toItem = (ItemInfo)_RangeNode1.VEObject; if (_RangeNode2 == null && tvTran.SelectedNode == null) { MessageBox.Show("Must 'Select Step' for range transition 'to'"); return; } if (_RangeNode2 == null) _RangeNode2 = (VETreeNode)tvTran.SelectedNode; rangeItem = (ItemInfo)_RangeNode2.VEObject; // If this is Transition type 2, then make 'rangenode2' same as rangenode1 // This will get resolved when transition text is resolved. This case represents // range from rangenode1 to last sibling. Note that this is only done if within // the same sibling group. Otherwise, get the second item in the // range, based on current tree view selection. if (listBoxTranFmt.SelectedIndex == 2) { // if type 2 and not a HLS and the range is within the same hls, then set // to and range to be equal. When text gets resolved, this case generates // a list represent the toid,,,lastsibling. if (!toItem.IsHigh && toItem.MyHLS.ItemID == rangeItem.MyHLS.ItemID) rangeItem = toItem; else rangeItem = rangeItem.MyHLS; } // Check that the two items are of the below the section type. if (toItem.MyContent.Type < 20000 || rangeItem.MyContent.Type < 20000) { MessageBox.Show("Must select two items at the step level or below, i.e. no sections, procedures, etc."); return; } // be sure that the order is right, i.e. to is before range in list. if (toItem.ItemID != rangeItem.ItemID) { Boolean switchIds = false; // check for order of hls first, then do within sibling list. if (toItem.MyHLS.Ordinal > rangeItem.MyHLS.Ordinal) switchIds = true; else if (toItem.Ordinal > rangeItem.Ordinal) switchIds = true; if (switchIds) { ItemInfo switchItem = toItem; toItem = rangeItem; rangeItem = switchItem; } } linktxt = string.Format("#Link:TransitionRange:{0} {1} {2}", listBoxTranFmt.SelectedIndex, toItem.ItemID, rangeItem.ItemID); } else if ((etm & E_TransUI.StepFirst) == E_TransUI.StepFirst) { if (tvTran.SelectedNode != null && (cbIncStepNum.Visible == false || cbIncStepNum.Checked)) { VETreeNode vtn = (VETreeNode)tvTran.SelectedNode; toItem = (ItemInfo)vtn.VEObject; } else toItem = (ItemInfo)cbTranSects.SelectedItem; // didn't select a step. linktxt = string.Format("#Link:Transition:{0} {1}", listBoxTranFmt.SelectedIndex, toItem.ItemID); } // toItem may have been set in the 'Range' selection code above. if (toItem == null && (etm & E_TransUI.SectMenuAny) == E_TransUI.SectMenuAny) { if (tvTran.Enabled == false || (toItem!=null && toItem.IsAccPages)) toItem = (ItemInfo)cbTranSects.SelectedItem; else { VETreeNode vtn = (VETreeNode)tvTran.SelectedNode; if (vtn.Tag == null) toItem = (ItemInfo)cbTranSects.SelectedItem; else toItem = (ItemInfo)vtn.VEObject; } if (toItem==null) { MessageBox.Show("Must 'Select Section' or 'Select Step' for transition 'to'"); return; } linktxt = string.Format("#Link:Transition:{0} {1}", listBoxTranFmt.SelectedIndex, toItem.ItemID); } if (toItem == null && (((etm & E_TransUI.ProcCur) == E_TransUI.ProcCur) || ((etm & E_TransUI.ProcMenu) == E_TransUI.ProcMenu))) { toItem = (ItemInfo)cbTranProcs.SelectedItem; if (toItem == null) { MessageBox.Show("Must select an item for transition 'to'"); return; } linktxt = string.Format("#Link:Transition:{0} {1}", listBoxTranFmt.SelectedIndex, toItem.ItemID); } // Can I build the text right now? trantxt = TransitionText.GetResolvedText(_MyRTB.MyItemInfo, listBoxTranFmt.SelectedIndex,toItem,rangeItem ?? toItem); int ss = _MyRTB.SelectionStart;// Remember where the link is being added _MyRTB.InsertTran(trantxt, linktxt);// Insert the LINK _MyRTB.SaveText();// Save the text with the LINK - This also moves the cursor to the end of the text // By selecting a starting position within a link, StepRTB (HandleSelectionChange) will select the link _MyRTB.Select(ss + 7 + trantxt.Length, 0);// Try 7 for i2) { VETreeNode t = node2; node2 = node1; node1 = t; } // Turn Hilighting on/off (depending on bool argument) between the two nodes // they may be at different tree levels. // find common parent level first and save the 'top parent' node for each selection. VETreeNode top1 = node1; VETreeNode top2 = node2; // loop, walking up node2's tree checking against node1. If not found, go to node1 // parent, etc. bool foundcommon = false; while (!foundcommon && top1 != null) { while (!foundcommon & top2 != null) { if (top1.Parent == top2.Parent) foundcommon = true; else top2 = (VETreeNode)top2.Parent; } if (!foundcommon) { top2 = node2; top1 = (VETreeNode)top1.Parent; } } // work down from node1. VETreeNode cur = node1; while (cur != null) { cur.BackColor = on ? _RangeColor : tvTran.BackColor; cur = (VETreeNode)(cur.NextNode == null ? cur.Parent : cur.NextNode); // if these nodes were at the same level, then stop after the current node = range2 if (cur == top1) cur = null; // stop at top if (cur == top2) top1 = cur = null; } // set background for highest level between two nodes. cur = top1==null?null:(VETreeNode)top1.NextNode; while (cur != null) { cur.BackColor = on ? _RangeColor : tvTran.BackColor; cur = (cur == top2) ? null : (VETreeNode)cur.NextNode; } // finish subtree of second node in range. cur = top2==node2?null:node2; while (cur != null) { cur.BackColor = on ? _RangeColor : tvTran.BackColor; cur = (VETreeNode)(cur.PrevNode == null ? cur.Parent : cur.PrevNode); if (cur == top2) cur = null; // stop at top } // hilite last selection.. top2.BackColor = on ? _RangeColor : tvTran.BackColor; } #endregion private void cbIncStepNum_CheckedChanged(object sender, EventArgs e) { tvTran.Enabled=cbIncStepNum.Checked; } } }