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
}
}