using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Forms;
using VEPROMS.CSLA.Library;
using System.Drawing;
using Volian.Base.Library;
using JR.Utils.GUI.Forms;
using System.Linq;
namespace Volian.Controls.Library
{
public partial class StepPanel : Panel
{
#region Fields
///
/// Procedure Item Info - Top ItemInfo
///
private ItemInfo _MyProcedureItemInfo;
public E_ViewMode VwMode { get; set; } = E_ViewMode.Edit;
public EditItem TopMostEditItem { get; set; } = null;
public ItemInfo ExpandingHLS { get; set; } = null;
// TODO: This is not correct. There should be a dictionary of Section Layouts
///
/// Lookup Table to convert ItemInfo.ItemID to EditItem
///
internal Dictionary _LookupEditItems;
public EditItem FindItem(ItemInfo itemInfo)
{
if (itemInfo == null) return null;
if (!_LookupEditItems.ContainsKey(itemInfo.ItemID)) return null;
return _LookupEditItems[itemInfo.ItemID];
}
private int _ApplDisplayMode = -1;
public int ApplDisplayMode
{
get { return _ApplDisplayMode; }
set
{
if(_ApplDisplayMode == value) return;
_ApplDisplayMode = value;
foreach (Control c in Controls)
{
if (c is EditItem ei)
{
ei.Enabled = ei.MyItemInfo.IsApplicable(value);
}
}
}
}
///
/// Currently selected ItemInfo
///
internal ItemInfo _SelectedItemInfo;
private StepPanelSettings _MyStepPanelSettings;
private Font _MyFont = null;
private Color _ActiveColor = Color.SkyBlue;
private Color _PanelColor = Color.LightGray;
// Whether panel is in view or edit mode. Toggled from steprtb
// or set based on approval/multi-user (these two will be done
// later.
internal string _LastAdjust="";
private Graphics _MyGraphics = null;
private int _DPI = 0;
#endregion
#region Item Events
///
/// Occurs when the user clicks tab of a EditItem
///
public event StepPanelEvent ItemClick;
///
/// Checks to see if the 'ItemClick' event is handled and launches it
///
///
///
internal void OnItemClick(object sender, StepPanelEventArgs args)
{
ItemClick?.Invoke(sender, args);
}
public bool ItemSelectionChangeShown = false; // This keeps OnItemSelectedChanged from being called twice when an item is selected.
///
/// Occurs when the selected EditItem changes
///
public event ItemSelectedChangedEvent ItemSelectedChanged;
///
/// Checks to see if the 'ItemSelectedChanged' event is handled and launches it
///
///
///
internal void OnItemSelectedChanged(object sender, ItemSelectedChangedEventArgs args)
{
ItemSelectionChangeShown = true;//Remember that you have run already
//vlnStackTrace.ShowStack(string.Format("OnItemSelectedChanged {0}",args.MyItemInfo.ItemID));
ItemSelectedChanged?.Invoke(sender, args);
}
///
/// Occurs when the user clicks on the Attachment Expander
///
public event StepPanelAttachmentEvent AttachmentClicked;
///
/// Checks to see if the 'AttachmentClicked' event is handled and launches it
///
///
///
internal void OnAttachmentClicked(object sender, StepPanelAttachmentEventArgs args)
{
if (AttachmentClicked != null) AttachmentClicked(sender, args);
else FlexibleMessageBox.Show(args.MyEditItem.MyItemInfo.MyContent.MyEntry.MyDocument.DocumentTitle, "Unhandled Attachment Click", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public event StepPanelTabDisplayEvent TabDisplay;
internal void OnTabDisplay(object sender, StepPanelTabDisplayEventArgs args) => TabDisplay(sender, args);
// close section, if deleting word doc section
public event StepPanelWordSectionCloseEvent WordSectionClose;
internal void OnWordSectionClose(object sender, WordSectionEventArgs args) => WordSectionClose(sender, args);
// if section deleted, have event to flag in other UI panels
public event StepPanelWordSectionDeletedEvent WordSectionDeleted;
internal void OnWordSectionDeleted(object sender, WordSectionEventArgs args) => WordSectionDeleted(sender, args);
// if item pasted, have event to flag in other UI panels
public event StepPanelItemPastedEvent ItemPasted;
internal void OnItemPasted(object sender, vlnTreeItemInfoPasteEventArgs args) => ItemPasted(sender, args);
#endregion
#region Link Events
///
/// Occurs when the user moves onto or off of a Link
///
public event StepPanelLinkEvent LinkActiveChanged;
///
/// Checks to see if the 'LinkActiveChanged' event is handled and launches it
///
///
///
internal void OnLinkActiveChanged(object sender, StepPanelLinkEventArgs args)
{
if (LinkActiveChanged != null) LinkActiveChanged(sender, args);
else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Active Changed", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
///
/// Occurs when the user chooses to Insert a Transition
///
public event StepPanelLinkEvent LinkInsertTran;
///
/// Checks to see if the 'LinkInsertTran' event is handled and launches it
///
///
///
internal void OnLinkInsertTran(object sender, StepPanelLinkEventArgs args)
{
if (LinkInsertTran != null) LinkInsertTran(sender, args);
else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Insert Tran", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
///
/// Occurs when the user chooses to Insert an RO
///
public event StepPanelLinkEvent LinkInsertRO;
///
/// Checks to see if the 'LinkInsertRO' event is handled and launches it
///
///
///
internal void OnLinkInsertRO(object sender, StepPanelLinkEventArgs args)
{
if (LinkInsertRO != null) LinkInsertRO(sender, args);
else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Insert RO", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
///
/// Occurs when the user clicks a Link
///
public event StepPanelLinkEvent LinkClicked;
///
/// Checks to see if the 'LinkClicked' event is handled and launches it
///
///
///
internal void OnLinkClicked(object sender, StepPanelLinkEventArgs args)
{
if (LinkClicked != null) LinkClicked(sender, args);
else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Click", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
///
/// Occurs when the user chooses to modify a Transition
///
public event StepPanelLinkEvent LinkModifyTran;
///
/// Checks to see if the 'LinkModifyTran' event is handled and launches it
///
///
///
internal void OnLinkModifyTran(object sender, StepPanelLinkEventArgs args)
{
if (LinkModifyTran != null) LinkModifyTran(sender, args);
else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Modify Tran", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
///
/// Occurs when the user chooses to modify an RO
///
public event StepPanelLinkEvent LinkModifyRO;
///
/// Checks to see if the 'LinkModifyRO' event is handled and launches it
///
///
///
internal void OnLinkModifyRO(object sender, StepPanelLinkEventArgs args)
{
if (LinkModifyRO != null) LinkModifyRO(sender, args);
else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Modify RO", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
#region Constructors
public StepPanel()
{
InitializeComponent();
SetupStepPanel();
}
private void SetupStepPanel()
{
this.BackColorChanged += new EventHandler(StepPanel_BackColorChanged);
if (VlnSettings.DebugMode)
{
InactiveColor = Color.Linen;
TabColor = Color.Beige;
_PanelColor = Color.LightGray;
this.DoubleClick += new EventHandler(StepPanel_DoubleClick); // Toggles Vertical lines on and off
}
else
{
InactiveColor = Color.White;
TabColor = Color.White;
_PanelColor = Color.White;
this.BackColor = Color.White;
}
this.AutoScroll = true;
}
public StepPanel(IContainer container)
{
container.Add(this);
InitializeComponent();
SetupStepPanel();
}
void StepPanel_BackColorChanged(object sender, EventArgs e)
{
// Walk through controls & set colors
InactiveColor = PanelColor = BackColor;
foreach (Control ctrl in Controls)
{
if (ctrl is EditItem ei)
{
ei.BackColor = BackColor;
}
}
}
#endregion
#region Private Methods
///
/// Expands an Item and It's Parents as need to display an item
///
/// Item to Expand
private void ExpandAsNeeded(ItemInfo myItemInfo)
{
int id = myItemInfo.ItemID;
if (!_LookupEditItems.ContainsKey(id)) // If the item is not currently displayed
ExpandAsNeeded((ItemInfo)myItemInfo.ActiveParent); // Expand it's parent
if (_LookupEditItems.ContainsKey(id)) // Expanding Parent should have added it to _LookupEditItems
{
EditItem itm = _LookupEditItems[id];
if (!itm.Visible && myItemInfo.ActiveParent is ItemInfo ii)
ExpandAsNeeded(ii);
itm.AutoExpand(); // Expand it if it should expand
}
}
#endregion
#region Properties
public StepTabPanel MyStepTabPanel
{ get { return Parent as StepTabPanel; } }
///
/// Procedure Item Info - Top ItemInfo
/// Get and Set - Set stes-up all of the
///
public ItemInfo MyProcedureItemInfo
{
get { return _MyProcedureItemInfo; }
set
{
_MyProcedureItemInfo = value;
Controls.Clear();
_LookupEditItems = new Dictionary();
new RTBItem(_MyProcedureItemInfo, this, null, ChildRelation.None, false);
}
}
public bool AutoExpand
{
get
{
// This is temporary to get the code working for this particular procedure
if (MyProcedureItemInfo.DisplayNumber == "PMS-810") return false;
if (MyProcedureItemInfo.DisplayNumber == "PMS-809") return false;
return true;
}
}
public void Reset()
{
if (SelectedItemInfo.ActiveParent is ItemInfo parent) ItemInfo.ResetParts(parent.ItemID); // Force data to reload
else ItemInfo.ResetParts(SelectedItemInfo.ItemID);
// The following line actually reloads the procedure item
MyProcedureItemInfo = MyProcedureItemInfo; // see get/set above. - Load Procedure and Sections
// The following line expands the items needed to display SelectedItemInfo
ExpandAsNeeded(SelectedItemInfo);
}
public void Reset(ItemInfo myItemInfo)
{
if (myItemInfo.ActiveParent is ItemInfo parent) ItemInfo.ResetParts(parent.ItemID); // Force data to reload
else ItemInfo.ResetParts(myItemInfo.ItemID);
// The following line actually reloads the procedure item
MyProcedureItemInfo = MyProcedureItemInfo; // see get/set above. - Load Procedure and Sections
// The following line expands the items needed to display SelectedItemInfo
ExpandAsNeeded(myItemInfo);
}
//C2019-036 View Only mode work with Checked Out Procedures
public void ResetAll()
{
List itemIDs = Controls.OfType().Where(t => t?.MyItemInfo?.ActiveParent != null && t.MyItemInfo.ActiveParent.GetType() == typeof(ItemInfo)).Select(x => (x.MyItemInfo.ActiveParent as ItemInfo).ItemID).Distinct().ToList();
foreach (int itemID in itemIDs)
{
ItemInfo.ResetParts(itemID);
}
// The following line actually reloads the procedure item
MyProcedureItemInfo = ItemInfo.Get(MyProcedureItemInfo.ItemID, true);
MyProcedureItemInfo.RefreshConfig();
ContentInfo.Refresh(Content.Get(MyProcedureItemInfo.MyContent.ContentID, true));
// The following line expands the items needed to display SelectedItemInfo
ExpandAsNeeded(SelectedItemInfo);
}
///
/// Gets or Sets the SelectedItemInfo
/// Activates and Expands as necessary
///
public ItemInfo SelectedItemInfo
{
get { return _SelectedItemInfo; }
set
{
_SelectedItemInfo = value;
ItemSelectionChangeShown = false; //OnItemSelectedChanged has not run yet.
SelectedEditItem.ItemSelect();
if (!ItemSelectionChangeShown) OnItemSelectedChanged(this, new ItemSelectedChangedEventArgs(SelectedEditItem));
}
}
public EditItem GetEditItem(ItemInfo itemInfo)
{
ExpandAsNeeded(itemInfo);
if (_SelectedItemInfo == null) _SelectedItemInfo = itemInfo;
if (itemInfo.Moving)
{
Reset(itemInfo);
itemInfo.Moving = false;
}
else if ( !_LookupEditItems.ContainsKey(itemInfo.ItemID)) Reset(itemInfo);
if (!_LookupEditItems.ContainsKey(itemInfo.ItemID)) return null;
return _LookupEditItems[itemInfo.ItemID];
}
public bool DisplayItemChanging { get; set; } = false;
///
/// Returns the SelectedEditItem
///
private EditItem _SelectedEditItem;
public EditItem SelectedEditItem
{
get
{
return _SelectedEditItem;
}
set
{
EditItem newFocus = null; // B2018-152 when empty step is deleted, will contain the new step element focus
bool deletingParent = false; // B2018-152 used to tell us user clicked on subtep of step element who's text was removed (special case)
EditItem lastEI = _SelectedEditItem;
value?.SetActive(); // Set the active color
if (lastEI == value) return; // Same - No Change
// B2018-002 - Invalid Transitions - If the current step contains an invalid transition convert it to text
if(value != null) ItemInfo.ConvertInvalidTransitionsToText(value.MyItemInfo);
if (lastEI != null && lastEI.BeingDisposed == false)
{
// B2019-139 if a procedure with out a title, or a section without a title, don't try to delete when you are moving off of the title while in the step editor
bool shouldDelete = !lastEI.BeingRemoved && lastEI.Empty && (lastEI.MyItemInfo.MyContent.ContentEntryCount <= 0) && !_SelectedItemInfo.IsProcedure && !_SelectedItemInfo.IsSection;
if (shouldDelete)
{
if (lastEI.HasChildren)
{
// B2018-152 Added a messagebox for when user clicks on a substep of a step element who's text was just deleted
// Also made the message for when we ask about removing a step and its substeps more descriptive
string msg1 = "Do you want to delete it and its substeps?";
string msg2 = "Select YES to remove the empty step";
string msg3 = "Select NO to keep the empty step which can be restored via the History tab on the Step Properties panel.";
if (value != null && value.MyItemInfo.HasAncestor(lastEI.MyItemInfo))
{
msg1 = $"This step does not have text but you had selected one of its substeps. {msg1}";
msg2 += " including the substep you had selected. You will be placed at the next location.";
deletingParent = true; // B2018-152 this will tell us that the user selected a substep of a parent being deleted
}
else
{
msg1 = $"This step does not have text but has substeps. {msg1}";
msg2 += " and its substeps.";
}
DialogResult result = FlexibleMessageBox.Show($"{msg1}\n\n{msg2}\n\n{msg3}", "Verify Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.No) shouldDelete = false;
}
}
if (shouldDelete)
{
// if this item has enhanced edititems, remove them. Note that this code supports
// deleting text in an rtbitem that may be a step or section level.
EnhancedDocuments eds = null;
if (lastEI.MyItemInfo.MyConfig is StepConfig sc) eds = sc.MyEnhancedDocuments;
else
{
// if a section, just the title or all contents may be linked. If just title,
// don't delete enhanced, but clear links back from enhanced.
if (lastEI.MyItemInfo.IsSection)
{
if (lastEI.MyItemInfo.MyConfig is SectionConfig sec)
{
if (sec.Section_LnkEnh == "Y") eds = sec.MyEnhancedDocuments;
else lastEI.MyItemInfo.ClearEnhancedSectionLink();
}
}
}
List enhIds = new List();
if (eds != null)
{
foreach (EnhancedDocument ed in eds)
{
if (ed.Type != 0) enhIds.Add(ed.ItemID);
}
}
float oldTop = lastEI.Top;
newFocus = lastEI.DeleteItem(); //B2018-152 made "newFocus" available outside this IF statement
if (newFocus == null)
{
lastEI.RefreshContent();
return;
}
float newTop = newFocus.Top;
lastEI.Dispose();
newFocus.SetAllTabs();
// If the step being deleted appears above the step to recieve focus, find another step
// to use so that the steps are positioned properly (vertically)
if (oldTop < newTop)
{
if (newFocus.MyParentEditItem != null)
{
if (newFocus.Top > newFocus.MyParentEditItem.Top)
newFocus.MyParentEditItem.AdjustLocation();
else if (newFocus.MyParentEditItem.MyPreviousEditItem != null &&
newFocus.Top > newFocus.MyParentEditItem.MyPreviousEditItem.Top)
newFocus.MyParentEditItem.MyPreviousEditItem.AdjustLocation();
else if (newFocus.MyParentEditItem.MyParentEditItem != null &&
newFocus.Top > newFocus.MyParentEditItem.MyParentEditItem.Top)
newFocus.MyParentEditItem.MyParentEditItem.AdjustLocation();
else
newFocus.AdjustLocation();
}
else if (newFocus.MyPreviousEditItem != null)
newFocus.MyPreviousEditItem.AdjustLocation();
else
newFocus.AdjustLocation();
}
else
newFocus.AdjustLocation();
foreach (int enhId in enhIds)
{
ItemInfo ii = ItemInfo.Get(enhId);
bool success = MyStepTabPanel.MyDisplayTabControl.DeleteRTBItem(ii);
if (!success) // item was not displayed in editor, just delete from database (add tree if necessarY)
Item.DeleteItemAndChildren(ii);
}
}
else
{
lastEI.SaveContents();
if (!(lastEI.MyItemInfo.IsTable))
lastEI.RefreshDisplay(false);
}
}
//B2018-152 if we are deleteing a step element that has substeps and the user click on one of those substep,
// use resulting focus position returned from lastEI.DeleteItem() instead of current "value"
if (deletingParent && newFocus != null)
value = newFocus;
_SelectedEditItem = value;
if (MyStepTabPanel != null)
MyStepTabPanel.MyStepTabRibbon.MyEditItem = value;// Update StepTabRibbon.MyEditItem to match
if (value != null)
{
_SelectedEditItem.RefreshDisplay(true);
if (_SelectedItemInfo.ItemID != value.MyItemInfo.ItemID)
{
ExpandAsNeeded(value.MyItemInfo);
SelectedItemInfo = value.MyItemInfo;
}
}
lastEI?.IdentifyMe(false);
}
}
///
/// Displays the selected EditItem
///
public void ItemShow()
{
if (_SelectedEditItem != null && SelectedEditItem.BeingDisposed == false)
{
SelectedEditItem.ItemShow();
OnItemSelectedChanged(this, new ItemSelectedChangedEventArgs(SelectedEditItem));
}
}
public new void MouseWheel(MouseEventArgs e) => base.OnMouseWheel(e);
///
/// Used to track movement other than scrolling
/// 0 - Indicates no other movement
/// > 0 - Indicates that other movement is happening
///
public int ItemMoving { get; set; } = 0;
///
/// Lazy loaded StepPanelSettings
///
public StepPanelSettings MyStepPanelSettings
{
get
{
if (_MyStepPanelSettings == null) _MyStepPanelSettings = new StepPanelSettings(this);
return _MyStepPanelSettings;
}
set { _MyStepPanelSettings = value;}
}
///
/// Gets or Sets the font for the Panel
///
public Font MyFont
{
get { return _MyFont; }
set { ProcFont = SectFont = StepFont = _MyFont = value; }
}
///
/// Gets or sets the font for the Procedure Text
///
public Font ProcFont { get; set; } = new Font("Arial", 12, FontStyle.Bold);
///
/// Gets or sets the font for the Section Text
///
public Font SectFont { get; set; } = new Font("Arial", 10, FontStyle.Bold);
///
/// Gets or sets the Step Font
///
public Font StepFont { get; set; } = new Font("Arial", 10);
///
/// Gets or Sets the Active Color for the Panel
///
public Color ActiveColor
{
get {
// C2015-028 Add Editorial Mode to PROMS Step Editor
// if in Editorial Mode, use LightGreen background
_ActiveColor = MyStepTabPanel != null && MyStepTabPanel.MyDisplayTabControl.IsInEditorialMode ? Color.LightGreen : Color.SkyBlue;
return _ActiveColor;
}
set { _ActiveColor = value; }
}
///
/// Gets or Sets the Annotation backcolor for StepRTBs in the Panel
///
public Color AnnotationColor { get; set; } = Color.FromArgb(255, 255, 128);
///
/// Gets or sets the InActive Color for the Panel
///
public Color InactiveColor { get; set; } = Color.Linen;
///
/// Gets or sets the Tab Color
///
public Color TabColor { get; set; } = Color.Beige;
///
/// Gets or sets the Panel Color
///
public Color PanelColor
{
get { return _PanelColor; }
set { _PanelColor = value;
BackColor = value;
}
}
#endregion
#region DisplayConversions
///
/// gets a Graphic object for the panel
///
public Graphics MyGraphics
{
get
{
if (_MyGraphics == null)
_MyGraphics = CreateGraphics();
return _MyGraphics;
}
}
///
/// Gets the DPI setting for the current graphics setting
///
internal int DPI
{
get
{
if (_DPI == 0)
_DPI = Convert.ToInt32(MyGraphics.DpiX);
return _DPI;
}
}
///
/// Converts an integer value from Twips to Pixels
///
///
///
public int ToDisplay(int value) => (DPI * value) / 72;
public int ToDisplay(float? value) => (int)(DPI * (value ?? 0)) / 72;
///
/// Converts an integer? value from Twips to Pixels
///
///
///
public int ToDisplay(int? value) => ToDisplay((int)value);
///
/// Converts an string value from Twips to Pixels
///
///
///
public int ToDisplay(string value) => ToDisplay(Convert.ToSingle(value));
///
/// Converts a value from a list in a string from Twips to Pixels
///
///
///
public int ToDisplay(string value,int i)
{
if (i < 0) return 0;
string s = value.Split(",".ToCharArray())[i];
return ToDisplay(s);
}
#endregion
#region Debug Methods
///
/// Gets or sets ShowLines so that vertical lines are shown for debugging purposes
///
public bool ShowLines { get; set; } = true;
///
/// Toggle the vertical lines on and off
///
///
///
private void StepPanel_DoubleClick(object sender, EventArgs e)
{
ShowLines = !ShowLines;
Refresh();
}
#endregion
#region Cursor Movement Methods
///
/// Finds the Displayed 'top' child for a given item. Used for down arrow.
///
/// ItemInfo
///
private ItemInfo TopPart(ItemInfo ii)
{
ExpandAsNeeded(ii);
if (ii.Cautions != null && ii.Cautions.Count > 0) return TopPart(ii.Cautions[0]);
if (ii.Notes != null && ii.Notes.Count > 0) return TopPart(ii.Notes[0]);
return (ii);
}
///
/// Finds the Displayed 'bottom' child for a given item. Used for up arrow.
///
/// ItemInfo
///
private ItemInfo BottomPart(ItemInfo ii)
{
ExpandAsNeeded(ii);
if (ii.RNOs != null && ii.RNOs.Count > 0 && ii.RNOLevel >= ii.ColumnMode) return BottomPart(ii.RNOs[0]);
if (ii.Sections != null && ii.Sections.Count > 0) return BottomPart(ii.Sections[0].LastSibling);
if (ii.Steps != null && ii.Steps.Count > 0) return BottomPart(ii.Steps[0].LastSibling);
if (ii.Tables != null && ii.Tables.Count > 0) return BottomPart(ii.Tables[0].LastSibling);
return ii;
}
///
/// Supports cursor movement between richtext boxes, including arrow keys/page up,down/
/// ctrl Home,End
///
/// StepRTB
/// Point
/// E_ArrowKeys
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0059:Unnecessary assignment of a value", Justification = "Values assigned to ItemInfo ii for Debugging")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Point position kept for consistancy")]
public void CursorMovement(EditItem ei, Point position, E_ArrowKeys arrow)
{
ItemInfo ii = null;
// The following lines are debug to check that the results of moving down and moving up are the same
//ItemInfo ix = null;
switch (arrow)
{
case E_ArrowKeys.Up:
case E_ArrowKeys.CtrlUp:
ii = ArrowUp(ei.MyItemInfo);
// The following lines are debug to check that the results of moving down and moving up are the same
//ix = ArrowDown(ii);
//Console.WriteLine("'Up',{0},{1},{2},{3}", rtb.MyItemInfo.ItemID, rtb.MyItemInfo.DBSequence, ii.DBSequence, ix.DBSequence);
if (ii != null) SelectedEditItem = _LookupEditItems[ii.ItemID];
break;
case E_ArrowKeys.Down:
case E_ArrowKeys.CtrlDown:
ii = MoveDown(ei, ii);
break;
case E_ArrowKeys.Right:
case E_ArrowKeys.CtrlRight:
if (!ei.MyItemInfo.IsInRNO && ei.MyItemInfo.RNOs != null)
SelectedEditItem = _LookupEditItems[ei.MyItemInfo.RNOs[0].ItemID];
else
ii = MoveDown(ei, ii);
break;
case E_ArrowKeys.Left:
if (!ei.MyItemInfo.IsProcedure)
{
ii = ArrowUp(ei.MyItemInfo);
if (ii != null)
{
ItemInfo tmpII = ii;
while (!ei.MyItemInfo.IsInRNO && tmpII.RNOs != null)
tmpII = GetLowestRNOEditItem(tmpII, ei.MyItemInfo);
if (tmpII != ei.MyItemInfo)
ii = tmpII;
SelectedEditItem = _LookupEditItems[ii.ItemID];
}
}
break;
case E_ArrowKeys.CtrlLeft: // this logic is same as in 16-bit VE-PROMS
if (!ei.MyItemInfo.IsProcedure)
SelectedEditItem = _LookupEditItems[ei.MyItemInfo.MyParent.ItemID];
break;
default:
break;
}
}
// This is used for the Left Arrow key when we move off the current edit window
private ItemInfo GetLowestRNOEditItem(ItemInfo newII, ItemInfo startII)
{
EditItem tmpEI = _LookupEditItems[newII.RNOs[newII.RNOs.Count - 1].ItemID];
ItemInfo tmpII = tmpEI.MyItemInfo;
while (tmpII != startII && tmpII.RNOs != null)
{
tmpEI = _LookupEditItems[tmpII.RNOs[tmpII.RNOs.Count - 1].ItemID];
tmpII = tmpEI.MyItemInfo;
}
if (tmpII != startII && tmpEI.MyAfterEditItems != null)
tmpEI = tmpEI.MyAfterEditItems[tmpEI.MyAfterEditItems.Count - 1];
return tmpEI.MyItemInfo;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "ItemInfo ii Kept for Debugging")]
private ItemInfo MoveDown(EditItem ei, ItemInfo ii)
{
ii = ArrowDown(ei.MyItemInfo);
// The following lines are debug to check that the results of moving down and moving up are the same
//ix = ArrowUp(ii);
//Console.WriteLine("'Down',{0},{1},{2},{3}", rtb.MyItemInfo.ItemID, rtb.MyItemInfo.DBSequence, ii.DBSequence, ix.DBSequence);
if (ii != null) SelectedEditItem = _LookupEditItems[ii.ItemID];
return ii;
}
private ItemInfo ArrowUp(ItemInfo ii)
{
// Arrow-Up from a Substep should look for a Table.
if (ii.IsStepPart && (ii.MyPrevious == null) && (ii.ActiveParent as ItemInfo).Tables != null)
return BottomPart((ii.ActiveParent as ItemInfo).Tables[0]);
// if on RNO, check display mode (1 column/2 column, etc) and how deep RNO is before going to
// parents substeps.
if (ii.IsRNOPart && ii.MyParent.Steps != null && ii.RNOLevel >= ii.ColumnMode) return BottomPart(ii.MyParent.Steps[0].LastSibling);
// If on top note and parent has cautions - go to bottom caution
if (ii.IsFirstNotePart && ii.MyParent != null && ii.MyParent.Cautions != null) return BottomPart(ii.MyParent.Cautions[0].LastSibling);
if (ii.IsFirstCautionPart || ii.IsFirstNotePart)
{
if (ii.MyParent.MyPrevious != null) return BottomPart(ii.MyParent.MyPrevious);
return ii.MyParent.MyParent;
}
// If has note, BottomPart of last sibling of the note
if (ii.Notes != null) return BottomPart(ii.Notes[0].LastSibling);
// If has caution, BottomPart of last sibling of the caution
if (ii.Cautions != null) return BottomPart(ii.Cautions[0].LastSibling);
// If previous sibling, BottomPart of previous sibling
if (ii.MyPrevious != null && ii.IsProcedure == false) return BottomPart(ii.MyPrevious);
// Go to parent until at procedure
if (!ii.IsProcedure) return (ii.MyParent);
return null;
}
private ItemInfo ArrowDown(ItemInfo ii) => ArrowDown(ii, true, true);
private ItemInfo ArrowDown(ItemInfo ii, bool lookAtSub, bool lookAtRNO)
{
if (ii.IsSection || ii.IsProcedure)
{
if (lookAtSub && ii.Sections != null) return TopPart(ii.Sections[0]);
if (lookAtSub && ii.Steps != null) return TopPart(ii.Steps[0]);
ItemInfo nxt = ii.GetNext();
if (nxt != null) return TopPart(nxt);
}
else
{
// Subitems - go to top part of subitem
// (the lookAtSub prevented looping within a substep group at same level)
// Arrow down from a Table should look for a Substep
if(ii.IsTablePart && (ii.ActiveParent as ItemInfo).Steps != null)
return TopPart((ii.ActiveParent as ItemInfo).Steps[0]);
// if this is enhanced background, the RNO is displayed after the HLS, so check
// for this, arrow down should go to the RNO. If on the RNO, then go to substeps if they exist.
if (((ii.ActiveFormat.PlantFormat.FormatData.PurchaseOptions.Value & E_PurchaseOptions.EnhancedBackgrounds) == E_PurchaseOptions.EnhancedBackgrounds))
{
if (lookAtRNO && ii.RNOs != null) return TopPart(ii.RNOs[0]);
if (ii.IsRNOPart && ii.MyHLS.Steps != null) return TopPart(ii.MyHLS.Steps[0]);
}
if (lookAtSub && ii.Tables != null) return TopPart(ii.Tables[0]);
if (lookAtSub && ii.Steps != null) return TopPart(ii.Steps[0]);
// RNOs: Use PMode (column)
if (lookAtRNO && ii.RNOs != null && ii.RNOLevel >= ii.ColumnMode) return TopPart(ii.RNOs[0]);
// Nextsibling - go to top part of sibling
// TODO: RHM - NextItems was not null when it should have been after delete of a note below a caution
ItemInfo nxt = ii.GetNext();
if (nxt != null) return TopPart(nxt);
// If on caution, if parent has note - go to note
if (ii.IsCautionPart && ii.MyParent.Notes != null) return ii.MyParent.Notes[0];
// If on caution, if parent !has note or if on note go to parent
if ((ii.IsCautionPart && ii.MyParent.Notes == null) || ii.IsNotePart) return ii.MyParent;
// Recursively call with parent until at procedure
if (!ii.IsProcedure) return (ArrowDown(ii.MyParent, false, ii.MyParent.RNOLevel==ii.RNOLevel));
}
return null;
}
internal void StepCursorKeys(EditItem ei, KeyEventArgs keyargs)
{
ItemInfo ii = ei.MyItemInfo;
if (ii.IsSection || ii.IsProcedure) return;
while (!ii.IsHigh)
{
ii = ii.MyParent;
}
switch (keyargs.KeyCode)
{
// for home/end, control key must be pressed too, but this is checked
// before here.
case Keys.Home:
ii = ii.FirstSibling;
break;
case Keys.End:
ii = ii.LastSibling;
break;
case Keys.PageDown:
ii = ii.GetNext();
break;
case Keys.PageUp:
ii = ii.MyPrevious;
break;
}
if (ii == null) return;
SelectedEditItem = _LookupEditItems[ii.ItemID];
}
#endregion
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class StepPanelSettings
{
public StepPanelSettings(StepPanel panel) => MyStepPanel = panel;
public StepPanelSettings()
{
}
[Browsable(false)]
public StepPanel MyStepPanel { get; set; }
private float _CircleXOffset = -4;
[Category("Circle")]
[DisplayName("Circle Horizontal Offset")]
public float CircleXOffset
{
get { return _CircleXOffset; }
set { _CircleXOffset = value; MyStepPanel?.Refresh(); }
}
private float _CircleYOffset = -13;
[Category("Circle")]
[DisplayName("Circle Vertical Offset")]
public float CircleYOffset
{
get { return _CircleYOffset; }
set { _CircleYOffset = value; MyStepPanel?.Refresh(); }
}
private Color _CircleColor = Color.Black;
[Category("Circle")]
[DisplayName("Circle Color")]
public Color CircleColor
{
get { return _CircleColor; }
set { _CircleColor = value; MyStepPanel?.Refresh(); }
}
private int _CircleDiameter = 25;
[Category("Circle")]
[DisplayName("Circle Diameter")]
public int CircleDiameter
{
get { return _CircleDiameter; }
set { _CircleDiameter = value; MyStepPanel?.Refresh(); }
}
private int _CircleWeight = 2;
[Category("Circle")]
[DisplayName("Circle Pen Weight")]
public int CircleWeight
{
get { return _CircleWeight; }
set { _CircleWeight = value; MyStepPanel?.Refresh(); }
}
private float _NumberLocationX = 20F;
[Category("Number")]
[DisplayName("Number Location X")]
public float NumberLocationX
{
get { return _NumberLocationX; }
set { _NumberLocationX = value; MyStepPanel?.Refresh(); }
}
private float _NumberLocationY = 4;
[Category("Number")]
[DisplayName("Number Location Y")]
public float NumberLocationY
{
get { return _NumberLocationY; }
set { _NumberLocationY = value; MyStepPanel?.Refresh(); }
}
private SizeF _NumberSize = new SizeF(200F, 23F);
[Category("Number")]
[DisplayName("Number Size")]
public SizeF NumberSize
{
get { return _NumberSize; }
set { _NumberSize = value; MyStepPanel?.Refresh(); }
}
private int _TableWidthAdjust = 4;
[Category("Table")]
[DisplayName("Table Width Adjust")]
public int TableWidthAdjust
{
get { return _TableWidthAdjust; }
set { _TableWidthAdjust = value; MyStepPanel?.Refresh(); }
}
private int _CheckOffWeight = 1;
[Category("CheckOff")]
[DisplayName("CheckOff Pen Weight")]
public int CheckOffWeight
{
get { return _CheckOffWeight; }
set { _CheckOffWeight = value; MyStepPanel?.Refresh(); }
}
private Color _CheckOffColor = Color.Black;
[Category("CheckOff")]
[DisplayName("CheckOff Color")]
public Color CheckOffColor
{
get { return _CheckOffColor; }
set { _CheckOffColor = value; MyStepPanel?.Refresh(); }
}
private int _CheckOffSize =12;
[Category("CheckOff")]
[DisplayName("CheckOff Size")]
public int CheckOffSize
{
get { return _CheckOffSize; }
set { _CheckOffSize = value; MyStepPanel?.Refresh(); }
}
private int _CheckOffX =0;
[Category("CheckOff")]
[DisplayName("CheckOff X")]
public int CheckOffX
{
get { return _CheckOffX; }
set { _CheckOffX = value; MyStepPanel?.Refresh(); }
}
private int _CheckOffY =5;
[Category("CheckOff")]
[DisplayName("CheckOff Y")]
public int CheckOffY
{
get { return _CheckOffY; }
set { _CheckOffY = value; MyStepPanel?.Refresh(); }
}
private int _ChangeBarWeight = 1;
[Category("ChangeBar")]
[DisplayName("ChangeBar Pen Weight")]
public int ChangeBarWeight
{
get { return _ChangeBarWeight; }
set { _ChangeBarWeight = value; MyStepPanel?.Refresh(); }
}
private Color _ChangeBarColor = Color.Black;
[Category("ChangeBar")]
[DisplayName("ChangeBar Color")]
public Color ChangeBarColor
{
get { return _ChangeBarColor; }
set { _ChangeBarColor = value; MyStepPanel?.Refresh(); }
}
}
public partial class StepPanelEventArgs
{
public EditItem MyEditItem { get; set; }
public MouseEventArgs MyMouseEventArgs { get; set; }
public StepPanelEventArgs(EditItem myEditItem, MouseEventArgs myMouseEventArgs)
{
MyEditItem = myEditItem;
MyMouseEventArgs = myMouseEventArgs;
}
}
public partial class ItemSelectedChangedEventArgs
{
public ItemInfo MyItemInfo { get; set; }
public EditItem MyEditItem { get; set; } = null;
public ItemSelectedChangedEventArgs(ItemInfo myItemInfo)
{
MyItemInfo = myItemInfo;
}
public ItemSelectedChangedEventArgs(EditItem myEditItem)
{
MyItemInfo = myEditItem?.MyItemInfo;
MyEditItem = myEditItem;
}
}
public partial class StepPanelAttachmentEventArgs
{
public EditItem MyEditItem { get; set; }
public StepPanelAttachmentEventArgs(EditItem myEditItem)
{
MyEditItem = myEditItem;
}
}
public partial class StepPanelLinkEventArgs : EventArgs
{
public string LinkInfoText { get; }
public LinkText MyLinkText { get; }
public StepPanelLinkEventArgs(string linkInfoText)
{
LinkInfoText = linkInfoText;
MyLinkText = new LinkText(LinkInfoText);
//for Debugging: linkInfo.LinkText
}
}
public partial class StepPanelTabDisplayEventArgs : EventArgs
{
public string PanelTabName { get; }
public StepPanelTabDisplayEventArgs(string panelTabname) => PanelTabName = panelTabname;
}
public partial class WordSectionEventArgs : EventArgs
{
public SectionInfo MySectionInfo { get; }
public WordSectionEventArgs(SectionInfo mySectionInfo)
{
MySectionInfo = mySectionInfo;
}
}
public delegate void StepPanelEvent(object sender, StepPanelEventArgs args);
public delegate void ItemSelectedChangedEvent(object sender, ItemSelectedChangedEventArgs args);
public delegate void StepPanelLinkEvent(object sender, StepPanelLinkEventArgs args);
public delegate void StepPanelAttachmentEvent(object sender, StepPanelAttachmentEventArgs args);
public delegate void StepRTBLinkEvent(object sender, StepPanelLinkEventArgs args);
public delegate void StepPanelModeChangeEvent(object sender, StepRTBModeChangeEventArgs args);
public delegate void StepPanelTabDisplayEvent(object sender, StepPanelTabDisplayEventArgs args);
public delegate void StepPanelWordSectionCloseEvent(object sender, WordSectionEventArgs args);
public delegate void StepPanelWordSectionDeletedEvent(object sender, WordSectionEventArgs args);
public delegate void StepPanelItemPastedEvent(object sender, vlnTreeItemInfoPasteEventArgs args);
}