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 DisplayRTBEvent(object sender, EventArgs args); public partial class DisplayRTB : RichTextBox { #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 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 _MyItem; public ItemInfo MyItem { get { return _MyItem; } set { _MyItem = value; if (value != null) { DisplayText vlntxt = new DisplayText(_MyItem, EpMode, VwMode); _origVlnText = vlntxt; // TODO: RHM20071115 this.Font = _origVlnText.TextFont.WindowsFont; AddRtfText(vlntxt); ReadOnly = !(EpMode == E_EditPrintMode.EDIT && VwMode == E_ViewMode.EDIT); RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT); } } } //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 _origVlnText; private RichTextBox _rtbTemp = new RichTextBox(); private string _eLinkText; #endregion #region HeightSupport public event DisplayRTBEvent HeightChanged; private void OnHeightChanged(object sender, EventArgs args) { if (HeightChanged != null) HeightChanged(sender, args); } private void AdjustSizeForContents() { //Console.WriteLine("Size {0} Client {1} New {2}", Size, ClientRectangle, ContentsRectangle); // I want the client size to match the new rectangle. // First I need to determine the offset Size offset = Size - ClientSize; this.Size = ContentsSize + offset + AdjustSize; OnHeightChanged(this, new EventArgs()); } #endregion #region Constructors /// /// vlnRichTextBox constructor: /// Creates a RichTextBox 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 DisplayRTB(string txtbxname, ItemInfo itemInfo, int x, int y, int iwid, int tbindx, E_EditPrintMode epMode, E_ViewMode vwMode) { try { EpMode = epMode; VwMode = vwMode; DisplayText vlntxt = new DisplayText(itemInfo, epMode, vwMode); _origVlnText = vlntxt; InitializeComponent(); Location = new System.Drawing.Point(x, y); Name = txtbxname; DetectUrls = false; // TODO: RHM20071115 Font = _origVlnText.TextFont.WindowsFont; ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None; Width = iwid; ContentsResized += new ContentsResizedEventHandler(vlnRichTextBox_ContentsResized); AddRtfText(vlntxt); //ContextMenuStrip = contextMenuStrip; ReadOnly = !(epMode == E_EditPrintMode.EDIT && vwMode == E_ViewMode.EDIT); RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT); this.LinkClicked += new LinkClickedEventHandler(onLinkClicked); this.KeyPress += new KeyPressEventHandler(onKeyPress); this.KeyDown += new KeyEventHandler(onKeyDown); this.Leave += new EventHandler(DisplayRTB_Leave); } catch (Exception ex) { Console.WriteLine("Error in creating vlnRichTextBox: " + ex.Message); } } public DisplayRTB() { InitializeComponent(); SetUp(); } public DisplayRTB(IContainer container) { container.Add(this); InitializeComponent(); _Container = container; SetUp(); } private void SetUp() { BorderStyle = System.Windows.Forms.BorderStyle.None; this.DetectUrls = true; ContextMenuStrip = contextMenuStrip; ContentsResized += new ContentsResizedEventHandler(vlnRichTextBox_ContentsResized); this.LinkClicked += new LinkClickedEventHandler(onLinkClicked); this.KeyPress += new KeyPressEventHandler(onKeyPress); this.KeyDown += new KeyEventHandler(onKeyDown); this.Leave += new EventHandler(DisplayRTB_Leave); } #endregion #region ApplicationSupport public void ToggleViewEdit() { ItemInfo tmp = MyItem; MyItem = null; ReadOnly = !ReadOnly; EpMode = ReadOnly?E_EditPrintMode.PRINT:E_EditPrintMode.EDIT; VwMode = ReadOnly?E_ViewMode.VIEW:E_ViewMode.EDIT; Clear(); MyItem = 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); } #endregion #region SaveData public void Save() { // TODO: RHM20071115 bool success = _origVlnText.Save((RichTextBox) this); } #endregion #region AddRtfText private void AddRtfText(DisplayText vlntext) { foreach (displayTextElement vte in vlntext.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 vte) { SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 "+this.Font.FontFamily.Name+@";}}\f0\fs" + this.Font.SizeInPoints*2 + " " + vte.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 vte) { SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset0 Arial Unicode MS;}}\f0\fs" + this.Font.SizeInPoints * 2 + " " + vte.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 vte) { if (CreateParams.ClassName == "RICHEDIT50W") AddLink50(vte.Text, vte.Link); else AddLink20(vte.Text, vte.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 = this.TextLength; SelectionLength = 0; SelectedRtf = @"{\rtf1\ansi " + linkValue + @"\v " + linkUrl + @"\v0}"; Select(position, linkValue.Length + linkUrl.Length + 1); // 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 = 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; } #endregion #region CalculateHeight 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 private LinkClickedEventArgs _LinkClickedEventArgs; public event DisplayRTBLinkEvent LinkGoTo; private void OnLinkGoTo(object sender, LinkClickedEventArgs args) { _LinkClickedEventArgs = args; Console.WriteLine("DisplayRTB " + _LinkClickedEventArgs.LinkText); if (LinkGoTo != null) LinkGoTo(sender, args); } void DisplayRTB_Leave(object sender, EventArgs e) { // Save returns true if text was not changed or if change was saved successfully. if (ReadOnly) return; // TODO: RHM20071115 bool success = _origVlnText.Save((RichTextBox)this); // TODO: RHM20071115 if (!success) Console.WriteLine("Failed to save text: {0}", this.Text); } private Point _savcurpos; private void onLinkClicked(object sender, System.Windows.Forms.LinkClickedEventArgs e) { if (ReadOnly) return; _LinkClickedEventArgs = e; _eLinkText = e.LinkText; _savcurpos = Cursor.Position; if (e.LinkText.IndexOf("ReferencedObject") > -1) this.contextMenuStripROs.Show(System.Windows.Forms.Cursor.Position); else this.contextMenuStripTrans.Show(System.Windows.Forms.Cursor.Position); } private void SelectLink(string LinkText) { Point cp = PointToClient(_savcurpos); int index = GetCharIndexFromPosition(cp); int iMax = index; int iMin = index; Select(index, 0); while (SelectionProtected) Select(--iMin, 0); Select(iMin - 1, 1 + LinkText.Length); SelectionProtected = false; Select(iMin, LinkText.Length); } void vlnRichTextBox_ContentsResized(object sender, ContentsResizedEventArgs e) { ContentsRectangle = e.NewRectangle; } #region KeyboardHandling private bool IsControlChar = false; private void onKeyDown(object sender, System.Windows.Forms.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; } } } private void onKeyPress(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. // check for symbol - how?? AddRtf(e.KeyChar.ToString()); } IsControlChar = false; } e.Handled = true; // flag that it's been handled, otherwise, will get 2 chars. } #endregion #endregion #region Font with Styles 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 Context Menu Strip private void contextMenuStrip_Opening(object sender, CancelEventArgs e) { Font cfont = GetFontDetails(); menu_Bold.Checked = cfont.Bold; menu_Underline.Checked = cfont.Underline; menu_Italics.Checked = cfont.Italic; menu_Superscript.Checked = RTBAPI.IsSuperScript(this); menu_Subscript.Checked = RTBAPI.IsSubScript(this); menu_Bold.Enabled = !ReadOnly; menu_Underline.Enabled = !ReadOnly; menu_Italics.Enabled = !ReadOnly; menu_Superscript.Enabled = !ReadOnly; menu_Subscript.Enabled = !ReadOnly; menu_Undo.Enabled = !ReadOnly; menu_Redo.Enabled = !ReadOnly; menu_lowercase.Enabled = !ReadOnly; menu_UPPERCASE.Enabled = !ReadOnly; menu_TitleCase.Enabled = !ReadOnly; menu_InsRO.Enabled = !ReadOnly; menu_InsTran.Enabled = !ReadOnly; menu_InsSym.Enabled = !ReadOnly; menu_ToggleView.Enabled = true; } private void contextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { try { Font cfont = GetFontDetails(); //if (e.ClickedItem.ToString() == "Paste") DoPaste(); if (e.ClickedItem.ToString() == "Underline") ToggleFontStyle(FontStyle.Underline, cfont.Underline); else if (e.ClickedItem.ToString() == "Bold") ToggleFontStyle(FontStyle.Bold, cfont.Bold); else if (e.ClickedItem.ToString() == "Italics") ToggleFontStyle(FontStyle.Italic, cfont.Italic); else if (e.ClickedItem.ToString() == "Subscript") RTBAPI.ToggleSubscript(!RTBAPI.IsSubScript(this), this, this.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION); else if (e.ClickedItem.ToString() == "Superscript") RTBAPI.ToggleSuperscript(!RTBAPI.IsSuperScript(this), this, this.SelectionLength == 0 ? RTBAPI.RTBSelection.SCF_DEFAULT : RTBAPI.RTBSelection.SCF_SELECTION); else if (e.ClickedItem.ToString() == "Undo") this.Undo(); else if (e.ClickedItem.ToString() == "Redo") this.Redo(); else if (e.ClickedItem.ToString() == "lowercase") SetSelectedCase('l'); else if (e.ClickedItem.ToString() == "UPPERCASE") SetSelectedCase('U'); else if (e.ClickedItem.ToString() == "TitleCase") SetSelectedCase('T'); else if (e.ClickedItem.ToString() == "Insert RO") InsertRO("kbr ro", "0000000000000"); else if (e.ClickedItem.ToString() == "Insert Transition") InsertTran("kbr Tran", "5 3 5"); else if (e.ClickedItem.ToString() == "Insert Symbol") InsertSymbol(@"\u916?"); // hardcode for now, but should get value from dialog else if (e.ClickedItem.ToString() == "Toggle View/Edit") ToggleViewEdit(); //else if (e.ClickedItem.ToString() == "Find text") findit(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private 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; } } private void DeleteTransition() { SelectLink(_eLinkText); SelectedText = ""; } private void ModifyTransition() { Console.WriteLine("Modify Transition"); } private void contextMenuStripTrans_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (e.ClickedItem.ToString() == "Delete Transition") DeleteTransition(); else if (e.ClickedItem.ToString() == "Modify Transition") ModifyTransition(); else if (e.ClickedItem.ToString() == "Go To") { Console.WriteLine("DisplayRTB:contextMenu:Go TO"); OnLinkGoTo(sender, _LinkClickedEventArgs); } } private void contextMenuStripTrans_Opening(object sender, CancelEventArgs e) { menu_GoToTrans.Enabled = true; menu_DeleteTrans.Enabled = !ReadOnly; menu_ModifyTrans.Enabled = !ReadOnly; } private void contextMenuStripROs_Opening(object sender, CancelEventArgs e) { menu_DeleteRO.Enabled = !ReadOnly; menu_ModifyRO.Enabled = !ReadOnly; } private void DeleteRefObj() { SelectLink(_eLinkText); SelectedText = ""; } private void ModifyRefObj() { Console.WriteLine("ModifyRefObj"); } private void contextMenuStripROs_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (e.ClickedItem.ToString() == "Delete RO") DeleteRefObj(); else if (e.ClickedItem.ToString() == "Modify RO") ModifyRefObj(); } #endregion } }