using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using VEPROMS.CSLA.Library; namespace Volian.Controls.Library { public delegate void StepRTBEvent(object sender, EventArgs args); public partial class StepRTB : RichTextBox , IStepRTB { #region Properties and Variables // use newer rich text box.... //[DllImport("kernel32.dll", CharSet = CharSet.Auto)] //static extern IntPtr LoadLibrary(string lpFileName); //protected override CreateParams CreateParams //{ // get // { // CreateParams prams = base.CreateParams; // if (LoadLibrary("msftedit.dll") != IntPtr.Zero) // { // //prams.ExStyle |= 0x020; // transparent // prams.ClassName = "RICHEDIT50W"; // } // return prams; // } //} private StepItem _MyStepItem; public StepItem MyStepItem { get { return _MyStepItem; } set { _MyStepItem = value; } } private bool _IsDirty = false; //private bool _InitializingRTB; private IContainer _Container = null; private string _MyClassName=string.Empty; public string MyClassName { get { if (_MyClassName == string.Empty)_MyClassName = CreateParams.ClassName; return _MyClassName; } set { _MyClassName = value; } } private E_EditPrintMode _epMode = E_EditPrintMode.Edit; public E_EditPrintMode EpMode { get { return _epMode; } set { _epMode = value; } } private E_ViewMode _vwMode = E_ViewMode.Edit; public E_ViewMode VwMode { get { return _vwMode; } set { _vwMode = value; } } private VE_Font _MyStyleFont; public VE_Font MyStyleFont { get { return _origDisplayText.TextFont; } } private ItemInfo _MyItemInfo; public ItemInfo MyItemInfo { get { return _MyItemInfo; } set { _MyItemInfo = value; if (value != null) { //_InitializingRTB = true; DisplayText vlntxt = new DisplayText(_MyItemInfo, EpMode, VwMode); _origDisplayText = vlntxt; #if(DEBUG) // Use Times New Roman for Debugging Font = new Font("Times New Roman", 14, FontStyle.Regular); //Font = _origDisplayText.TextFont.WindowsFont; #else Font = _origDisplayText.TextFont.WindowsFont; #endif Text = ""; // Initialize text before add text //if (_MyStepItem.MyID == 168) // IMPORTANT: SetLineSpacing must be set before Link/protect, otherwise it // was confusing the 'handle' of the rtf box. RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT); //SelectionStart = 1; AddRtfText(vlntxt); //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; _IsDirty = false; ClearUndo(); _MyItemInfo.MyConfig.PropertyChanged += new PropertyChangedEventHandler(MyConfig_PropertyChanged); } } } //public EnterKeyHandler EnterKeyPressed; //protected override bool ProcessCmdKey(ref Message msg, Keys keyData) //{ // const int WM_KEYDOWN = 0x100; // const int WM_SYSKEYDOWN = 0x104; // if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN)) // { // switch (keyData) // { // case Keys.Control | Keys.V: // // check for valid data to be inserted: // return base.ProcessCmdKey(ref msg, keyData); // default: // return base.ProcessCmdKey(ref msg, keyData); // } // } // return base.ProcessCmdKey(ref msg, keyData); //} private Point ScrollPos { get { return RTBAPI.GetScrollLocation(this); } set { RTBAPI.SetScrollLocation(this, value); } } private Rectangle _ContentsRectangle; public Rectangle ContentsRectangle { get { return _ContentsRectangle; } set { _ContentsRectangle = value; AdjustSizeForContents(); } } public Size ContentsSize { get { return _ContentsRectangle.Size; } } private Size _AdjustSize; // if 0,0 puts text right next to bottom of box. public Size AdjustSize { get { return _AdjustSize; } set { _AdjustSize = value; AdjustSizeForContents(); } } public System.Windows.Forms.AutoScaleMode AutoScaleMode; private DisplayText _origDisplayText; private RichTextBox _rtbTemp = new RichTextBox(); private string _MyLinkText; public string MyLinkText { get { return _MyLinkText; } set { if (value != _MyLinkText) { _MyLinkText = value; OnLinkChanged(this, new StepPanelLinkEventArgs(_MyStepItem, _MyLinkText)); } } } #endregion #region Constructors /// /// vlnRichTextBox constructor: /// Creates a MyDisplayRTB with extra support for veproms editing/printing. /// Arguments are: /// string txtbxname - name to give box (is this needed) /// ItemInfo itm - Item for which box is created /// int x,y - starting position for box /// int iwid - width of box /// int tbindx - tab index /// E_EditPrintMode ep_mode - edit or print. /// E_ViewMode vw_mode - view or edit. /// public StepRTB() { InitializeComponent(); SetUp(); } public StepRTB(IContainer container) { container.Add(this); InitializeComponent(); _Container = container; SetUp(); } protected override void OnMouseWheel(MouseEventArgs e) { _MyStepItem.MyStepPanel.MouseWheel(e); //base.OnMouseWheel(e); } private void SetUp() { BorderStyle = System.Windows.Forms.BorderStyle.None; this.DetectUrls = true; ContentsResized += new ContentsResizedEventHandler(StepRTB_ContentsResized); 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.TextChanged += new EventHandler(StepRTB_TextChanged); this.SelectionChanged +=new EventHandler(StepRTB_SelectionChanged); } void MyConfig_PropertyChanged(object sender, PropertyChangedEventArgs e) { 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; } #endregion #region ApplicationSupport public void ToggleViewEdit() { ItemInfo tmp = MyItemInfo; MyItemInfo = null; ReadOnly = !ReadOnly; EpMode = ReadOnly ? E_EditPrintMode.Print : E_EditPrintMode.Edit; VwMode = ReadOnly ? E_ViewMode.View : E_ViewMode.Edit; Clear(); MyItemInfo = tmp; } public void InsertRO(string value, string link) { AddRtfLink(value, link); } public void InsertTran(string value, string link) { AddRtfLink(value, link); } public void InsertSymbol(string symbol) { AddSymbol(symbol); } public void SetSelectedCase(char type) { switch (type) { case 'l': SelectedText = SelectedText.ToLower(); break; case 'U': SelectedText = SelectedText.ToUpper(); break; case 'T': SelectedText = SelectedText.Substring(0, 1).ToUpper() + SelectedText.Substring(1, SelectedText.Length - 1).ToLower(); break; } } #endregion #region SaveData public void SaveText() { if (ReadOnly) return; if (!_IsDirty) return; if (_IsDirty) { bool success = _origDisplayText.Save((RichTextBox)this); if (success) { _IsDirty = false; ClearUndo(); } } } public void SaveConfig() { if (!_MyItemInfo.MyConfig.IsDirty) return; Item itm = _MyItemInfo.Get(); itm.MyContent.Config = _MyItemInfo.MyConfig.ToString(); itm.Save(); _MyItemInfo.MyConfig.IsDirty = false; } #endregion #region AddRtfTextAndStyles private void AddRtfText(DisplayText myDisplayText) { AddFontTable(); foreach (displayTextElement vte in myDisplayText.DisplayTextElementList) { if (vte.Type == E_TextElementType.Text) AddRtf(vte); else if (vte.Type == E_TextElementType.Symbol) AddSymbol(vte); 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); } } } private StringBuilder _SelectedRtfSB = new StringBuilder(); private void AddFontTable() { StringBuilder sbbeg = new StringBuilder(); StringBuilder sbend = new StringBuilder(); if (Font.Bold) { sbbeg.Append(@"\b"); sbend.Append(@"\b0"); } if (Font.Underline) { sbbeg.Append(@"\ul"); sbend.Insert(0, @"\ulnone"); } if (Font.Italic) { sbbeg.Append(@"\i"); sbend.Insert(0, @"\i0"); } _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) _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); // + @"}"); } private void AddRtf(string str) { SelectedText = str; // SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @";}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + str + @"}}"; } 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() + @"}"; } private List _LinkLocations = null; private void AddLinkLocation(string location, string url) { SelectedRtf = _SelectedRtfSB.ToString() + "}"; int linkPosition = this.TextLength; this.Text = ""; if (_LinkLocations == null) _LinkLocations = new List(); _LinkLocations.Add(new LinkLocation(linkPosition, location.Length + url.Length)); } private int _LinkPosition = -1; private int _LinkLength; private void AddRtfLink(displayLinkElement myDisplayLinkElement) { if (CreateParams.ClassName == "RICHEDIT50W") AddLink50(myDisplayLinkElement.Text, myDisplayLinkElement.Link); 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); } } public void AddRtfLink(string linkUrl, string linkValue) { //if (CreateParams.ClassName == "RICHEDIT50W") //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 this.SelectionLength = 0; } private void AddLink50(string linkValue, string linkUrl) { this.DetectUrls = false; int position = SelectionStart; // before inserttran = this.TextLength; SelectionLength = 0; SelectedRtf = string.Format(@"{{\rtf\field{{\*\fldinst{{HYPERLINK ""www.volian.com #{0}"" }}}}{{\fldrslt{{\cf2\ul {1}}}}}}}", linkUrl, linkValue); this.SelectionStart = this.TextLength; this.SelectionLength = 0; } private void AddRtfStyles() { if ((_origDisplayText.TextFont.Style & E_Style.Bold) > 0) { this.SelectAll(); RTBAPI.ToggleBold(true, this, RTBAPI.RTBSelection.SCF_SELECTION); this.Select(0, 0); } if ((_origDisplayText.TextFont.Style & E_Style.Underline) > 0) RTBAPI.ToggleUnderline(true, this, RTBAPI.RTBSelection.SCF_ALL); if ((_origDisplayText.TextFont.Style & E_Style.Italics) > 0) RTBAPI.ToggleItalic(true, this, RTBAPI.RTBSelection.SCF_ALL); } #endregion #region HeightSupport public event StepRTBEvent HeightChanged; private void OnHeightChanged(object sender, EventArgs args) { if (HeightChanged != null) HeightChanged(sender, args); } private void AdjustSizeForContents() { // The client size should match the new rectangle. // First, determine the offset Size offset = Size - ClientSize; this.Size = ContentsSize + offset + AdjustSize; OnHeightChanged(this, new EventArgs()); } public int CalculateHeight() { if (this.CreateParams.ClassName == "RICHEDIT50W") return CalculateHeight50(); else return CalculateHeight20(); } private int CalculateHeight20() { Application.DoEvents(); int yBottom = GetPositionFromCharIndex(TextLength).Y; int yTop = GetPositionFromCharIndex(0).Y; int heightFont = SelectionFont.Height; int borderSize = this.Height - this.ClientSize.Height; int heightNext = (yBottom - yTop) + heightFont + borderSize + 2;// 2 pixels - 1 at the top and 1 at the bottom if (heightNext != Height) { Height = heightNext; OnHeightChanged(this, new EventArgs()); ScrollPos = new Point(0, 0); // Scroll to make sure that the first line is displayed as the first line } return heightNext; } private int CalculateHeight50() { 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; } #endregion #region ColorSupport - Not currently used. private void SetBackGroundColor(ItemInfo itemInfo) { string backcolor = null; int type = (int)itemInfo.MyContent.Type; FormatInfo formatinfo = itemInfo.ActiveFormat; if (type == (int)E_FromType.Procedure) backcolor = formatinfo.PlantFormat.FormatData.ProcData.BackColor; else if (type == (int)E_FromType.Section) backcolor = formatinfo.PlantFormat.FormatData.SectData.BackColor; else { int typindx = (int)itemInfo.MyContent.Type - 20000; // what to do for other types rather than steps backcolor = formatinfo.PlantFormat.FormatData.StepDataList[typindx].StepLayoutData.BackColor; } BackColor = Color.FromName(backcolor); } #endregion #region EventSupport #region LinkEvents private StepPanelLinkEventArgs _MyLinkClickedEventArgs; public event StepRTBLinkEvent LinkChanged; private void OnLinkChanged(object sender, StepPanelLinkEventArgs args) { _MyLinkClickedEventArgs = args; if (LinkChanged != null) LinkChanged(sender, args); } public event StepRTBLinkEvent LinkGoTo; private void OnLinkGoTo(object sender, StepPanelLinkEventArgs args) { _MyLinkClickedEventArgs = args; if (LinkGoTo != null) LinkGoTo(sender, args); } public event StepRTBLinkEvent LinkModifyTran; private void OnLinkModifyTran(object sender, StepPanelLinkEventArgs args) { _MyLinkClickedEventArgs = args; if (LinkModifyTran != null) LinkModifyTran(sender, args); } public event StepRTBLinkEvent LinkModifyRO; private void OnLinkModifyRO(object sender, StepPanelLinkEventArgs args) { _MyLinkClickedEventArgs = args; if (LinkModifyRO != null) LinkModifyRO(sender, args); } private Point _savcurpos; private void StepRTB_LinkClicked(object sender,LinkClickedEventArgs args) { if (ReadOnly) return; _MyLinkClickedEventArgs = new StepPanelLinkEventArgs(_MyStepItem, args.LinkText); _savcurpos = Cursor.Position; SelectLinkFromPoint(); OnLinkChanged(sender, _MyLinkClickedEventArgs); } #endregion #region TextOrContents void StepRTB_TextChanged(object sender, EventArgs e) { _IsDirty = true; } void StepRTB_ContentsResized(object sender, ContentsResizedEventArgs e) { ContentsRectangle = e.NewRectangle; } #endregion #region KeyboardHandling private bool IsControlChar = false; void StepRTB_KeyDown(object sender, KeyEventArgs e) { if (e.Control) { IsControlChar = true; switch (e.KeyCode) { 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); e.Handled = true; break; case Keys.End: StepRTB_HomeEndPressed(e); e.Handled = true; break; } } switch (e.KeyCode) { 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 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; 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) { // 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 if (e.KeyChar == '-') AddSymbol(@"\u8209?"); else if (e.KeyChar == '{') AddRtf("\\{"); else if (e.KeyChar == '}') AddRtf("\\}"); else if (e.KeyChar == '[') AddRtf(@"\b "); else return; // AddRtf(e.KeyChar.ToString()); e.Handled = true; // flag that it's been handled, otherwise, will get 2 chars. } IsControlChar = false; } } #endregion #region LinkSelectionAndHandling private void SelectLinkFromPoint() { Point cp = PointToClient(_savcurpos); int index = GetCharIndexFromPosition(cp); SelectLinkFromIndex(index); } private void SelectLinkFromIndex(int index) { // 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(); } private void SelectLink() { 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; } private void DeleteLink() { SelectionProtected = false; SelectedText = ""; MyLinkText = null; } #endregion #endregion #region FontAndStylesSupport private void ToggleFontStyle(FontStyle style, bool att_on) { int start = SelectionStart; int len = SelectionLength; System.Drawing.Font currentFont; FontStyle fs; for (int i = 0; i < len; ++i) { Select(start + i, 1); currentFont = SelectionFont; fs = currentFont.Style; //add or remove style if (!att_on)fs = fs | style; else fs = fs & ~style; SelectionFont = new Font( currentFont.FontFamily, currentFont.Size, fs ); } } /// /// Returns a Font with: /// 1) The font applying to the entire selection, if none is the default font. /// 2) The font size applying to the entire selection, if none is the size of the default font. /// 3) A style containing the attributes that are common to the entire selection, default regular. /// /// public Font GetFontDetails() { //This method should handle cases that occur when multiple fonts/styles are selected int start = SelectionStart; int len = SelectionLength; int TempStart = 0; if (len <= 1) { // Return the selection or default font if (SelectionFont != null) return SelectionFont; else return Font; // should be default from format. } // Step through the selected text one char at a time // after setting defaults from first char _rtbTemp.Rtf = SelectedRtf; //Turn everything on so we can turn it off one by one FontStyle replystyle = FontStyle.Bold | FontStyle.Italic | FontStyle.Underline; // Set reply font, size and style to that of first char in selection. _rtbTemp.Select(TempStart, 1); string replyfont = _rtbTemp.SelectionFont.Name; float replyfontsize = _rtbTemp.SelectionFont.Size; replystyle = replystyle & _rtbTemp.SelectionFont.Style; // Search the rest of the selection for (int i = 1; i < len; ++i) { _rtbTemp.Select(TempStart + i, 1); // Check reply for different style replystyle = replystyle & _rtbTemp.SelectionFont.Style; // Check font if (replyfont != _rtbTemp.SelectionFont.FontFamily.Name) replyfont = ""; // Check font size if (replyfontsize != _rtbTemp.SelectionFont.Size) replyfontsize = (float)0.0; } // Now set font and size if more than one font or font size was selected if (replyfont == "") replyfont = _rtbTemp.Font.FontFamily.Name; if (replyfontsize == 0.0) replyfontsize = _rtbTemp.Font.Size; // generate reply font Font reply = new Font(replyfont, replyfontsize, replystyle); return reply; } #endregion } #region LinkLocation Class internal class LinkLocation { private int _Position; public int Position { get { return _Position; } set { _Position = value; } } private int _Length; public int Length { get { return _Length; } set { _Length = value; } } public LinkLocation(int position, int length) { _Position = position; _Length = length; } } #endregion }