Rich ee9acb929d Fix problem with Item Selected. Fixes problem so that Item selected stays selected even if it is not active.
Also, makes DSOFramer properly select the related tab when it becomes active.
2008-02-26 16:20:00 +00:00

682 lines
22 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 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;
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
/// <summary>
/// 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.
/// </summary>
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()
{
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; // 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;
}
#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);
}
public event DisplayRTBLinkEvent LinkModifyTran;
private void OnLinkModifyTran(object sender, LinkClickedEventArgs args)
{
_LinkClickedEventArgs = args;
if (LinkModifyTran != null) LinkModifyTran(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;
// // if selecting another rtb, save. If selecting the info panel don't because
// // we're still on a valid item.??
//}
public void SaveText()
{
if (ReadOnly) return;
bool success = _origVlnText.Save((RichTextBox)this);
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
);
}
}
/// <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
#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")
{
OnLinkModifyTran(sender, _LinkClickedEventArgs);
}
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
}
}