diff --git a/PROMS/Volian.Controls.Library/StepPanel.cs b/PROMS/Volian.Controls.Library/StepPanel.cs
index ee323169..278a463a 100644
--- a/PROMS/Volian.Controls.Library/StepPanel.cs
+++ b/PROMS/Volian.Controls.Library/StepPanel.cs
@@ -581,6 +581,151 @@ namespace Volian.Controls.Library
}
}
#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) return TopPart(ii.Cautions[0]);
+ if (ii.Notes != null) 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.RNOLevel >= ii.Columns - 1) return BottomPart(ii.RNOs[0]);
+ if (ii.Sections != null) return BottomPart(ii.Sections[0].LastSibling);
+ if (ii.Steps != null) return BottomPart(ii.Steps[0].LastSibling);
+ return ii;
+ }
+ ///
+ /// Supports cursor movement between richtext boxes, including arrow keys/page up,down/
+ /// ctrl Home,End
+ ///
+ /// StepRTB
+ /// Point
+ /// E_ArrowKeys
+ public void CursorMovement(StepRTB rtb, Point position, E_ArrowKeys arrow)
+ {
+ ItemInfo ii = null;
+ switch (arrow)
+ {
+ case E_ArrowKeys.Up:
+ case E_ArrowKeys.CtrlUp:
+ ii = ArrowUp(rtb.MyItemInfo);
+ if (ii != null) SelectedStepRTB = _LookupStepItems[ii.ItemID].MyStepRTB;
+ break;
+ case E_ArrowKeys.Down:
+ case E_ArrowKeys.CtrlDown:
+ ii = ArrowDown(rtb.MyItemInfo);
+ if (ii != null) SelectedStepRTB = _LookupStepItems[ii.ItemID].MyStepRTB;
+ break;
+ case E_ArrowKeys.Right:
+ case E_ArrowKeys.CtrlRight:
+ if (rtb.MyItemInfo.RNOs != null)
+ SelectedStepRTB = _LookupStepItems[rtb.MyItemInfo.RNOs[0].ItemID].MyStepRTB;
+ break;
+ case E_ArrowKeys.Left:
+ case E_ArrowKeys.CtrlLeft:
+ if (!rtb.MyItemInfo.IsProcedure)
+ SelectedStepRTB = _LookupStepItems[rtb.MyItemInfo.MyParent.ItemID].MyStepRTB;
+ break;
+ default:
+ break;
+ }
+ }
+ private ItemInfo ArrowUp(ItemInfo ii)
+ {
+ // if on RNO, check display mode (1 column/2 column, etc) and how deep RNO is before going to
+ // parents substeps.
+ if (ii.IsRNO && ii.MyParent.Steps != null && ii.RNOLevel >= ii.Columns) return BottomPart(ii.MyParent.Steps[0].LastSibling);
+
+ // If on top note and parent has cautions - go to bottom caution
+ if (ii.IsNoteStructure && ii.MyParent != null && ii.MyParent.Cautions != null) return BottomPart(ii.MyParent.Cautions[0].LastSibling);
+ if (ii.IsCautionStructure || ii.IsNoteStructure)
+ {
+ 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) return BottomPart(ii.MyPrevious);
+ // Go to parent until at procedure
+ if (!ii.IsProcedure) return (ii.MyParent);
+ return null;
+ }
+ private ItemInfo ArrowDown(ItemInfo ii)
+ {
+ return 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]);
+ if (ii.IsSection && ii.NextItems != null) return TopPart(ii.NextItems[0]);
+ }
+ else
+ {
+ // Subitems - go to top part of subitem
+ // (the lookAtSub prevented looping within a substep group at same level)
+ if (lookAtSub && ii.Steps != null) return TopPart(ii.Steps[0]);
+ // RNOs: Use PMode (column)
+ if (lookAtRNO && ii.RNOs != null && ii.RNOLevel >= ii.Columns - 1) return TopPart(ii.RNOs[0]);
+ // Nextsibling - go to top part of sibling
+ if (ii.NextItems != null) return TopPart(ii.NextItems[0]);
+ // If on caution, if parent has note - go to note
+ if (ii.IsCautionStructureFirstSib && 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.IsCautionStructureFirstSib && ii.MyParent.Notes == null) || ii.IsNoteStructureFirstSib) 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(StepRTB rtb, KeyEventArgs keyargs)
+ {
+ ItemInfo ii = rtb.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.NextItems == null ? null : ii.NextItems[0];
+ break;
+ case Keys.PageUp:
+ ii = ii.MyPrevious;
+ break;
+ }
+ if (ii == null) return;
+ SelectedStepRTB = _LookupStepItems[ii.ItemID].MyStepRTB;
+ }
+ #endregion
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class StepPanelSettings
@@ -813,7 +958,7 @@ namespace Volian.Controls.Library
private LinkText _MyLinkText;
public LinkText MyLinkText
{
- get { return _MyLinkText; }
+ get { return _MyLinkText;}
}
public StepPanelLinkEventArgs(StepItem linkedStepItem, string linkInfoText)
{
diff --git a/PROMS/Volian.Controls.Library/StepRTB.cs b/PROMS/Volian.Controls.Library/StepRTB.cs
index 5f3bc9b9..1f83f5bc 100644
--- a/PROMS/Volian.Controls.Library/StepRTB.cs
+++ b/PROMS/Volian.Controls.Library/StepRTB.cs
@@ -305,7 +305,7 @@ namespace Volian.Controls.Library
}
private void AddSymbol(string str)
{
- MessageBox.Show(SelectedRtf);
+ //MessageBox.Show(SelectedRtf);
SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + " " + /* ConvertUnicodeChar(str) */ str + @"}";
}
private void AddRtfLink(displayLinkElement myDisplayLinkElement)
@@ -435,6 +435,7 @@ namespace Volian.Controls.Library
}
#endregion
#region EventSupport
+
#region LinkEvents
private StepPanelLinkEventArgs _MyLinkClickedEventArgs;
public event StepRTBLinkEvent LinkChanged;
@@ -486,7 +487,7 @@ namespace Volian.Controls.Library
private bool IsControlChar = false;
void StepRTB_KeyDown(object sender, KeyEventArgs e)
{
- if (e.Modifiers == Keys.Control)
+ if (e.Control)
{
IsControlChar = true;
switch (e.KeyCode)
@@ -496,59 +497,124 @@ namespace Volian.Controls.Library
// check if insertable?
Console.WriteLine(String.Format("in switch, keydata = {0}, keyvalue = {1}, buff = {2}", e.KeyData, e.KeyValue, buff));
+ return;
+ case Keys.Home:
+ StepRTB_HomeEndPressed(e);
+ e.Handled = true;
+ break;
+ case Keys.End:
+ StepRTB_HomeEndPressed(e);
+ e.Handled = true;
break;
}
}
- else
+ switch (e.KeyCode)
{
- switch (e.KeyCode)
- {
- case Keys.Delete:
- // if it's just a link, delete the link. if the text has embedded links, i.e. text and links
- // use DeleteTextAndLink to delete it (just setting selectedrtf to "" fails because of the
- // embedded protected text. If it's just text, let the richtextbox handle the delete.
- if (_MyLinkText != null)
+ case Keys.Left:
+ if (e.Control || SelectionStart == 0)
+ {
+ StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlLeft : E_ArrowKeys.Left);
+ e.Handled = true;
+ }
+ break;
+ case Keys.Up:
+ int ln = GetLineFromCharIndex(SelectionStart);
+ if (e.Control || ln == 0)
+ {
+ StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlUp : E_ArrowKeys.Up);
+ e.Handled = true;
+ }
+ break;
+ case Keys.Right:
+ if (e.Control || SelectionStart == this.Text.Length)
+ {
+ StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlRight : E_ArrowKeys.Right);
+ e.Handled = true;
+ }
+ break;
+ case Keys.Down:
+ int l = GetLineFromCharIndex(SelectionStart);
+ Point pos = new Point();
+ pos.X = ClientRectangle.Width;
+ pos.Y = ClientRectangle.Height;
+ int lastIndex = this.GetCharIndexFromPosition(pos);
+ int lastLine = this.GetLineFromCharIndex(lastIndex);
+
+ if (e.Control || l == lastLine)
+ {
+ StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlDown : E_ArrowKeys.Down);
+ e.Handled = true;
+ }
+ break;
+ case Keys.PageUp:
+ StepRTB_PageKeyPressed(e);
+ e.Handled = true;
+ break;
+ case Keys.PageDown:
+ StepRTB_PageKeyPressed(e);
+ e.Handled = true;
+ break;
+ case Keys.Delete:
+ // if it's just a link, delete the link. if the text has embedded links, i.e. text and links
+ // use DeleteTextAndLink to delete it (just setting selectedrtf to "" fails because of the
+ // embedded protected text. If it's just text, let the richtextbox handle the delete.
+ if (_MyLinkText != null)
+ {
+ DeleteLink();
+ e.Handled = true;
+ }
+ else if (SelectedRtf.IndexOf(@"\protect") > -1)
+ {
+ // unprotect and then delete text & links.
+ DeleteTextAndLink();
+ e.Handled = true;
+ }
+ break;
+ case Keys.Back:
+ // if not a range, i.e. SelectionLength = 0, then see if backspacing a link
+ // or just regular text. If link, need to select link, unprotect before delete.
+ if (SelectionLength == 0 && SelectionStart > 0)
+ {
+ int tmpss = SelectionStart;
+ Select(SelectionStart - 1, 0); // see if previous char is protected
+ if (SelectionProtected)
{
+ SelectLinkFromIndex(SelectionStart);
DeleteLink();
e.Handled = true;
}
- else if (SelectedRtf.IndexOf(@"\protect") > -1)
- {
- // unprotect and then delete text & links.
- DeleteTextAndLink();
- e.Handled = true;
- }
- break;
- case Keys.Back:
- // if not a range, i.e. SelectionLength = 0, then see if backspacing a link
- // or just regular text. If link, need to select link, unprotect before delete.
- if (SelectionLength == 0 && SelectionStart > 0)
- {
- int tmpss = SelectionStart;
- Select(SelectionStart - 1, 0); // see if previous char is protected
- if (SelectionProtected)
- {
- SelectLinkFromIndex(SelectionStart);
- DeleteLink();
- e.Handled = true;
- }
- else
- Select(tmpss, 0); // go back to original cursor position
- }
- // if a range, need to see if range includes protected text, if so this is a
- // special case, so use DeleteTextAndLink. Otherwise, just let the richtextbox
- // delete it.
- else if (SelectionLength > 0 && (SelectedRtf.IndexOf(@"\protect") > -1))
- {
- // unprotect and then delete text & links.
- DeleteTextAndLink();
- e.Handled = true;
- }
- break;
- }
+ else
+ Select(tmpss, 0); // go back to original cursor position
+ }
+ // if a range, need to see if range includes protected text, if so this is a
+ // special case, so use DeleteTextAndLink. Otherwise, just let the richtextbox
+ // delete it.
+ else if (SelectionLength > 0 && (SelectedRtf.IndexOf(@"\protect") > -1))
+ {
+ // unprotect and then delete text & links.
+ DeleteTextAndLink();
+ e.Handled = true;
+ }
+ break;
}
}
-
+ private void StepRTB_HomeEndPressed(KeyEventArgs keyargs)
+ {
+ if (MyItemInfo.IsProcedure || MyItemInfo.IsSection) return;
+ // Cursor moves out of box only if control is pressed too - otherwise key is
+ // handled in rtb.
+ if (keyargs.Control)_MyStepItem.MyStepPanel.StepCursorKeys(this, keyargs);
+ }
+ private void StepRTB_PageKeyPressed(KeyEventArgs keyargs)
+ {
+ if (MyItemInfo.IsProcedure || MyItemInfo.IsSection) return;
+ _MyStepItem.MyStepPanel.StepCursorKeys(this, keyargs);
+ }
+ private void StepRTB_ArrowPressed(E_ArrowKeys key)
+ {
+ Point cp = PointToClient(Cursor.Position);
+ _MyStepItem.MyStepPanel.CursorMovement(this, cp, key);
+ }
private void DeleteTextAndLink()
{
int start = SelectionStart;