720 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			720 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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 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;
 | |
| 					Font = _origDisplayText.TextFont.WindowsFont;
 | |
| 					Text = ""; // Initialize text before add text
 | |
| 					AddRtfText(vlntxt);
 | |
| 					//AddRtfStyles();
 | |
| 					ReadOnly = !(EpMode == E_EditPrintMode.Edit && VwMode == E_ViewMode.Edit);
 | |
| 					RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT);
 | |
| 					//_InitializingRTB = false;
 | |
| 					_IsDirty = false;
 | |
| 					ClearUndo();
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		//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
 | |
| 		/// <summary>
 | |
| 		///     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.
 | |
| 		/// </summary>	
 | |
| 		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(DisplayRTB_SelectionChanged);
 | |
| 		}
 | |
| 
 | |
| 		private void StepRTB_Click(object sender, EventArgs e)
 | |
| 		{
 | |
| 			if (ReadOnly) return;
 | |
| 
 | |
| 			if (!SelectionProtected)
 | |
| 			{
 | |
| 				MyLinkText = null;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		void StepRTB_SelectionChanged(object sender, EventArgs e)
 | |
| 		{
 | |
| 			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;
 | |
| 			bool success = _origDisplayText.Save((RichTextBox)this);
 | |
| 			if (success)
 | |
| 			{
 | |
| 				_IsDirty = false;
 | |
| 				ClearUndo();
 | |
| 			}
 | |
| 		}
 | |
| 		#endregion
 | |
| 		#region AddRtfTextAndStyles
 | |
| 		private void AddRtfText(DisplayText myDisplayText)
 | |
| 		{
 | |
| 			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);
 | |
| 			}
 | |
| 		}
 | |
| 		private void AddRtf(displayTextElement myDisplayTextElement)
 | |
| 		{
 | |
| 			SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 "+this.Font.FontFamily.Name+@";}}\f0\fs" + this.Font.SizeInPoints*2 + " " + myDisplayTextElement.Text + @"}}";
 | |
| 		}
 | |
| 		private void AddRtf(string str)
 | |
| 		{
 | |
| 			SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @";}}\f0\fs" + this.Font.SizeInPoints * 2 + " " + str + @"}}";
 | |
| 		}
 | |
| 		private void AddSymbol(displayTextElement myDisplayTextElement)
 | |
| 		{
 | |
| 			SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + " " + myDisplayTextElement.Text + @"}";
 | |
| 		}
 | |
| 		private void AddSymbol(string str)
 | |
| 		{
 | |
| 			SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + " " + /* ConvertUnicodeChar(str) */ str + @"}";
 | |
| 		}
 | |
| 		private void AddRtfLink(displayLinkElement myDisplayLinkElement)
 | |
| 		{
 | |
| 			if (CreateParams.ClassName == "RICHEDIT50W")
 | |
| 
 | |
| 				AddLink50(myDisplayLinkElement.Text, myDisplayLinkElement.Link);
 | |
| 			else
 | |
| 
 | |
| 				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}";
 | |
| 			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;
 | |
| 			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.Modifiers == Keys.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));
 | |
| 						break;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				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)
 | |
| 						{
 | |
| 							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 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
 | |
| 						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
 | |
| 					);
 | |
| 			}
 | |
| 		}
 | |
| 		/// <summary>
 | |
| 		///     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.
 | |
| 		/// </summary>		
 | |
| 		/// 
 | |
| 		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
 | |
| 	}
 | |
| }
 |