using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using VEPROMS.CSLA.Library; using System.Text.RegularExpressions; namespace Volian.Controls.Library { #region Enums public enum ChildRelation : int { None = 0, After = 1, Before = 2, RNO = 3 } public enum ExpandingStatus : int { No = 0, Expanding = 1, Colapsing = 2, Hiding = 4, Showing = 8, Done = 16 } #endregion public partial class StepItem : UserControl { #region Private Fields private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private StepPanel _MyStepPanel; public StepPanel MyStepPanel { get { return _MyStepPanel; } set { _MyStepPanel = value; } } private ChildRelation _MyChildRelation; private StepItem _MyParentStepItem = null; private StepItem _MySectionStepItem; private StepItem _MyPreviousStepItem = null; private StepItem _MyNextStepItem = null; private bool _ChildrenLoaded = false; private List _MyBeforeStepItems; public List MyBeforeStepItems { get { return _MyBeforeStepItems; } set { _MyBeforeStepItems = value; } } private List _MyAfterStepItems; public List MyAfterStepItems { get { return _MyAfterStepItems; } set { _MyAfterStepItems = value; } } private List _MyRNOStepItems; public List MyRNOStepItems { get { return _MyRNOStepItems; } set { _MyRNOStepItems = value; } } public Label MyLabel { get { return lblTab; } } private StepSectionLayoutData _MyStepSectionLayoutData; private bool _Loading = true; private StepData _MyStepData; private ItemInfo _MyItemInfo; private static int _WidthAdjust = 3; private string _TabFormat; private int _ExpandPrefix = 0; private int _ExpandSuffix = 0; private ExpandingStatus _MyExpandingStatus = ExpandingStatus.No; private bool _Colapsing = false; private bool _Moving = false; private int _RNOLevel = 0; private int _SeqLevel = 0; private int _Type; private bool _Circle = false; private bool _CheckOff = false; private bool _ChangeBar = false; #endregion #region Properties /// /// This returns the section or procedure for the current item. /// If the item is a step or section, it returns the section /// If it is a procedure, it returns the procedure /// public StepItem MySectionStepItem { get { if (_MySectionStepItem == null) { if (MyItemInfo.IsSection || MyItemInfo.IsProcedure) _MySectionStepItem = this; else _MySectionStepItem = _MyParentStepItem.MySectionStepItem; } return _MySectionStepItem; } set { _MySectionStepItem = value; } } /// /// Gets or Sets ItemInfo /// public ItemInfo MyItemInfo { get { return _MyItemInfo; } set { _MyItemInfo = value; int typ = (int)value.MyContent.Type; if (typ >= 20000) { int stepType = typ % 10000; _MyStepData = value.ActiveFormat.PlantFormat.FormatData.StepDataList[stepType]; } #if(DEBUG) // TODO: This formatting should come from the format file if (value.MyContent.Type == 20002) Circle = true; if (_TabFormat == "o ") CheckOff = true; if ((value.ItemID % 25) == 0) ChangeBar = true; #endif value.MyContent.Changed += new ContentInfoEvent(MyContent_Changed); } } void MyContent_Changed(object sender) { // Update the text to reflect the content change MyStepRTB.MyItemInfo=MyStepRTB.MyItemInfo; // Reset Text // TODO: Need code to update tabs. } /// /// Used to connect the RichTextBox with the menus and toolbars /// public StepRTB MyStepRTB { get { return _MyStepRTB; } } /// /// Return the Parent StepItem /// private StepItem UpOneStepItem { get { StepItem tmp = this; while (tmp != null && tmp.MyParentStepItem == null) tmp = tmp.MyPreviousStepItem; if (tmp != null) return tmp.MyParentStepItem; return null; } } /// /// Sets the parent and postions the item with respect to the parent /// public StepItem MyParentStepItem { get { return _MyParentStepItem; } set { _MyParentStepItem = value; if (_MyParentStepItem != null) { switch (_MyChildRelation) { case ChildRelation.None: // Same as after case ChildRelation.After: // The size depends upon the parent type int iType = (int)_MyParentStepItem._Type; switch (iType / 10000) { case 0: // Procedure ItemLocation = new Point(_MyParentStepItem.ItemLocation.X + 20, _MyParentStepItem.Bottom); ItemWidth = _MyStepPanel.ToDisplay(_MyStepSectionLayoutData.ColT) + _MyStepPanel.ToDisplay(_MyStepSectionLayoutData.WidT); break; case 1: // Section ItemLocation = new Point(_MyParentStepItem.ItemLocation.X + 20, _MyParentStepItem.Bottom); int borderWidth = _MyStepRTB.Width - _MyStepRTB.ClientRectangle.Width; TextWidth = _WidthAdjust + borderWidth + _MyStepPanel.ToDisplay(_MyStepSectionLayoutData.WidSTableEdit, Convert.ToInt32(_MyStepSectionLayoutData.PMode) - 1); break; case 2: // Step // if Table then determine width and location based upon it's parent's location if (_MyStepData.Type == "TABLE" || _MyStepData.ParentType == "TABLE") { _MyStepRTB.Font = _MyStepData.Font.WindowsFont; ItemWidth = (int)TableWidth(_MyStepRTB.Font, _MyItemInfo.MyContent.Text); ItemLocation = new Point(50, _MyParentStepItem.Bottom); ItemLocation = TableLocation(_MyParentStepItem, _MyStepSectionLayoutData, ItemWidth); } else { ItemLocation = new Point(_MyParentStepItem.TextLeft, _MyParentStepItem.Bottom); ItemWidth = _MyParentStepItem.TextWidth; } break; } break; case ChildRelation.RNO: if (RNOLevel <= _MyStepPanel.MaxRNO) { int colR = _MyStepPanel.ToDisplay(_MyStepSectionLayoutData.ColRTable, Convert.ToInt32(_MyStepSectionLayoutData.PMode) - 1); if (colR - _MyParentStepItem.Width < 0) colR = _MyParentStepItem.Width + 0; ItemLocation = new Point(_MyParentStepItem.ItemLeft + RNOLevel * colR, _MyParentStepItem.Top); } else { TextLocation = new Point(_MyParentStepItem.TextLeft, _MyParentStepItem.BottomMostStepItem.Bottom); } // Same size as the Parent TabFormat = ""; TextWidth = _MyParentStepItem.TextWidth; break; case ChildRelation.Before: Location = new Point(_MyParentStepItem.Left + 20, _MyParentStepItem.Top); _MyStepPanel.ItemMoving++; _MyParentStepItem.Top = Bottom; _MyStepPanel.ItemMoving--; // Could be a Caution or Note - Need to get WidT Width = _MyStepPanel.ToDisplay(_MyStepSectionLayoutData.WidT); break; } } } } /// /// The left edge of the Tab /// public int ItemLeft { get { return Left + lblTab.Left; } set { Left = value - lblTab.Left; } } /// /// The Top of the StepItem /// public int ItemTop { get { return Top; } set { _MyStepPanel.ItemMoving++; Top = value; _MyStepPanel.ItemMoving--; } } /// /// The Location of the Tab /// public Point ItemLocation { get { return new Point(Location.X + lblTab.Left, Location.Y); } set { Location = new Point(value.X - lblTab.Left, value.Y); } } /// /// Width of the Tab and RTB /// public int ItemWidth { get { return Width - lblTab.Left; } set { Width = value + lblTab.Left; } } /// /// Width of the RichTextBox /// public int TextWidth { get { return _MyStepRTB.Width; } set { Width = value + lblTab.Left + lblTab.Width; } } /// /// Location of the RichTextBox /// public Point TextLocation { get { return new Point(Location.X + _MyStepRTB.Left, Location.Y); } set { Location = new Point(value.X - _MyStepRTB.Left, value.Y); } } /// /// Left edge of the RichTextBox /// public int TextLeft { get { return Left + _MyStepRTB.Left; } } /// /// Tab Format used for outputing the Tab /// public string TabFormat { get { return _TabFormat; } set { _TabFormat = value; if (_MyItemInfo != null) { string tabString = _TabFormat; switch (_Type / 10000) { case 0: // Procedure //// TIMING: DisplayItem.TimeIt("TabFormat Start"); tabString = _MyItemInfo.MyContent.Number.PadRight(20); //// TIMING: DisplayItem.TimeIt("TabFormat End"); break; case 1: // Section //// TIMING: DisplayItem.TimeIt("TabFormat Start"); tabString = _MyItemInfo.MyContent.Number.PadRight(20); //// TIMING: DisplayItem.TimeIt("TabFormat End"); break; case 2: // Step //// TIMING: DisplayItem.TimeIt("TabFormat Start"); //int ordinal = _MyItem.Ordinal; int ordinal = Ordinal; //// TIMING: DisplayItem.TimeIt("TabFormat End"); string alpha = AlphabeticalNumbering.Convert(ordinal); tabString = tabString.Replace("", alpha.ToLower()); tabString = tabString.Replace("", alpha); string roman = RomanNumeral.Convert(ordinal); tabString = tabString.Replace("", roman.ToLower()); tabString = tabString.Replace("", roman); tabString = tabString.Replace("", ordinal.ToString().PadLeft(2)); tabString = tabString.Replace("", MyID.ToString()); break; } lblTab.Text = tabString; lblTab.Width = tabString.Length * 8; _MyStepRTB.Left = lblTab.Left + lblTab.Width;// +2; _MyStepRTB.Width = Width - _MyStepRTB.Left; // TODO: Performance - SetToolTip(); } } } /// /// This is the "number" of the item (1, 2, 3 etc.) for Substeps /// public int Ordinal { get { int count = 1; for (StepItem tmp = this; tmp.MyPreviousStepItem != null; tmp = tmp.MyPreviousStepItem) count++; return count; } } /// /// Sets the previous item and adjusts locations /// public StepItem MyPreviousStepItem { get { return _MyPreviousStepItem; } set { _MyPreviousStepItem = value; if (_MyPreviousStepItem != null) { Location = new Point(_MyPreviousStepItem.Left, _MyPreviousStepItem.BottomMostStepItem.Bottom); Width = MyPreviousStepItem.Width; switch (_MyChildRelation) { case ChildRelation.None: break; case ChildRelation.After: break; case ChildRelation.RNO: break; case ChildRelation.Before: _MyStepPanel.ItemMoving++; UpOneStepItem.Top = BottomMostStepItem.Bottom; _MyStepPanel.ItemMoving--; break; } if (_MyPreviousStepItem.MyNextStepItem != this) _MyPreviousStepItem.MyNextStepItem = this; } } } /// /// Sets the next item and adjusts the location, /// This also sets the previous for the "next" item /// which adjusts other locations. /// public StepItem MyNextStepItem { get { return _MyNextStepItem; } set { _MyNextStepItem = value; if (_MyNextStepItem != null) { if (_MyNextStepItem.MyPreviousStepItem != this) { _MyNextStepItem.MyPreviousStepItem = this; MyNextStepItem.Location = new Point(Left, Bottom); } } } } /// /// returns the TopMostChild /// public StepItem TopMostStepItem { get { if (Expanded && _MyBeforeStepItems != null) return _MyBeforeStepItems[0].TopMostStepItem; return this; } } /// /// Returns the bottom location (Top + Height) /// public new int Bottom { get { return Top + (Visible ? Height : 0); } } /// /// Bottom most child /// public StepItem BottomMostStepItem { get { StepItem tmpr = null; // BottomMost RNO if ((MyExpandingStatus != ExpandingStatus.No || Expanded) && _MyRNOStepItems != null) tmpr = _MyRNOStepItems[_MyRNOStepItems.Count - 1].BottomMostStepItem; StepItem tmpa = this; // BottomMost After if ((MyExpandingStatus != ExpandingStatus.No || Expanded) & _MyAfterStepItems != null) tmpa = _MyAfterStepItems[_MyAfterStepItems.Count - 1].BottomMostStepItem; // return the bottom most of the two results if (tmpr == null) return tmpa; if (tmpa.Bottom >= tmpr.Bottom) return tmpa; return tmpr; } } /// /// First sibling /// private StepItem FirstSiblingStepItem { get { StepItem tmp = this; while (tmp.MyPreviousStepItem != null) tmp = tmp.MyPreviousStepItem; return tmp; } } /// /// Last sibling /// private StepItem LastSiblingStepItem { get { StepItem tmp = this; while (tmp.MyNextStepItem != null) tmp = tmp.MyNextStepItem; return tmp; } } /// /// Returns the status of the vlnExpander unless it is in the process of expanding or collapsing /// If it is colapsing it returns false /// If it is expanding it returns true /// public bool Expanded { get { return !_Colapsing && (MyExpandingStatus != ExpandingStatus.No || _MyvlnExpander.Expanded); } set { _MyvlnExpander.Expanded = value; } } /// /// Sets or Gets expanding status /// public ExpandingStatus MyExpandingStatus { get { return _MyExpandingStatus; } set { _MyExpandingStatus = value; } } /// /// Gets or sets colapsing /// public bool Colapsing { get { return _Colapsing; } set { _Colapsing = value; } } /// /// Gets or Sets the ability to expand /// public bool CanExpand { get { return _MyvlnExpander.Visible; } set { _MyvlnExpander.Visible = value; } } /// /// Gets the text from the content /// public string MyText { get { return _MyItemInfo == null ? null : _MyItemInfo.MyContent.Text; } } /// /// Gets the ItemID from the ItemInfo /// public int MyID { get { return _MyItemInfo == null ? 0 : _MyItemInfo.ItemID; } } /// /// Tracks when a StepItem is moving /// public bool Moving { get { return _Moving; } set { _Moving = value; } } /// /// The RNO (Contingency) Level /// public int RNOLevel { get { return _RNOLevel; } set { _RNOLevel = value; } } /// /// Sequential Level - Only counts levels of Sequential substeps /// public int SeqLevel { get { return _SeqLevel; } set { _SeqLevel = value; } } // TODO: This should be changed to get the Circle format from the data /// /// Show a circle or not /// public bool Circle { get { return _Circle; } set { _Circle = value; } } // TODO: This should be changed to get the Checkoff status from the data /// /// Has a check-off or not /// public bool CheckOff { get { return _CheckOff; } set { _CheckOff = value; } } // TODO: This should be changed to get the ChangeBar status from the data /// /// Has a changebar or not /// public bool ChangeBar { get { return _ChangeBar; } set { _ChangeBar = value; } } #endregion // Properties #region Constructors public StepItem(ItemInfo itemInfo, StepPanel myStepPanel, StepItem myParentStepItem, ChildRelation myChildRelation, bool expand) { //// TIMING: DisplayItem.TimeIt("CSLARTB Top"); InitializeComponent();// TODO: Performance 25% _MyStepRTB.MyStepItem = this; //// TIMING: DisplayItem.TimeIt("CSLARTB InitComp"); BackColor = myStepPanel.PanelColor; _MyStepRTB.BackColor = myStepPanel.InactiveColor; // TODO: Adjust top based upon format // TODO: Remove Label and just output ident on the paint event lblTab.Top = 3; _MyStepRTB.Top = 3; this.Paint += new PaintEventHandler(StepItem_Paint); this.BackColorChanged += new EventHandler(StepItem_BackColorChanged); if (itemInfo != null) { _Type = (int)itemInfo.MyContent.Type; switch (_Type / 10000) { case 0: // Procedure _MyStepRTB.Font = lblTab.Font = myStepPanel.ProcFont; break; case 1: // Section _MyStepRTB.Font = lblTab.Font = myStepPanel.SectFont; break; case 2: // Steps _MyStepRTB.Font = lblTab.Font = myStepPanel.StepFont; _MyStepData = itemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[_Type % 10000]; break; } //this.Move += new EventHandler(DisplayItem_Move); } else { if (myStepPanel.MyFont != null) _MyStepRTB.Font = lblTab.Font = myStepPanel.MyFont; } if (expand) _MyvlnExpander.ShowExpanded(); _MyStepPanel = myStepPanel; if (itemInfo != null) myStepPanel._LookupStepItems.Add(itemInfo.ItemID, this); _MyChildRelation = myChildRelation; if (myParentStepItem != null) RNOLevel = myParentStepItem.RNOLevel; if (itemInfo != null) { //// TIMING: DisplayItem.TimeIt("CSLARTB before _Layout"); _MyStepSectionLayoutData = itemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionLayoutData; //// TIMING: DisplayItem.TimeIt("CSLARTB _Layout"); if (myParentStepItem != null) SeqLevel = myParentStepItem.SeqLevel + ((myChildRelation == ChildRelation.After || myChildRelation == ChildRelation.Before) && TemporaryFormat.IsSequential(itemInfo) ? 1 : 0); //// TIMING: DisplayItem.TimeIt("CSLARTB seqLevel"); MyItemInfo = itemInfo; } //// TIMING: DisplayItem.TimeIt("CSLARTB MyItem"); myStepPanel.Controls.Add(this); switch (myChildRelation) { case ChildRelation.After: AddItem(myParentStepItem, ref myParentStepItem._MyAfterStepItems); break; case ChildRelation.Before: AddItem(myParentStepItem, ref myParentStepItem._MyBeforeStepItems); break; case ChildRelation.RNO: RNOLevel = myParentStepItem.RNOLevel + 1; AddItem(myParentStepItem, ref myParentStepItem._MyRNOStepItems); break; case ChildRelation.None: break; } if (itemInfo != null) { if (myChildRelation == ChildRelation.None) { if (_Type == 0 && _MyStepSectionLayoutData != null) { Width = _MyStepPanel.ToDisplay(_MyStepSectionLayoutData.WidT); } } } //// TIMING: DisplayItem.TimeIt("CSLARTB Parent"); SetText(); //// TIMING: DisplayItem.TimeIt("CSLARTB SetText"); if (itemInfo != null) { Name = string.Format("Item-{0}", itemInfo.ItemID); // Don't allow substeps to expand switch (_Type / 10000) { case 1: // Section can expand CanExpand = true; // If a word document set the expander to attachment _MyvlnExpander.Attachment = (itemInfo.MyContent.ContentPartCount == 0); break; case 2: // High level steps with children can expand CanExpand = itemInfo.IsHigh && itemInfo.HasChildren; // TemporaryFormat.IsHigh(item); ; break; default://Procedures cannot expand, because they automatically expand CanExpand = false; break; } if (expand && (itemInfo.MyContent.ContentPartCount != 0)) // If it should expand and it can expand Expand(true); else if (myParentStepItem == null)// If it is the top node if (_Type >= 20000) // and it is a step - fully expand Expand(true); else // otherwise only expand one level Expand(false); } //// TIMING: DisplayItem.TimeIt("CSLARTB before Controls Add"); //myStepPanel.Controls.Add(this); _Loading = false; //// TIMING: DisplayItem.TimeIt("CSLARTB Controls Add"); } #endregion #region AddItem /// /// Adds an item to a list /// /// Parent Container /// StepItem List public void AddItem(StepItem parentStepItem, ref List siblingStepItems) { if (siblingStepItems == null) { siblingStepItems = new List(); siblingStepItems.Add(this); MyParentStepItem = parentStepItem; } else { StepItem lastChild = LastChild(siblingStepItems); siblingStepItems.Add(this); MyPreviousStepItem = lastChild; } TabFormat = TemporaryFormat.TabFormat(this); } /// /// Add the next item to a list /// /// /// /// //public StepItem AddNext(ItemInfo myItemInfo, bool expand) //{ // StepItem tmp = new StepItem(myItemInfo, _MyStepPanel, MyParentStepItem, ChildRelation.None, expand); // MyNextStepItem = tmp; // return tmp; //} #endregion #region Add Children /// /// Add a child before (Notes, Cautions, etc.) /// /// /// public void AddChildBefore(ItemInfo myItemInfo, bool expand) { StepItem child = new StepItem(myItemInfo, _MyStepPanel, this, ChildRelation.Before, expand); } /// /// Add a list of children before /// /// /// public void AddChildBefore(ItemInfoList myItemInfoList, bool expand) { if (myItemInfoList != null) foreach (ItemInfo item in myItemInfoList) AddChildBefore(item, expand); } /// /// Add an RNO (Contingency) child /// /// /// public void AddChildRNO(ItemInfo myItemInfo, bool expand) { StepItem child = new StepItem(myItemInfo, _MyStepPanel, this, ChildRelation.RNO, expand); } /// /// Add a list of RNO (Contingency) children /// /// /// public void AddChildRNO(ItemInfoList myItemInfoList, bool expand) { if (myItemInfoList != null) foreach (ItemInfo item in myItemInfoList) AddChildRNO(item, expand); } /// /// Add a child after /// /// /// public void AddChildAfter(ItemInfo MyItemInfo, bool expand) { StepItem child = new StepItem(MyItemInfo, _MyStepPanel, this, ChildRelation.After, expand); child.RNOLevel = this.RNOLevel; } /// /// Add a list of children after /// /// /// public void AddChildAfter(ItemInfoList myItemInfoList, bool expand) { if (myItemInfoList != null) foreach (ItemInfo item in myItemInfoList) AddChildAfter(item, expand); } #endregion #region Event Handlers /// /// If the background changes, change the background of the RichTextBox /// /// /// void StepItem_BackColorChanged(object sender, EventArgs e) { _MyStepRTB.BackColor = BackColor; } /// /// When the RichTextBox height changes, change the height of the control to match /// /// /// private void _StepRTB_HeightChanged(object sender, EventArgs args) { this.Height = _MyStepRTB.Height + 10; } /// /// Handle the colape event /// /// /// private void vlnExp_BeforeColapse(object sender, vlnExpanderEventArgs args) { Cursor tmp = Cursor.Current; Cursor.Current = Cursors.WaitCursor; int top = TopMostStepItem.Top;// This does'nt work - this is since the last time it was expanded. _Colapsing = true; // Hide Children HideChildren(); // Adjust Positions _ExpandPrefix = Top - top; _ExpandSuffix = BottomMostStepItem.Bottom - Bottom; if (Top != top) { _MyStepPanel.ItemMoving++; Top = top; _MyStepPanel.ItemMoving--; } else AdjustLocation(); BottomMostStepItem.AdjustLocation(); _Colapsing = false; Cursor.Current = tmp; } /// /// Handle the expand event /// /// /// private void vlnExp_BeforeExpand(object sender, vlnExpanderEventArgs args) { Cursor tmp = Cursor.Current; Cursor.Current = Cursors.WaitCursor; if (!_Loading && MyExpandingStatus == ExpandingStatus.No) Expand(_Type >= 20000); Cursor.Current = tmp; } /// /// Adjust the locations when the StepItem is resized /// /// /// private void StepItem_Resize(object sender, EventArgs e) { if (_MyItemInfo == null) return; AdjustLocation(); } /// /// Handles movement of the StepItems /// /// /// private void StepItem_Move(object sender, EventArgs e) { if (_MyStepPanel.ItemMoving == 0) return; // If 0 - Indicates scrolling which requires no action. if (_MyItemInfo == null) return; if (MyExpandingStatus == ExpandingStatus.Expanding) return; _Moving = true; StepItem tmp = (StepItem)sender; if (tmp._MyPreviousStepItem == null && tmp._MyParentStepItem == null) { return; } AdjustLocation(); if (_MyRNOStepItems != null) { if (_MyRNOStepItems[0].TopMostStepItem.Top != Top) { //if(_MyLog.IsDebugEnabled)_MyLog.DebugFormat("\r\n'Adjust RNO',{0},'Move',{1}", MyID, _RNO[0].MyID); if (RNOLevel >= _MyStepPanel.MaxRNO) { StepItem tmpBottom = this; if (_MyAfterStepItems != null) tmpBottom = _MyAfterStepItems[_MyAfterStepItems.Count - 1].BottomMostStepItem; _MyStepPanel.ItemMoving++; _MyRNOStepItems[0].TopMostStepItem.Top = tmpBottom.Bottom; _MyStepPanel.ItemMoving--; } else { _MyStepPanel.ItemMoving++; _MyRNOStepItems[0].TopMostStepItem.Top = Top; _MyStepPanel.ItemMoving--; } } } _Moving = false; BottomMostStepItem.AdjustLocation(); } /// /// Handle the LinkGoTO event /// /// /// private void _StepRTB_LinkGoTo(object sender, StepPanelLinkEventArgs args) { _MyLog.DebugFormat("_DisplayRTB_LinkGoTo " + args.LinkInfoText); _MyStepPanel.OnLinkClicked(sender, args); } /// /// Raises an ItemClick event when the user clicks on the Tab /// /// /// private void lblTab_MouseDown(object sender, MouseEventArgs e) { _MyStepPanel.OnItemClick(this, new StepPanelEventArgs(this, e)); } /// /// When a RichTextBox is entered, the selected StepRTB is set /// /// /// private void _StepRTB_Enter(object sender, EventArgs e) { if (_MyStepPanel.DisplayItemChanging) return; //vlnStackTrace.ShowStack("_StepRTB_Enter {0}",this.MyID); _MyStepPanel.SelectedStepRTB = _MyStepRTB; } /// /// Raise a OnLinkModifyTran event, when the user chooses to Modify a transition /// /// /// private void _StepRTB_LinkModifyTran(object sender, StepPanelLinkEventArgs args) { _MyStepPanel.OnLinkModifyTran(sender, args); } /// /// Raise a OnLinkModifyRO event, when the user chooses to modify an RO /// /// /// private void _StepRTB_LinkModifyRO(object sender, StepPanelLinkEventArgs args) { _MyStepPanel.OnLinkModifyRO(sender, args); } /// /// Pass the AttachmentClick event to the StepPanel control. /// /// /// private void vlnExp_AttachmentClick(object sender, vlnExpanderEventArgs args) { _MyStepPanel.OnAttachmentClicked(sender, new StepPanelAttachmentEventArgs(this)); } #endregion // Event Handlers #region Private Methods /// /// Finds the last child in a list /// /// /// private static StepItem LastChild(List childStepItems) { return childStepItems[childStepItems.Count - 1]; } /// /// Calculate the width of the table /// /// /// /// private float TableWidth(Font myFont, string txt) { string[] lines = txt.Split("\n".ToCharArray()); float max = 0; Graphics g = this.CreateGraphics(); PointF pnt = new PointF(0, 0); foreach (string line in lines) { string line2 = Regex.Replace(line, @"\\.*? ", ""); // Remove RTF Commands SizeF siz = g.MeasureString(line2, myFont, pnt, StringFormat.GenericTypographic); if (siz.Width + _MyStepPanel.MyStepPanelSettings.TableWidthAdjust > max) max = siz.Width + _MyStepPanel.MyStepPanelSettings.TableWidthAdjust; } return max; } /// /// Calculates the table location /// /// /// /// /// private Point TableLocation(StepItem myParentStepItem, StepSectionLayoutData myStepSectionLayoutData, int width) { int x = myParentStepItem.TextLeft; int y = myParentStepItem.Bottom; if (x + width > myParentStepItem.Right) x = myParentStepItem.Right - width; int colT = _MyStepPanel.ToDisplay(myStepSectionLayoutData.ColT); if (x < colT) x = colT; return new Point(x, y); } /// /// Sets the Item and as a result the text for the RichTextBox /// private void SetText() { if (_MyItemInfo != null) this._MyStepRTB.MyItemInfo = _MyItemInfo; } /// /// If the selected StepItem is within the window leave it as it is. /// If not, scroll so that the selected window is centered. /// private void ScrollToCenter() { //vlnStackTrace.ShowStack("CenterScroll {0} Current {1} Top {2} Bottom {3} Limit {4}", _MyItem.ItemID, _Panel.VerticalScroll.Value, Top, Bottom, _Panel.Height);// Show StackTrace //Console.WriteLine("CenterScroll {0} Current {1} Top {2} Bottom {3} Limit {4}", _MyItem.ItemID, _Panel.VerticalScroll.Value, Top, Bottom, _Panel.Height); if (Top >= 0 && Bottom <= _MyStepPanel.Height) return;// Don't move if within screen. int scrollValue = _MyStepPanel.VerticalScroll.Value + (Top - (_MyStepPanel.Height / 2)); // calculate scroll center for the item //Console.WriteLine("CenterScroll {0} Current {1} New {2} Min {3} Max {4}", _MyItem.ItemID, _Panel.VerticalScroll.Value, scrollValue, _Panel.VerticalScroll.Minimum, _Panel.VerticalScroll.Maximum); if (scrollValue >= _MyStepPanel.VerticalScroll.Minimum && scrollValue <= _MyStepPanel.VerticalScroll.Maximum) // If it is within range _MyStepPanel.VerticalScroll.Value = scrollValue; // Center the item } // TODO: the format of the circles, Checkoffs and Changebars should come from the format file /// /// This adds drawing items to the StepItem as needed including /// Circle around the Tab Number /// Check-Offs /// Change Bars /// /// /// private void StepItem_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.DrawString(lblTab.Text, _MyStepRTB.Font, Brushes.Black, new RectangleF(new PointF(_MyStepPanel.MyStepPanelSettings.NumberLocationX, _MyStepPanel.MyStepPanelSettings.NumberLocationY), _MyStepPanel.MyStepPanelSettings.NumberSize), StringFormat.GenericDefault); if (Circle) { Pen penC = new Pen(_MyStepPanel.MyStepPanelSettings.CircleColor, _MyStepPanel.MyStepPanelSettings.CircleWeight); g.DrawArc(penC, lblTab.Left + 1, 0, _MyStepPanel.MyStepPanelSettings.CircleDiameter, _MyStepPanel.MyStepPanelSettings.CircleDiameter, 0F, 360F); } if (CheckOff) { Pen penCO = new Pen(_MyStepPanel.MyStepPanelSettings.CheckOffColor, _MyStepPanel.MyStepPanelSettings.CheckOffWeight); g.DrawRectangle(penCO, _MyStepPanel.MyStepPanelSettings.CheckOffX, _MyStepPanel.MyStepPanelSettings.CheckOffY, _MyStepPanel.MyStepPanelSettings.CheckOffSize, _MyStepPanel.MyStepPanelSettings.CheckOffSize); } if (ChangeBar) { Pen penCB = new Pen(_MyStepPanel.MyStepPanelSettings.ChangeBarColor, _MyStepPanel.MyStepPanelSettings.ChangeBarWeight); g.DrawLine(penCB, 0, 0, 0, Height); } } /// /// Hide a Items Children - Part of colapsing /// protected void HideChildren() { HideChildren(_MyBeforeStepItems); HideChildren(_MyRNOStepItems); HideChildren(_MyAfterStepItems); } /// /// Hide a list of children - Part of colapsing /// /// private void HideChildren(List childStepItems) { if (childStepItems != null) { foreach (StepItem child in childStepItems) { if (child.Expanded) child.HideChildren(); child.Visible = false; } } } /// /// Unhide an items Children - Part of expanding /// /// protected void UnhideChildren(bool expand) { UnhideChildren(_MyBeforeStepItems, expand); UnhideChildren(_MyRNOStepItems, expand); UnhideChildren(_MyAfterStepItems, expand); if (!_MyvlnExpander.Expanded) _MyvlnExpander.ShowExpanded(); } /// /// Unhide a list of children - part of expanding /// /// /// private void UnhideChildren(List childStepItems, bool expand) { if (childStepItems != null) { foreach (StepItem child in childStepItems) { if (child.Expanded) child.UnhideChildren(expand); else if (expand) child.Expand(expand); child.Visible = true; } } } /// /// Move children as necessary /// protected void AdjustChildren() { AdjustChildren(_MyBeforeStepItems); AdjustChildren(_MyRNOStepItems); AdjustChildren(_MyAfterStepItems); } /// /// Move a list of children /// /// private void AdjustChildren(List childStepItems) { if (childStepItems != null) { foreach (StepItem child in childStepItems) { child.AdjustLocation(); if (child.Expanded) child.AdjustChildren(); } } } /// /// Expand a list of children /// /// private void ExpandChildren(List childStepItems) { if (childStepItems != null) { foreach (StepItem child in childStepItems) { if (child.CanExpand) { child.Expand(true); } child.Visible = true; } } } /// /// Expand children /// private void ExpandChildren() { // Walk though Children performing Expand ExpandChildren(_MyBeforeStepItems); ExpandChildren(_MyRNOStepItems); ExpandChildren(_MyAfterStepItems); } private string MyPath { get { if(MyItemInfo.MyContent.Type >= 20000) return MyItemInfo.Path.Substring(MyItemInfo.ActiveSection.Path.Length); return ""; } } /// /// Adjust the Location of all items below the current item. /// private void AdjustLocation() { StepItem tmp = NextDownStepItem; if (tmp == null) return; if (tmp != null && !tmp.Moving && tmp.Top != Bottom) { _MyStepPanel.ItemMoving++; tmp.Top = Bottom; _MyStepPanel.ItemMoving--; } } /// /// Automatically expands Steps if not currently expanded /// internal void AutoExpand() { if (CanExpand && Expanded == false)// TODO: May need to do some additional checking for subsections { //vlnStackTrace.ShowStack(">AutoExpand ID {0} - Can {1} Expanded {2}", _MyItem.ItemID, CanExpand, Expanded); Expand(_Type >= 20000); //Console.WriteLine(" /// Sets the focus to this StepItem and positions the cursor to the begining of the string /// public void ItemSelect() { _MyStepRTB.Focus(); _MyStepRTB.Select(0, 0); // if (CanExpand) AutoExpand(); // Expand the item if you can ScrollToCenter(); } /// /// Sets the focus to this StepItem /// public void ItemShow() { _MyStepRTB.Focus(); ScrollToCenter(); } /// /// Expand an item and it's children /// If the children have been loaded then just expand them /// If not, load the children and expand their children etc. /// /// normally equal to _Type > = 20000 (Step) public void Expand(bool expand) { //// TIMING: DisplayItem.TimeIt("Expand Start"); if (_ChildrenLoaded) { // Unhide Children MyExpandingStatus = ExpandingStatus.Showing; UnhideChildren(expand); if (_ExpandPrefix != 0) { _MyStepPanel.ItemMoving++; TopMostStepItem.Top = Top; _MyStepPanel.ItemMoving--; } else TopMostStepItem.AdjustLocation(); AdjustChildren(); //if(_Before != null ) // Top = _Before[_Before.Count - 1].BottomMost.Bottom; } else { MyExpandingStatus = ExpandingStatus.Expanding; _ChildrenLoaded = true; //_Panel.SuspendLayout(); AddChildBefore(MyItemInfo.Cautions, expand); AddChildBefore(MyItemInfo.Notes, expand); AddChildAfter(MyItemInfo.Procedures, expand); AddChildAfter(MyItemInfo.Sections, expand); AddChildAfter(MyItemInfo.Steps, expand); AddChildAfter(MyItemInfo.Tables, expand); AddChildRNO(MyItemInfo.RNOs, expand); if (!_MyvlnExpander.Expanded) _MyvlnExpander.ShowExpanded(); } MyExpandingStatus = ExpandingStatus.Done; BottomMostStepItem.AdjustLocation(); MyExpandingStatus = ExpandingStatus.No; //// TIMING: DisplayItem.TimeIt("Expand End"); } /// /// This finds the next StepItem down. /// public StepItem NextDownStepItem { get { StepItem tmp = this; if (tmp.MyNextStepItem == null && FirstSiblingStepItem._MyChildRelation == ChildRelation.Before && tmp._MyAfterStepItems == null) return UpOneStepItem; if (Expanded && tmp._MyAfterStepItems != null)// check to see if there is a _After return tmp._MyAfterStepItems[0].TopMostStepItem;// if there is go that way while (tmp != null && tmp.MyNextStepItem == null) // if no Next walk up the parent path { tmp = tmp.UpOneStepItem; if (tmp == null) // No Parent return null; if (tmp.MyExpandingStatus == ExpandingStatus.Expanding || tmp.Moving) // Parent Expanding or Moving - Wait return null; if (tmp.MyNextStepItem == null && tmp.FirstSiblingStepItem._MyChildRelation == ChildRelation.Before) return tmp.UpOneStepItem; StepItem btm = tmp.BottomMostStepItem; if (this != btm) { if (tmp.MyNextStepItem != null && tmp.MyNextStepItem.TopMostStepItem.Top != btm.Bottom) { _MyStepPanel.ItemMoving++; tmp.MyNextStepItem.TopMostStepItem.Top = btm.Bottom; _MyStepPanel.ItemMoving--; } return null; // Not the bottom - don't adjust anything else } } if (tmp != null) return tmp.MyNextStepItem.TopMostStepItem;// if no _After - check to see if there is a Next return null; } } #endregion } }