diff --git a/PROMS/Volian.Controls.Library/StepRTB.cs b/PROMS/Volian.Controls.Library/StepRTB.cs
index 7b41d6ef..ca6ef7db 100644
--- a/PROMS/Volian.Controls.Library/StepRTB.cs
+++ b/PROMS/Volian.Controls.Library/StepRTB.cs
@@ -7,15 +7,41 @@ using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
using VEPROMS.CSLA.Library;
namespace Volian.Controls.Library
{
public delegate void StepRTBEvent(object sender, EventArgs args);
- public partial class StepRTB : RichTextBox , IStepRTB
+ public partial class StepRTB : RichTextBox , IStepRTB
{
+ #region Events
+ public event StepRTBEvent RTBSelectionChanged;
+ private void OnRTBSelectionChanged(object sender, EventArgs args)
+ {
+ if (RTBSelectionChanged != null) RTBSelectionChanged(sender, args);
+ }
+ public event StepRTBEvent LinkLocationsChanged;
+ private void OnLinkLocationChanged(object sender, EventArgs args)
+ {
+ if (LinkLocationsChanged != null) LinkLocationsChanged(sender, args);
+ }
+ public event StepRTBEvent RTBRangeStatusChanged;
+ private void OnRTBRangeStatusChanged(object sender, EventArgs args)
+ {
+ if (RTBRangeStatusChanged != null) RTBRangeStatusChanged(sender, args);
+ }
+ ///
+ /// This event is not raised during all the in-between changes for link deletions
+ ///
+ public event StepRTBEvent RTBTextChanged;
+ private void OnRTBTextChanged(object sender, EventArgs args)
+ {
+ if (RTBTextChanged != null) RTBTextChanged(sender, args);
+ }
+ #endregion
#region Properties and Variables
- // use newer rich text box....
+ // use newer rich text box....
//[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
//static extern IntPtr LoadLibrary(string lpFileName);
//protected override CreateParams CreateParams
@@ -39,7 +65,7 @@ namespace Volian.Controls.Library
set { _MyStepItem = value; }
}
private bool _IsDirty = false;
- //private bool _InitializingRTB;
+ private bool _InitializingRTB;
private IContainer _Container = null;
private string _MyClassName=string.Empty;
public string MyClassName
@@ -73,7 +99,7 @@ namespace Volian.Controls.Library
_MyItemInfo = value;
if (value != null)
{
- //_InitializingRTB = true;
+ _InitializingRTB = true;
DisplayText vlntxt = new DisplayText(_MyItemInfo, EpMode, VwMode);
_origDisplayText = vlntxt;
#if(DEBUG)
@@ -85,32 +111,25 @@ namespace Volian.Controls.Library
#endif
Text = ""; // Initialize text before add text
- //if (_MyStepItem.MyID == 168)
- // IMPORTANT: SetLineSpacing must be set before Link/protect, otherwise it
+ // IMPORTANT: SetLineSpacing must be set before Links, otherwise it
// was confusing the 'handle' of the rtf box.
RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT);
-
- //SelectionStart = 1;
AddRtfText(vlntxt);
- //AddRtfStyles();
+ AddRtfStyles();
ReadOnly = !(EpMode == E_EditPrintMode.Edit && VwMode == E_ViewMode.Edit);
- if (_MyStepItem.MyID == 168)
- RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT);
- if (_MyStepItem.MyID == 168)
- Console.WriteLine("After Linespacing\r\n {0}", Rtf);
- //if (((_origDisplayText.TextFont.Style & E_Style.Bold) != 0) || ((_origDisplayText.TextFont.Style & E_Style.MmBold) != 0))
- // RTBAPI.ToggleBold(true, this, RTBAPI.RTBSelection.SCF_ALL);
- //if ((_origDisplayText.TextFont.Style & E_Style.Italics) != 0)
- // RTBAPI.ToggleItalic(true, this, RTBAPI.RTBSelection.SCF_ALL);
- //if ((_origDisplayText.TextFont.Style & E_Style.Underline) != 0)
- // RTBAPI.ToggleUnderline(true, this, RTBAPI.RTBSelection.SCF_ALL);
- //_InitializingRTB = false;
+ _InitializingRTB = false;
_IsDirty = false;
ClearUndo();
_MyItemInfo.MyConfig.PropertyChanged += new PropertyChangedEventHandler(MyConfig_PropertyChanged);
}
}
}
+ private bool _ProcessKeystrokes = true;
+ public bool ProcessKeystrokes
+ {
+ get { return _ProcessKeystrokes; }
+ set { _ProcessKeystrokes = value; }
+ }
//public EnterKeyHandler EnterKeyPressed;
//protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
@@ -214,9 +233,11 @@ namespace Volian.Controls.Library
this.LinkClicked += new LinkClickedEventHandler(StepRTB_LinkClicked);
this.Click +=new EventHandler(StepRTB_Click);
this.KeyPress += new KeyPressEventHandler(StepRTB_KeyPress);
- this.KeyUp += new KeyEventHandler(StepRTB_KeyUp);
this.KeyDown += new KeyEventHandler(StepRTB_KeyDown);
+ this.KeyUp += new KeyEventHandler(StepRTB_KeyUp);
this.TextChanged += new EventHandler(StepRTB_TextChanged);
+ this.MouseUp += new MouseEventHandler(StepRTB_MouseUp);
+ this.MouseDown += new MouseEventHandler(StepRTB_MouseDown);
this.SelectionChanged +=new EventHandler(StepRTB_SelectionChanged);
}
@@ -224,23 +245,27 @@ namespace Volian.Controls.Library
{
SaveConfig();
}
-
private void StepRTB_Click(object sender, EventArgs e)
{
if (ReadOnly) return;
-
- if (!SelectionProtected)
- {
- MyLinkText = null;
- }
}
public bool inRoAdd = false;
void StepRTB_SelectionChanged(object sender, EventArgs e)
{
- if (inRoAdd)
- Console.WriteLine("SelectionStart {0}, SelectionLength {1}", SelectionStart, SelectionLength);
- if (!SelectionProtected && MyLinkText != null) MyLinkText = null;
-
+ if (_InitializingRTB) return;
+ //DebugSelection("SelectionChanged Event ");
+ if (SelectionStart == 40 && SelectionLength == 1) vlnStackTrace.ShowStack("SELECTIONCHANGED EVENT");
+ HandleSelectionChange();
+ }
+ private bool _MouseDown = false;
+ private void StepRTB_MouseDown(object sender, MouseEventArgs e)
+ {
+ _MouseDown = true;
+ }
+ void StepRTB_MouseUp(object sender, MouseEventArgs e)
+ {
+ _MouseDown = false;
+ HandleSelectionChange();
}
#endregion
#region ApplicationSupport
@@ -256,6 +281,7 @@ namespace Volian.Controls.Library
}
public void InsertRO(string value, string link)
{
+ Console.WriteLine("Before Insert Called: {0}", Rtf);
AddRtfLink(value, link);
}
public void InsertTran(string value, string link)
@@ -292,6 +318,7 @@ namespace Volian.Controls.Library
bool success = _origDisplayText.Save((RichTextBox)this);
if (success)
{
+ FindAllLinks();
_IsDirty = false;
ClearUndo();
}
@@ -319,36 +346,10 @@ namespace Volian.Controls.Library
else
AddRtfLink((displayLinkElement)vte);
}
- if (_MyStepItem.MyID == 168)
- Console.WriteLine("_SelectedRtbSB\r\n {0}", _SelectedRtfSB.ToString());
SelectedRtf = _SelectedRtfSB.ToString() + "}";
- if (_MyStepItem.MyID == 168)
- Console.WriteLine("Rtf\r\n {0}", Rtf);
- //if (_LinkPosition > -1)
- FormatLinks();
- }
-
- private void FormatLinks()
- {
- if (_LinkLocations != null)
- {
- foreach (LinkLocation ll in _LinkLocations)
- {
- Select(ll.Position, ll.Length);
-
- RTBAPI.CharFormatTwo charFormat = RTBAPI.GetCharFormat(this, RTBAPI.RTBSelection.SCF_SELECTION);
- // Protect the link text to avoid manual changes
- charFormat.dwMask = RTBAPI.CharFormatMasks.CFM_LINK | RTBAPI.CharFormatMasks.CFM_PROTECTED;
- charFormat.dwEffects = RTBAPI.CharFormatEffects.CFE_LINK | RTBAPI.CharFormatEffects.CFE_PROTECTED;
- RTBAPI.SetCharFormat((RichTextBox)this, RTBAPI.RTBSelection.SCF_SELECTION, charFormat);
- //charFormat.dwMask = /* RTBAPI.CharFormatMasks.CFM_LINK | */ RTBAPI.CharFormatMasks.CFM_PROTECTED;
- //charFormat.dwEffects = /* RTBAPI.CharFormatEffects.CFE_LINK | */ RTBAPI.CharFormatEffects.CFE_PROTECTED;
- //RTBAPI.SetCharFormat((RichTextBox)this, RTBAPI.RTBSelection.SCF_SELECTION, charFormat);
- }
- }
+ FindAllLinks();
}
private StringBuilder _SelectedRtfSB = new StringBuilder();
-
private void AddFontTable()
{
StringBuilder sbbeg = new StringBuilder();
@@ -371,65 +372,57 @@ namespace Volian.Controls.Library
_SelectedRtfSB.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset2 " + this.Font.FontFamily.Name + @";}"); //}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}}";
_SelectedRtfSB.Append(@"{\f1\fnil\fcharset0 Arial Unicode MS;}}");
_SelectedRtfSB.Append("\r\n");
- // use styles to construct rtf commands to insert into next line (where \b is)
+ // use styles to construct rtf commands to insert into next line (where \b, etc is)
_SelectedRtfSB.Append(@"\viewkind4\uc1\pard\sl-240\slmult0" + sbbeg.ToString() + @"\fs" + this.Font.SizeInPoints * 2 + @" "); // \f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}";
- //SelectedRtf = _SelectedRtfSB.ToString();
}
private void AddRtf(displayTextElement myDisplayTextElement)
{
- // try later, i.e. adding bold to font name: SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @",Bold;}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}}";
- //SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @";}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}}";
- //_SelectedRtfSB.Append(@"\f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text); // + @"}");
- _SelectedRtfSB.Append(@"\f0 " + myDisplayTextElement.Text); // + @"}");
+ _SelectedRtfSB.Append(@"\f0 " + myDisplayTextElement.Text);
}
private void AddRtf(string str)
{
+ // Because we're inserting rtf with { }, the surrounding styles are not included. Get the font
+ // style of current position & use it after the insert to set the style.
+ RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(this);
+ int positionStart = SelectionStart;
+ SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @";}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + str + @"}}";
+ // Note that SelectedRtf does not contain the inserted text after the previous line. We need
+ // to determine how long the inserted string is in order to set its style. SelectionStart contains
+ // the location after the insertion.
+ int positionAfter = SelectionStart;
+ Select(positionStart, positionAfter - positionStart);
+ RTBAPI.SetFontStyle(this, fs);
+ Select(positionAfter, 0);
+ }
+ private void AddText(string str)
+ {
+ // See comments in AddRtf(string str) to explain the font style setting
+ RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(this);
+ int positionStart = SelectionStart;
SelectedText = str;
-// SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @";}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + str + @"}}";
+ int positionAfter = SelectionStart;
+ Select(positionStart, positionAfter - positionStart);
+ RTBAPI.SetFontStyle(this, fs);
+ Select(positionAfter, 0);
}
private void AddSymbol(displayTextElement myDisplayTextElement)
{
- //_SelectedRtfSB.Append(@"\f1\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text);
_SelectedRtfSB.Append(@"\f1 " + myDisplayTextElement.Text);
- //SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}";
}
private void AddSymbol(string str)
{
- //MessageBox.Show(SelectedRtf);
- Font selfont = this.SelectionFont;
- StringBuilder sbbeg = new StringBuilder();
- StringBuilder sbend = new StringBuilder();
- if (selfont.Bold)
- {
- sbbeg.Append(@"\b");
- sbend.Append(@"\b0");
- }
- if (selfont.Underline)
- {
- sbbeg.Append(@"\ul");
- sbend.Insert(0,@"\ulnone");
- }
- if (selfont.Italic)
- {
- sbbeg.Append(@"\i");
- sbend.Insert(0, @"\i0");
- }
- if (sbend.Length > 0) sbbeg.Append(" ");
-
- // sub/superscript???
- SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + sbbeg.ToString() + str + sbend.ToString() + @"}";
+ // See comments in AddRtf(string str) to explain the font style setting
+ RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(this);
+ int position = SelectionStart;
+ SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + str + @"}";
+ Select(position, 1);
+ RTBAPI.SetFontStyle(this, fs);
+ Select(position + 1, 0);
}
- private List _LinkLocations = null;
- private void AddLinkLocation(string location, string url)
+ private string GetAddSymbolText(string symtxt)
{
- SelectedRtf = _SelectedRtfSB.ToString() + "}";
- int linkPosition = this.TextLength;
- this.Text = "";
- if (_LinkLocations == null) _LinkLocations = new List();
- _LinkLocations.Add(new LinkLocation(linkPosition, location.Length + url.Length));
+ return (@"{\f0\fs" + this.Font.SizeInPoints * 2 + @" " + symtxt + @"}");
}
- private int _LinkPosition = -1;
- private int _LinkLength;
private void AddRtfLink(displayLinkElement myDisplayLinkElement)
{
if (CreateParams.ClassName == "RICHEDIT50W")
@@ -438,40 +431,27 @@ namespace Volian.Controls.Library
else
{
AddLinkLocation(myDisplayLinkElement.Text, myDisplayLinkElement.Link);
- _SelectedRtfSB.Append(@"\f0 ");
- _SelectedRtfSB.Append(myDisplayLinkElement.Text);
- _SelectedRtfSB.Append(@"\v ");
- _SelectedRtfSB.Append(myDisplayLinkElement.Link);
- _SelectedRtfSB.Append(@"\v0 ");
- //_SelectedRtfSB.Append(@"\sl-240\slmult0\f0\fs20 0POP05-EO-ES00, REDIAGNOSIS, COVER\v #Link:Transition:5 7 198\v0");
- //AddLink20(myDisplayLinkElement.Text, myDisplayLinkElement.Link);
+ _SelectedRtfSB.Append(@"\f0\fs20 ");
+ _SelectedRtfSB.Append(myDisplayLinkElement.TextAndLink);
}
}
public void AddRtfLink(string linkUrl, string linkValue)
{
- //if (CreateParams.ClassName == "RICHEDIT50W")
+ if (CreateParams.ClassName == "RICHEDIT50W")
- //AddLink50(linkUrl, linkValue);
- //else
-
- //AddLink20(linkUrl, linkValue);
+ AddLink50(linkUrl, linkValue);
+ else
+ AddLink20(linkUrl, linkValue);
}
private void AddLink20(string linkValue, string linkUrl)
{
this.DetectUrls = false;
- RTBAPI.CharFormatTwo charFormat = RTBAPI.GetCharFormat(this, RTBAPI.RTBSelection.SCF_SELECTION);
int position = SelectionStart; // before inserttran = this.TextLength;
SelectionLength = 0;
- //SelectedRtf = @"{\rtf1\ansi " + linkValue + @"\v " + linkUrl + @"\v0}";
- SelectedRtf = linkValue + @"\v " + linkUrl + @"\v0";
- Select(position, linkValue.Length + linkUrl.Length);
- // Protect the link text to avoid manual changes
- charFormat.dwMask = RTBAPI.CharFormatMasks.CFM_LINK | RTBAPI.CharFormatMasks.CFM_PROTECTED;
- charFormat.dwEffects = RTBAPI.CharFormatEffects.CFE_LINK | RTBAPI.CharFormatEffects.CFE_PROTECTED;
- RTBAPI.SetCharFormat((RichTextBox)this, RTBAPI.RTBSelection.SCF_SELECTION, charFormat);
- this.SelectionStart = this.TextLength;
-// \protect\fs20 0POP05-EO-ES00, REDIAGNOSIS, COVER\v #Link:Transition:5 7 198\protect0\v0
+ SelectedRtf = @"{\rtf1\ansi\v \v0 }";
this.SelectionLength = 0;
+ this.SelectionStart = position;
+ FindAllLinks();
}
private void AddLink50(string linkValue, string linkUrl)
{
@@ -539,10 +519,6 @@ namespace Volian.Controls.Library
Application.DoEvents();
int heightFont = SelectionFont.Height;
int borderSize = this.Height - this.ClientSize.Height;
- //for (int i = 235; i < TextLength; i++)
- //{
- // Console.WriteLine("{0}\t{1}\t{2}", i, GetLineFromCharIndex(i), GetPositionFromCharIndex(i));
- //}
int heightNext = (1 + GetLineFromCharIndex(TextLength)) * heightFont + borderSize + 2;// 2 pixels - 1 at the top and 1 at the bottom
return heightNext;
}
@@ -566,7 +542,6 @@ namespace Volian.Controls.Library
}
#endregion
#region EventSupport
-
#region LinkEvents
private StepPanelLinkEventArgs _MyLinkClickedEventArgs;
public event StepRTBLinkEvent LinkChanged;
@@ -608,14 +583,290 @@ namespace Volian.Controls.Library
void StepRTB_TextChanged(object sender, EventArgs e)
{
_IsDirty = true;
+ FindAllLinks();
}
void StepRTB_ContentsResized(object sender, ContentsResizedEventArgs e)
{
ContentsRectangle = e.NewRectangle;
}
#endregion
+ #region Selection Handlers
+ bool _AdjustingSelection = false;
+ private bool _ProcessingDelete;
+ private void HandleSelectionChange()
+ {
+ bool startingValue = _AdjustingSelection;
+ if (_IdentifyingLinks || _ProcessingDelete) return;
+ if (ProcessKeystrokes)
+ {
+ if (!_MouseDown && !_AdjustingSelection)
+ {
+ if (_LinkLocations != null)
+ {
+ DebugPrint("HSC===================>Beginning: SelectionStart {0}, SelectionLength {1}", SelectionStart, SelectionLength);
+ _AdjustingSelection = true;
+ LinkLocation ll = FindLinkLocation();
+ LinkLocation llend = null;
+ if (SelectionLength != 0)
+ llend = FindLinkLocation(SelectionStart + SelectionLength - 1);
+ if (ll != null)
+ {
+ if (SelectionStart == ll.Start && SelectionLength == 0)
+ {
+ if (SelectionStart >= 7)
+ {
+ DebugPrint("HSC===================>ll Insert: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, ll.Start, ll.Length);
+ SelectionStart = ll.Start - 7;
+ }
+ }
+ else if (SelectionStart + SelectionLength > ll.End) // Beyond the end of the starting link
+ {
+ int end = SelectionStart + SelectionLength;
+ if (llend != null) end = llend.End; // If it extends into another link extend the end to the end of that link
+ DebugPrint("HSC===================>ll After: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, ll.Start, ll.Length);
+ SetSelection(ll.Start, end - ll.Start);
+ }
+ else if (SelectionStart >= ll.Start || SelectionLength > 0)// Within the starting link
+ {
+ DebugPrint("HSC===================>ll: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, ll.Start, ll.Length);
+ SetSelection(ll);
+ }
+ }
+ else if (llend != null)
+ {
+ DebugPrint("HSC===================>llend: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, llend.Start, llend.Length);
+ // Check to see if the beginning starts before the Removing ending Removing starting _AdjustingSelection problem");
+ DebugPrint("RS------ SelectionChange > {0}", FindRangeStatus());
+ OnRTBSelectionChanged(this, new EventArgs());
+ }
+ private bool _CheckSelection = false;
+ #endregion
+ #region Delete Handlers
+ private void HandleDeleteKeyWithSelectedText(KeyEventArgs e, char keychar)
+ {
+ _ProcessingDelete = true;
+ FindRangeStatus();
+ //DebugPrint("RS---------------- Delete > {0}", _RTBRangeStatus);
+ switch (_RTBRangeStatus)
+ {
+ case RangeStatus.NoContainedLinks:
+ case RangeStatus.Before_After:
+ case RangeStatus.Before_EndLink:
+ case RangeStatus.Before_EndBox:
+ default:
+ DeleteCurrentSelection(keychar);
+ e.SuppressKeyPress = true;
+ break;
+ case RangeStatus.Before_Between: //myRTB1.SelectedText.EndsWith(@"[END>
+ /// This inserts a space in between two links.
+ /// It actually inserts "\v0 {space}\v " between the END tag and the START tag
+ ///
+ ///
+ ///
+ ///
+ private void InsertCharBetweenLinks(LinkLocation ll, char charToAdd, bool setSelect)
+ {
+ //_InsertingSpaceBetweenLinks = true;
+ DebugPrint("ICBLvvvvvvvvvvvvvvv>>>");
+ Rtf = Rtf.Substring(0, ll.StartRtf) + @"\v0 " + charToAdd.ToString() + @"\v " + Rtf.Substring(ll.StartRtf);
+ //_InsertingSpaceBetweenLinks = false;
+ if (setSelect)
+ SelectionStart = ll.Start - 6; // account for >>");
+ }
+ private void ExpandSelectionToIncludeStart()
+ {
+ //_AdjustingSelection = true;
+ SetSelection(SelectionStart - 7, SelectionLength + 7); // Expand selection to include start
+ //_AdjustingSelection = false;
+ }
+ private void DeleteBetweenBetweenLinks(char keychar)
+ {
+
+ DebugSelection("DeleteBetweenBetweenLinks");
+ int selStart = SelectionStart - 7;
+ int selLength = SelectionLength + 2; // Include the two added spaces
+ InsertCharBetweenLinks(_RangeEndLink.NextLink); // Add a space at the end link
+ InsertCharBetweenLinks(_RangeStartLink); // Add a space a the start link
+ SetSelection(selStart, selLength);// Select everything including the spaces
+ DeleteCurrentSelection(keychar);// Delete Selection
+ }
+ ///
+ /// This is added to handle a glitch in richtextbox. Depending on
+ /// which direction that selection is made (left -> right or right -> left)
+ /// a replacement or delete may not work, you'll just get a 'beep'.
+ /// This approach consistently works.
+ ///
+ private void DeleteCurrentSelection(char key)
+ {
+ DebugPrint("vvvvvvvvvvvvxxxxxxxxxxxx>");
+ DebugSelection("Before X");
+ SelectedText = key==0?"X":key.ToString(); // replace text with X
+ DebugSelection("After X");
+ DebugPrint("------------xxxxxxxxxxxx>");
+ if (key == 0)
+ {
+ _SendBackSpace = true;
+ RtbSendKeys("{BS}"); // remove X
+ Application.DoEvents();
+ DebugSelection("After BS");
+ }
+ DebugPrint("^^^^^^^^^^^^xxxxxxxxxxxx>");
+ }
+ private void DeleteSelection(int start, int length, char keychar)
+ {
+ SetSelection(start, length);
+ DeleteCurrentSelection(keychar);
+ }
+ private void DeleteEndBetweenLinks(char keychar)
+ {
+ _ProcessingKeys++;
+ DebugSelection("DeleteEndBetweenLinks");
+ int sstart = SelectionStart;
+ int slen = SelectionLength + 1 - 7;
+ // This puts a space at the link that starts at the end of the selection
+ InsertCharBetweenLinks(_RangeEndLink.NextLink);
+ //_AdjustingSelection = true;
+ DeleteSelection(sstart, slen, keychar);
+ //_AdjustingSelection = false;
+ _ProcessingKeys--;
+ }
+ private void DeleteStartBetweenLinks(char keychar)
+ {
+ _ProcessingKeys++;
+ DebugSelection("DeleteStartBetweenLinks");
+ int slen = SelectionLength + 8;
+ int sstart = SelectionStart - 7;
+ //LinkLocation ll = FindBetweenLinks(SelectionStart);
+ InsertCharBetweenLinks(_RangeStartLink);
+ DeleteSelection(sstart, slen, keychar);
+ _ProcessingKeys--;
+ }
+ private void DeleteFromStartOfBox(char keychar)
+ {
+ _ProcessingKeys++;
+ DebugSelection("DeleteFromStartOfBox");
+ int slen = SelectionLength;
+ SetSelection(0, 0);
+ //RtbSendKeys(" "); // open for space between links which separates END/START tokens
+ SelectedText = " ";
+ DeleteSelection(0, slen + 8, keychar);
+ _ProcessingKeys--;
+ }
+ private void DeleteFromStartOfBoxEndBetweenLinks(char keychar)
+ {
+ _ProcessingKeys++;
+ DebugSelection("DeleteFromStartOfBoxEndBetweenLinks");
+ // This puts a space at the link that starts at the end of the selection
+ int sLen = SelectionStart + SelectionLength - 7 + 2;// -7 for 0) SetSelection(SelectionStart, newend - SelectionStart);
+ break;
+ default:
+ break;
+ }
+
+ }
private bool IsControlChar = false;
+ private bool _SendBackSpace = false;
void StepRTB_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control)
@@ -625,9 +876,6 @@ namespace Volian.Controls.Library
{
case Keys.V:
string buff = Clipboard.GetText(TextDataFormat.UnicodeText);
-
- // 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);
@@ -642,11 +890,20 @@ namespace Volian.Controls.Library
switch (e.KeyCode)
{
case Keys.Left:
+ if (e.Shift)
+ {
+ int newstart = FindStart(); // find start of link ending on.
+ int len = SelectionLength + SelectionStart - newstart;
+ SetSelection(newstart, len);
+ e.Handled = true;
+ return;
+ }
if (e.Control || SelectionStart == 0)
{
StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlLeft : E_ArrowKeys.Left);
e.Handled = true;
}
+ HandleSelectionChange();
break;
case Keys.Up:
int ln = GetLineFromCharIndex(SelectionStart);
@@ -655,13 +912,42 @@ namespace Volian.Controls.Library
StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlUp : E_ArrowKeys.Up);
e.Handled = true;
}
+ // if shift-up & at selection had a link, handle this as special case.
+ if (e.Shift && SelectionLength>0)
+ {
+ RangeStatus rs = FindRangeStatus();
+ if (rs != RangeStatus.NoContainedLinks)
+ {
+ int curend = SelectionStart + SelectionLength;
+ SelectionLength = 0;
+ RtbSendKeys("{Up}");
+ Application.DoEvents();
+ Select(SelectionStart, curend - SelectionStart);
+ e.Handled = true;
+ }
+ }
+ else
+ HandleSelectionChange();
break;
case Keys.Right:
+ // If at beginning of box that starts with a link, don't worry about shift or not,
+ // because selection is first character or link without any other selection. Don't
+ // need to write code to handle link at beginning of box in Shift Right code because
+ // it's handled in HandleSelectionChange.
+ if (e.Shift && ((SelectionStart > 0) || (SelectionStart==0 && _LinkLocations.Count>0 && _LinkLocations[0].Start!=7)))
+ {
+ int newlen = FindEnd();
+ int len = SelectionLength + newlen;
+ SetSelection(SelectionStart, len);
+ e.Handled = true;
+ return;
+ }
if (e.Control || SelectionStart == this.Text.Length)
{
StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlRight : E_ArrowKeys.Right);
e.Handled = true;
}
+ HandleSelectionChange();
break;
case Keys.Down:
int l = GetLineFromCharIndex(SelectionStart);
@@ -670,10 +956,23 @@ namespace Volian.Controls.Library
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);
+ HandleSelectionChange();
+ e.Handled = true;
+ return;
+ }
+ if (!e.Shift)HandleSelectionChange();
+ // if shift-down & on link at beginning of box - do special processing (regular processing
+ // didn't handle it correctly.
+ if (e.Shift && lastLine > 0 && SelectionStart==0 && _LinkLocations.Count>0 && _LinkLocations[0].Start==7)
+ {
+ Point cpos = GetPositionFromCharIndex(SelectionStart);
+ int addon = ClientRectangle.Height / (lastLine + 1);
+ cpos.Y = cpos.Y + addon;
+ int selend = GetCharIndexFromPosition(cpos);
+ Select(7, selend-7);
e.Handled = true;
}
break;
@@ -686,46 +985,47 @@ namespace Volian.Controls.Library
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)
+ if (SelectionLength == 0)
{
- DeleteLink();
- e.Handled = true;
- }
- else if (SelectedRtf.IndexOf(@"\protect") > -1)
- {
- // unprotect and then delete text & links.
- DeleteTextAndLink();
- e.Handled = true;
+ foreach (LinkLocation lls in _LinkLocations)
+ {
+ if (SelectionStart >= lls.Start - 7 && SelectionStart < lls.End)
+ {
+ SetSelection(lls);// Select the link to the right
+ HandleDeleteKeyWithSelectedText(e, '\x0');
+ e.SuppressKeyPress = true;
+ return;
+ }
+ }
+ if (SelectionStart != TextLength)
+ {
+ SelectionStart++;// A Delete can be accomplished with a right arrow followed by a backspace.
+ RtbSendKeys("{BS}"); // This is done due to a glitch in the RichTextBox that sometimes causes a beep rather than a delete
+ e.SuppressKeyPress = true;
+ }
}
+ else
+ HandleDeleteKeyWithSelectedText(e, '\x0');
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)
+ if (_SendBackSpace)
{
- int tmpss = SelectionStart;
- Select(SelectionStart - 1, 0); // see if previous char is protected
- if (SelectionProtected)
+ _SendBackSpace = false;
+ return;
+ }
+ _CheckSelection = true;
+ if (SelectionLength == 0)
+ {
+ foreach (LinkLocation lls in _LinkLocations)
{
- SelectLinkFromIndex(SelectionStart);
- DeleteLink();
- e.Handled = true;
+ if (SelectionStart > lls.Start - 7 && SelectionStart <= lls.End)
+ {
+ SetSelection(lls);
+ 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;
}
+ if (SelectionLength > 0) HandleDeleteKeyWithSelectedText(e, '\x0');
break;
}
}
@@ -746,43 +1046,6 @@ namespace Volian.Controls.Library
Point cp = PointToClient(Cursor.Position);
_MyStepItem.MyStepPanel.CursorMovement(this, cp, key);
}
- private void DeleteTextAndLink()
- {
- int start = SelectionStart;
- int len = SelectionLength;
- for (int i = start; i < len + start; i++)
- {
- Select(i, 0);
- if (SelectionProtected)
- {
- SelectLinkFromIndex(i);
- SelectionProtected = false;
- }
- }
- Select(start, len);
- SelectedRtf = "";
- }
- void StepRTB_KeyUp(object sender, KeyEventArgs e)
- {
- switch (e.KeyCode)
- {
- case Keys.Left:
- case Keys.Up:
- case Keys.Down:
- case Keys.Right:
- if (!SelectionProtected)
- MyLinkText = null;
- else
- {
- if (e.KeyCode == Keys.Right)
- SelectLink();
- else
- SelectLinkFromIndex(SelectionStart);
- e.Handled = true;
- }
- break;
- }
- }
private void StepRTB_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (!ReadOnly)
@@ -790,60 +1053,327 @@ namespace Volian.Controls.Library
// add the character with its font depending on the char....
if (!IsControlChar)
{
- if (e.KeyChar == '\b') return; // return on backspace otherwise, get a block char
+ bool done = false;
+ string strpressed = null;
if (e.KeyChar == '-')
- AddSymbol(@"\u8209?");
+ strpressed = GetAddSymbolText(@"\u8209?");
else if (e.KeyChar == '{')
- AddRtf("\\{");
+ strpressed = "\\{";
else if (e.KeyChar == '}')
- AddRtf("\\}");
- else if (e.KeyChar == '[')
- AddRtf(@"\b ");
+ strpressed = "\\}";
else
- return; // AddRtf(e.KeyChar.ToString());
- e.Handled = true; // flag that it's been handled, otherwise, will get 2 chars.
+ strpressed = e.KeyChar.ToString();
+ if (e.KeyChar >= ' ')
+ {
+ LinkLocation ll = FindBetweenLinks();
+ if (ll != null && SelectionLength == 0) // SelectionLength = 0 means insert
+ {
+ InsertCharBetweenLinks(ll, e.KeyChar);
+ e.Handled = true;
+ }
+ else if (SelectionLength != 0)
+ {
+ HandleDeleteKeyWithSelectedText(new KeyEventArgs(Keys.None), e.KeyChar);
+ e.Handled = true;
+ }
+ }
+ if (!done)
+ {
+ if (e.KeyChar == '-')
+ AddSymbol(@"\u8209?");
+ else if (e.KeyChar == '{')
+ AddRtf(@"\{");
+ else if (e.KeyChar == '}')
+ AddRtf(@"\}");
+ else
+ return;
+ e.Handled = true; // flag that it's been handled, otherwise, will get 2 chars.
+ }
}
IsControlChar = false;
}
}
+ private void RtbSendKeys(string keys)
+ {
+ Focus();
+ SendKeys.Send(keys); // With .Net Framework 3.0 this can be replaced with EditingCommands
+ // http://msdn.microsoft.com/en-us/library/ms771634.aspx
+ }
+
+ private void DoDeleteEndBetweenLinks()
+ {
+ DebugSelection("Beginning");
+ int sstart = SelectionStart;
+ RtbSendKeys("{RIGHT} "); // open for space between links which separates END/START tokens
+ SetSelection(sstart, SelectionStart - sstart - 1); // 1 is accounting for typed space
+ DebugSelection("SetSelection");
+ RtbSendKeys("{DELETE}"); // deletes text including link
+ RtbSendKeys("{RIGHT}{BS}"); // deletes space that was added
+ }
+ private void DoDeleteStartBetweenLinks()
+ {
+ int slen = SelectionLength;
+ RtbSendKeys("{LEFT} ");
+ SetSelection(SelectionStart, slen + 7);
+ RtbSendKeys("{DELETE}");
+ RtbSendKeys("{BS}");
+ }
#endregion
#region LinkSelectionAndHandling
private void SelectLinkFromPoint()
{
Point cp = PointToClient(_savcurpos);
int index = GetCharIndexFromPosition(cp);
- SelectLinkFromIndex(index);
+ SelectLink(index, 0);
}
- private void SelectLinkFromIndex(int index)
+ private void SelectLink(int index, int len)
{
- // Find beginning of the link until no longer protected or beginning of string.
- int iMin = index;
- Select(index, 0);
- while (iMin > 0 && SelectionProtected)
- Select(--iMin, 0);
- Select(iMin + 1, 0);
-
- // Now select the entire link
- SelectLink();
+ FindLink(index, len);
+ if (SelectedText.IndexOf(@"[END>") > 0) MyLinkText = SelectedText.Substring(0, SelectedText.IndexOf(@"[END>"));
+ else MyLinkText = SelectedText;
}
- private void SelectLink()
+ public bool IsSelectionLinked(int index, int len)
{
- int index = SelectionStart;
- int iMax = index;
- Select(index, 0);
- while (iMax < TextLength && SelectionProtected)
- Select(++iMax, 0);
- if (index == 0) index++; // account for link at beginning of box
- Select(index - 1, SelectionStart + 1 - index);
- MyLinkText = SelectedText;
+ if (_LinkLocations == null)return false;
+ int sel = index;
+ int selLength = len;
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ if (sel >= ll.Start && sel < ll.Start + ll.Length + 7) return true;
+ }
+ return false;
}
+ private int FindLink(int startIndex, int len)
+ {
+ int sel = startIndex;
+ int selLength = len;
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ // add 7 to include the '= ll.Start && sel <= ll.Start + ll.Length)
+ {
+ SetSelection(ll.Start, ll.Length);
+ if (SelectionLength == 0)
+ {
+ // try adding 7 to locEnd
+ SetSelection(ll.Start, ll.Length + 7);
+ }
+ Console.WriteLine(string.Format("\nFindLink Start = {0}, Length = {1}\n", SelectionStart, SelectionLength));
+ return SelectionStart;
+ }
+ }
+ return SelectionStart;
+ }
+
private void DeleteLink()
{
- SelectionProtected = false;
SelectedText = "";
MyLinkText = null;
+ FindAllLinks();
+ }
+ #endregion
+ #endregion
+ #region SelectionStack
+ Stack _SelectionStack = new Stack();
+ public void PushSelection()
+ {
+ _SelectionStack.Push(new SelectionData(this));
+ }
+ public void PopSelection()
+ {
+ SelectionData selection = _SelectionStack.Pop();
+ Select(selection.SelectionStart, selection.SelectionLength);
+ }
+ public class SelectionData
+ {
+ int _SelectionStart;
+ public int SelectionStart
+ {
+ get { return _SelectionStart; }
+ set { _SelectionStart = value; }
+ }
+ int _SelectionLength;
+ public int SelectionLength
+ {
+ get { return _SelectionLength; }
+ set { _SelectionLength = value; }
+ }
+ public SelectionData(RichTextBox richTextBox)
+ {
+ _SelectionStart = richTextBox.SelectionStart;
+ _SelectionLength = richTextBox.SelectionLength;
+ }
+ }
+ #endregion
+ #region Link Support
+ int _ProcessingKeys = 0;
+
+ List _LinkLocations;
+ public List LinkLocations
+ {
+ get { return _LinkLocations; }
+ }
+ private int _FALLevel = 0;
+ private bool _IdentifyingLinks = false;
+ public void FindAllLinks()
+ {
+ if (_IdentifyingLinks || _ProcessingDelete) return;
+ //DebugPrint("FAL{0}vvvvvvvvvvvvvvvvvvvvvvvvv>>", ++_FALLevel);
+ _AdjustingSelection = true;
+ PushSelection();
+ FindLinks();
+ IdentifyLinks();
+ PopSelection();
+ LinkLocation llx = FindLinkLocation();
+ if (_CheckSelection)
+ {
+ if (llx != null) SetSelection(llx.End, 0);
+ _CheckSelection = false;
+ }
+ _AdjustingSelection = false;
+ if (!_ProcessingDelete)
+ OnLinkLocationChanged(this, new EventArgs());
+ //DebugPrint("FAL{0}^^^^^^^^^^^^^^^^^^^^^^^^^>>", _FALLevel--);
+
+ }
+ private void FindLinks()
+ {
+ string str = Text;
+ _LinkLocations = new List();
+ MatchCollection matches = Regex.Matches(str, "");
+ MatchCollection matchesRtf = Regex.Matches(Rtf, "");
+ LinkLocation thisLink = null;
+ for (int i = 0; i < matches.Count; i++) //each (Match match in matches)
+ {
+ Match match = matches[i];
+ Match matchrtf = matchesRtf[i];
+ thisLink = new LinkLocation(match.Index + 7, // If the [END> is immediately followed by ");
+ foreach (LinkLocation ll in _LinkLocations)
+ if (ll.Start == start && ll.StartsBetween)
+ return ll;
+ return null;
+ }
+ private LinkLocation FindLinkSelected()
+ {
+ DebugPrint("FL----------------Selected>");
+ if (_LinkLocations == null) return null;
+ foreach (LinkLocation ll in _LinkLocations)
+ if (ll.Start == SelectionStart && ll.Length == SelectionLength) return ll;
+ return null;
+ }
+ private LinkLocation FindLinkLocation()
+ {
+ return FindLinkLocation(SelectionStart);
+ }
+ private LinkLocation FindLinkLocation(int sel)
+ {
+ DebugPrint("FL----------------Location>");
+ if (_LinkLocations == null) return null;
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ // Moving right:
+ // if less than, allows stopping between two links
+ if (ll.Start < sel && ll.End > sel)
+ {
+ DebugPrint("Greater Than {0} {1} {2}", sel, ll.Start, ll.End);
+ return ll;
+ }
+ // if less than or equal, does not stop between two links
+ if ((!ll.StartsBetween) && ll.Start <= sel && ll.End > sel)
+ {
+ DebugPrint("Greater Than or Equal {0} {1} {2}", sel, ll.Start, ll.End);
+ return ll;
+ }
+ }
+ return null;
+ }
+ private int FindStart()
+ {
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ if (SelectionStart == ll.End) return ll.Start;
+ if (SelectionStart == ll.Start)
+ {
+ if (ll.Start == 7) return 7;
+ return ll.Start - 8;
+ }
+ }
+ if (SelectionStart > 0) return SelectionStart - 1;
+ return 0;
+ }
+ private int FindEnd()
+ {
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ if (SelectionStart + SelectionLength + 7 == ll.Start) return ll.Length + 7;
+ // this is for in-between links
+ if (SelectionStart + SelectionLength == ll.Start) return ll.Length;
+ }
+ if (SelectionStart + SelectionLength < TextLength) return 1;
+ return 0;
+ }
+ private int FindEndDown()
+ {
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ if (SelectionStart + SelectionLength >= ll.Start && SelectionStart + SelectionLength <= ll.End) return ll.End;
+ }
+ return 0;
+ }
+ private int FindStartUp()
+ {
+ DebugPrint("FINDSTARTUP Start = {0}, Len = {1}", SelectionStart, SelectionLength);
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ DebugPrint("FINDSTARTUP link start = {0}, link end = {1}", ll.Start, ll.End);
+ if ((SelectionStart >= ll.Start) && (SelectionStart <= ll.End))
+ {
+ DebugPrint("FINDSTARTUP - in link start = {0}, end = {1}", ll.Start, ll.End);
+ return ll.Start;
+ }
+ }
+ DebugPrint("FINDSTARTUP - Not in link");
+ return -1;
+ }
+ public void SetSelection(LinkLocation ll)
+ {
+ SetSelection(ll.Start, ll.Length);
+ }
+ public void SetSelection(int locStart, int locLength)
+ {
+ //Application.DoEvents(); // Not needed since SendKeys is always done last.
+ if (_IdentifyingLinks)
+ DebugPrint("SS------------------------> {0} {1}", locStart, locLength);
+ else
+ DebugPrint("SS========================> {0} {1}", locStart, locLength);
+ Select(locStart, locLength);
}
-#endregion
#endregion
#region FontAndStylesSupport
private void ToggleFontStyle(FontStyle style, bool att_on)
@@ -937,15 +1467,147 @@ namespace Volian.Controls.Library
return reply;
}
#endregion
+ #region EnumsSelectionRange
+ private enum StartStatus : int
+ {
+ Before = 100,
+ Between = 200,
+ StartLink = 300,
+ StartBox = 400
+ };
+ private enum EndStatus : int
+ {
+ After = 1,
+ Between = 2,
+ EndLink = 3,
+ EndBox = 4,
+ StartLink = 5
+ };
+ public enum RangeStatus : int
+ {
+ NoContainedLinks = 0,
+ Before_After = StartStatus.Before + EndStatus.After,
+ Before_Between = StartStatus.Before + EndStatus.Between,
+ Before_EndLink = StartStatus.Before + EndStatus.EndLink,
+ Before_EndBox = StartStatus.Before + EndStatus.EndBox,
+ Before_StartLink = StartStatus.Before + EndStatus.StartLink,
+ Between_After = StartStatus.Between + EndStatus.After,
+ Between_Between = StartStatus.Between + EndStatus.Between,
+ Between_EndLink = StartStatus.Between + EndStatus.EndLink,
+ Between_EndBox = StartStatus.Between + EndStatus.EndBox,
+ Between_StartLink = StartStatus.Between + EndStatus.StartLink,
+ StartLink_After = StartStatus.StartLink + EndStatus.After,
+ StartLink_Between = StartStatus.StartLink + EndStatus.Between,
+ StartLink_EndLink = StartStatus.StartLink + EndStatus.EndLink,
+ StartLink_EndBox = StartStatus.StartLink + EndStatus.EndBox,
+ StartLink_StartLink = StartStatus.StartLink + EndStatus.StartLink,
+ StartBox_After = StartStatus.StartBox + EndStatus.After,
+ StartBox_Between = StartStatus.StartBox + EndStatus.Between,
+ StartBox_EndLink = StartStatus.StartBox + EndStatus.EndLink,
+ StartBox_EndBox = StartStatus.StartBox + EndStatus.EndBox,
+ StartBox_StartLink = StartStatus.StartBox + EndStatus.StartLink
+ };
+ private RangeStatus _RTBRangeStatus;
+ public RangeStatus RTBRangeStatus
+ {
+ get { return _RTBRangeStatus; }
+ set
+ {
+ _RTBRangeStatus = value;
+ if (!_ProcessingDelete) OnRTBRangeStatusChanged(this, new EventArgs());
+ }
+ }
+ private LinkLocation _RangeStartLink = null;
+ private LinkLocation _RangeEndLink = null;
+ private RangeStatus FindRangeStatus()
+ {
+ _RangeStartLink = null;
+ _RangeEndLink = null;
+ if (_LinkLocations == null || _LinkLocations.Count == 0)
+ {
+ return RTBRangeStatus = RangeStatus.NoContainedLinks;
+ }
+ LinkLocation foundLink = null;
+ int start = SelectionStart;
+ int end = start + SelectionLength;
+
+ foreach (LinkLocation ll in _LinkLocations)
+ {
+ if (foundLink == null && ((ll.Start >= start && ll.Start < end) || (ll.End >= start && ll.End < end)))
+ foundLink = ll;
+ if (_RangeStartLink == null && start >= ll.Start - 7 && start < ll.End)
+ _RangeStartLink = ll;
+ if (_RangeEndLink == null && end >= ll.Start && end <= ll.End)
+ _RangeEndLink = ll;
+ }
+ DebugPrint("SelectionStart {0}, SelectionEnd {1}, TextLength {2}",
+ SelectionStart, SelectionStart + SelectionLength,
+ TextLength);
+ if (_RangeStartLink != null)
+ _RangeStartLink.Show("startLink");
+ if (_RangeEndLink != null)
+ _RangeEndLink.Show("endLink");
+ if (foundLink != null)
+ foundLink.Show("foundLink");
+
+ if (foundLink == null)
+ return RTBRangeStatus = RangeStatus.NoContainedLinks;
+
+ StartStatus myStartStatus = StartStatus.Before;
+ EndStatus myEndStatus = EndStatus.After;
+ if (_RangeStartLink != null)
+ {
+ if (_RangeStartLink.Start == 7)
+ myStartStatus = StartStatus.StartBox;
+ else if (_RangeStartLink.StartsBetween)
+ myStartStatus = StartStatus.Between;
+ else
+ myStartStatus = StartStatus.StartLink;
+ }
+ if (_RangeEndLink != null)
+ {
+ if (_RangeEndLink.End == TextLength)
+ myEndStatus = EndStatus.EndBox;
+ else if (_RangeEndLink.NextStart == _RangeEndLink.End)
+ myEndStatus = EndStatus.Between;
+ else if (end == _RangeEndLink.Start)
+ myEndStatus = EndStatus.StartLink; // Should not happen because of code in HandleSelectionChange
+ else //if (end == endLink.End)
+ myEndStatus = EndStatus.EndLink;
+ }
+ return RTBRangeStatus = (RangeStatus)((int)myStartStatus + (int)myEndStatus);
+ }
+ #endregion
+ #region Debug
+ private bool _ShowDebug = false;
+ public bool ShowDebug
+ {
+ get { return _ShowDebug; }
+ set { _ShowDebug = value; }
+ }
+ private void DebugPrint(string where, string format, params object[] myParams)
+ {
+ DebugPrint(where + string.Format(format, myParams));
+ }
+ private void DebugPrint(string format, params object[] myParams)
+ {
+ if (_ShowDebug)
+ Console.WriteLine(format, myParams);
+ }
+ private void DebugSelection(string where)
+ {
+ DebugPrint(where, ": {0} {1} '{2}'", SelectionStart, SelectionLength, SelectedText);
+ }
+ #endregion
}
#region LinkLocation Class
- internal class LinkLocation
+ public class LinkLocation
{
- private int _Position;
- public int Position
+ private int _Start;
+ public int Start
{
- get { return _Position; }
- set { _Position = value; }
+ get { return _Start; }
+ set { _Start = value; }
}
private int _Length;
public int Length
@@ -953,12 +1615,86 @@ namespace Volian.Controls.Library
get { return _Length; }
set { _Length = value; }
}
-
- public LinkLocation(int position, int length)
+ public int End
{
- _Position = position;
- _Length = length;
+ get { return _Length + _Start; }
}
+ private int _StartRtf;
+ public int StartRtf
+ {
+ get { return _StartRtf; }
+ set { _StartRtf = value; }
+ }
+ private int _LengthRtf;
+ public int LengthRtf
+ {
+ get { return _LengthRtf; }
+ set { _LengthRtf = value; }
+ }
+ public int EndRtf
+ {
+ get { return _LengthRtf + _StartRtf; }
+ }
+ private string _Text;
+ public string Text
+ {
+ get { return _Text; }
+ set { _Text = value; }
+ }
+ private LinkLocation _PreviousLink = null;
+ public LinkLocation PreviousLink
+ {
+ get { return _PreviousLink; }
+ set
+ {
+ _PreviousLink = value;
+ value.NextLink = this;
+ }
+ }
+ private LinkLocation _NextLink = null;
+ public LinkLocation NextLink
+ {
+ get { return _NextLink; }
+ set { _NextLink = value; }
+ }
+ public int PreviousEnd
+ {
+ get { return PreviousLink == null ? -1 : PreviousLink.End; }
+ }
+ public bool StartsBetween
+ {
+ get { return PreviousEnd == Start; }
+ }
+ public int NextStart
+ {
+ get { return NextLink == null ? -1 : NextLink.Start; }
+ }
+ public bool EndsBetween
+ {
+ get { return NextStart == End; }
+ }
+ public LinkLocation(int start, int length, string text, int startRtf, int lengthRtf, LinkLocation previousLink)
+ {
+ _Start = start;
+ _Length = length;
+ _Text = text;
+ _StartRtf = startRtf;
+ _LengthRtf = lengthRtf;
+ if (previousLink != null) PreviousLink = previousLink;
+ }
+ public override string ToString()
+ {
+ return (string.Format("{0}, {1}", Start, End));
+ }
+ public void Show(string str)
+ {
+ if (PreviousLink != null)
+ Console.WriteLine("LinkLocation: {0}.PreviousLink {1}", str, PreviousLink);
+ Console.WriteLine("LinkLocation: {0} {1}", str, this);
+ if (NextLink != null)
+ Console.WriteLine("LinkLocation: {0}.NextLink {1}", str, NextLink);
+ }
+
}
#endregion
}