
Correct dispose logic for transition destination ITEMs Correct cursor position after Transition Insert Correct logic to parse Transition Link Token Correct Save Config to dispose of ITEM Removed debug vlnStackTrace
2771 lines
91 KiB
C#
2771 lines
91 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 System.Text.RegularExpressions;
|
|
using VEPROMS.CSLA.Library;
|
|
using Volian.Base.Library;
|
|
|
|
namespace Volian.Controls.Library
|
|
{
|
|
public delegate void StepRTBEvent(object sender, EventArgs args);
|
|
public delegate void StepRTBCursorKeysEvent(object sender, KeyEventArgs args);
|
|
public delegate void StepRTBCursorMovementEvent(object sender, StepRTBCursorMovementEventArgs args);
|
|
public delegate void StepRTBModeChangeEvent(object sender, StepRTBModeChangeEventArgs args);
|
|
//public delegate void StepRTBMouseWheelEvent(object sender, MouseEventArgs args);
|
|
public partial class StepRTB : RichTextBox , IStepRTB
|
|
{
|
|
#region Events
|
|
public event StepRTBEvent RTBSelectionChanged;
|
|
private void OnRTBSelectionChanged(object sender, EventArgs args)
|
|
{
|
|
if (RTBSelectionChanged != null) RTBSelectionChanged(sender, args);
|
|
}
|
|
public event StepRTBEvent LinkLocationsChanged;
|
|
private void OnLinkLocationChanged(object sender, EventArgs args)
|
|
{
|
|
if (LinkLocationsChanged != null) LinkLocationsChanged(sender, args);
|
|
}
|
|
public event StepRTBEvent RTBRangeStatusChanged;
|
|
private void OnRTBRangeStatusChanged(object sender, EventArgs args)
|
|
{
|
|
if (RTBRangeStatusChanged != null) RTBRangeStatusChanged(sender, args);
|
|
}
|
|
public event StepRTBCursorKeysEvent CursorKeyPress;
|
|
private void OnCursorKeyPress(object sender, KeyEventArgs args)
|
|
{
|
|
if (CursorKeyPress != null) CursorKeyPress(sender, args);
|
|
}
|
|
public event StepRTBCursorMovementEvent CursorMovement;
|
|
private void OnCursorMovement(object sender, StepRTBCursorMovementEventArgs args)
|
|
{
|
|
if (CursorMovement != null) CursorMovement(sender, args);
|
|
}
|
|
public event StepRTBModeChangeEvent ModeChange;
|
|
private void OnModeChange(object sender, StepRTBModeChangeEventArgs args)
|
|
{
|
|
//_MyModeChangeEventArgs = args;
|
|
if (ModeChange != null) ModeChange(sender, args);
|
|
else MessageBox.Show("StepRTB - no mode change defined");
|
|
}
|
|
//public event StepRTBMouseWheelEvent MouseWheel;
|
|
//private void OnMouseWheel(object sender, MouseEventArgs args)
|
|
//{
|
|
// if (MouseWheel != null) MouseWheel(sender, args);
|
|
//}
|
|
|
|
/// <summary>
|
|
/// This event is not raised during all the in-between changes for link deletions
|
|
/// </summary>
|
|
public event StepRTBEvent RTBTextChanged;
|
|
private void OnRTBTextChanged(object sender, EventArgs args)
|
|
{
|
|
if (RTBTextChanged != null) RTBTextChanged(sender, args);
|
|
}
|
|
#endregion
|
|
#region Properties and Variables
|
|
private static FontFamily _MyFontFamily = null;
|
|
public static FontFamily MyFontFamily
|
|
{
|
|
get { return StepRTB._MyFontFamily; }
|
|
set { StepRTB._MyFontFamily = value; }
|
|
}
|
|
// 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 E_FieldToEdit _FieldToEdit = E_FieldToEdit.StepText;
|
|
public E_FieldToEdit FieldToEdit
|
|
{
|
|
get { return _FieldToEdit; }
|
|
set { _FieldToEdit = value; }
|
|
}
|
|
private string _RtfPrefix; // contains Font table and styles (bold/underline/italics) for rtb from step style
|
|
public string RtfPrefix
|
|
{
|
|
get
|
|
{
|
|
return _RtfPrefix + @"\f1\fs" + this.Font.SizeInPoints * 2 + " ";
|
|
}
|
|
}
|
|
private StepItem _MyStepItem;
|
|
public StepItem MyStepItem
|
|
{
|
|
get { return _MyStepItem; }
|
|
set { _MyStepItem = value; }
|
|
}
|
|
// August 5, 2009 - KBR & RHM:
|
|
// Insert/Overwrite will be developed later if needed. various issues
|
|
// were found during initial development that made its scope larger than
|
|
// expected. Problems were related to having overstrike on in the following
|
|
// cases:
|
|
// 1) left arrow when on link - positions after link
|
|
// 2) left arrow and after link - does not move
|
|
// 3) shift left arrow does not move past links correctly and also, first
|
|
// shift left arrow looks more like insert mode.
|
|
// private bool _OverWrite;
|
|
// _IsDirty compares the original rtf to the current rtf from the
|
|
// richtextbox to see if a change was made.
|
|
private bool _IsDirty
|
|
{
|
|
get { return _origRTF != Rtf; }
|
|
}
|
|
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; }
|
|
}
|
|
public bool ViewRTB = true;
|
|
private ItemInfo _MyItemInfo;
|
|
public ItemInfo MyItemInfo
|
|
{
|
|
get { return _MyItemInfo; }
|
|
set
|
|
{
|
|
_MyItemInfo = value;
|
|
if (value != null)
|
|
{
|
|
RTBFillIn(!ViewRTB);
|
|
SetBackColor();
|
|
//ViewRTB = MyStepItem.MyStepPanel.PanelViewEditMode == E_ViewMode.View;
|
|
}
|
|
}
|
|
}
|
|
public void SetBackColor()
|
|
{
|
|
if (MyStepItem == null || MyStepItem.MyStepPanel == null) return;
|
|
if (!Focused)BackColor = _MyItemInfo.ItemAnnotationCount == 0 ? MyStepItem.MyStepPanel.InactiveColor : Color.FromArgb(255, 255, 128);
|
|
}
|
|
public void HighlightBackColor()
|
|
{
|
|
// Don't try to highlight if this rtb is used on property pages.
|
|
if (MyStepItem == null || MyStepItem.MyStepPanel == null) return;
|
|
BackColor = Color.Gray;
|
|
}
|
|
private string _origRTF;
|
|
public void RTBFillIn(bool edit)
|
|
{
|
|
if (edit && _MyStepItem != null && (_MyItemInfo.IsTable || _MyItemInfo.IsFigure))
|
|
{
|
|
// First get ColR
|
|
int colR = MyStepItem.MyStepPanel.ToDisplay(MyStepItem.MyStepSectionLayoutData.ColRTable, MyItemInfo.ColumnMode);
|
|
// Second get WidS
|
|
int widS = /* _WidthAdjust + borderWidth + */ MyStepItem.MyStepPanel.ToDisplay(MyStepItem.MyStepSectionLayoutData.WidSTableEdit, MyItemInfo.ColumnMode);
|
|
//int wNew = _MyStepItem.MyStepPanel.ToDisplay(_MyStepItem.MyStepSectionLayoutData.WidT);
|
|
int wNew = 70 + widS + colR * MyItemInfo.ColumnMode;
|
|
if(wNew > _MyStepItem.ItemWidth)
|
|
_MyStepItem.ItemWidth= wNew;
|
|
}
|
|
_InitializingRTB = true;
|
|
_SelectedRtfSB.Remove(0, _SelectedRtfSB.Length);
|
|
DisplayText vlntxt = new DisplayText(_MyItemInfo, EpMode, VwMode, !edit, FieldToEdit, true);
|
|
//if (_origDisplayText != null && vlntxt.StartText == _origDisplayText.StartText)
|
|
//{
|
|
// ReadOnly = !(EpMode == E_EditPrintMode.Edit && VwMode == E_ViewMode.Edit);
|
|
// if (!ReadOnly && !edit) ReadOnly = true;
|
|
// return;
|
|
//}
|
|
_origDisplayText = vlntxt;
|
|
Font formatFont = _origDisplayText.TextFont.WindowsFont;
|
|
if (_MyItemInfo.IsTable || _MyItemInfo.IsFigure)
|
|
Font = formatFont;
|
|
else
|
|
{
|
|
if (VlnSettings.DebugMode)
|
|
Font = new Font(_MyFontFamily == null ? formatFont.FontFamily : _MyFontFamily, formatFont.Size, formatFont.Style);
|
|
else
|
|
Font = new Font("Bookman Old Style", formatFont.Size, formatFont.Style);
|
|
// TODO: Release Mode
|
|
//Font = _origDisplayText.TextFont.WindowsFont; // font defined in plant's format
|
|
}
|
|
Text = ""; // Initialize text before add text
|
|
// IMPORTANT: SetLineSpacing must be set before Links, otherwise it
|
|
// was confusing the 'handle' of the rtf box.
|
|
RTBAPI.SetLineSpacing(this, RTBAPI.ParaSpacing.PFS_EXACT);
|
|
AddRtfText(vlntxt.StartText);
|
|
//AddRtfStyles();
|
|
// set readonly based on initial modes, however, these may change if
|
|
// user selected view mode.
|
|
ReadOnly = !(EpMode == E_EditPrintMode.Edit && VwMode == E_ViewMode.Edit);
|
|
if (!ReadOnly && !edit) ReadOnly = true;
|
|
ClearUndo();
|
|
RightMargin = Width;
|
|
// figure out if needs outlined, depends on table/figure type
|
|
if (!edit)
|
|
{
|
|
RemoveEventHandlers();
|
|
if ((!_MyItemInfo.IsSection && !_MyItemInfo.IsProcedure) && (_MyItemInfo.IsTable || _MyItemInfo.IsFigure))
|
|
{
|
|
int newwidth = (int)_MyStepItem.TableWidth(Font, Text, true);
|
|
if (_MyStepItem.ItemWidth != newwidth)
|
|
{
|
|
_MyStepItem.ItemWidth = newwidth;
|
|
}
|
|
// int typ = ((int)_MyItemInfo.MyContent.Type) % 10000;
|
|
// OutlineTable(_MyItemInfo.ActiveFormat.PlantFormat.FormatData.StepDataList[typ].Type.IndexOf(@"Borderless")<0);
|
|
// FindAllLinks();
|
|
}
|
|
SelectAll();
|
|
if (SelectionHangingIndent !=0) SelectionHangingIndent = 0;
|
|
int indchar = 0;
|
|
string indentToken = _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IndentToken;
|
|
if (indentToken == null) indentToken = "\x5";
|
|
while ((indchar = Find(indentToken, indchar, RichTextBoxFinds.None)) >= 0)
|
|
{
|
|
Point indent = GetPositionFromCharIndex(indchar);
|
|
SelectionHangingIndent = indent.X;
|
|
indchar++;
|
|
}
|
|
AddEventHandlers();
|
|
}
|
|
//else
|
|
//{
|
|
// if (_MyStepItem != null && (_MyItemInfo.IsTable || _MyItemInfo.IsFigure))
|
|
// {
|
|
// //_MyStepItem.ItemWidth = (int)_MyStepItem.TableWidth(Font, Text,false);
|
|
// _MyStepItem.ItemWidth = _MyStepItem.MyStepPanel.ToDisplay(_MyStepItem.MyStepSectionLayoutData.WidT);
|
|
// }
|
|
//}
|
|
_origRTF = Rtf;
|
|
_InitializingRTB = false;
|
|
_MyItemInfo.MyConfig.PropertyChanged += new PropertyChangedEventHandler(MyConfig_PropertyChanged);
|
|
AdjustSizeForContents(!edit); // TODO: this is not quite right yet.
|
|
if (MyStepItem != null) MyStepItem.ChangeBar = MyStepItem.MyItemInfo.HasChangeBar();
|
|
}
|
|
private bool _ProcessKeystrokes = true;
|
|
public bool ProcessKeystrokes
|
|
{
|
|
get { return _ProcessKeystrokes; }
|
|
set { _ProcessKeystrokes = value; }
|
|
}
|
|
|
|
//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 = new Rectangle(0,0,0,0);
|
|
public Rectangle ContentsRectangle
|
|
{
|
|
get
|
|
{
|
|
if (_ContentsRectangle.X == 0 && _ContentsRectangle.Y == 0 && _ContentsRectangle.Width == 0 && _ContentsRectangle.Height == 0)
|
|
_ContentsRectangle = this.ClientRectangle;
|
|
return _ContentsRectangle;
|
|
}
|
|
set
|
|
{
|
|
_ContentsRectangle = value;
|
|
AdjustSizeForContents(false);
|
|
}
|
|
}
|
|
public Size ContentsSize
|
|
{
|
|
get { return _ContentsRectangle.Size; }
|
|
}
|
|
private Size _AdjustSize = new Size(0,0); // if 0,0 puts text right next to bottom of box.
|
|
public Size AdjustSize
|
|
{
|
|
get { return _AdjustSize; }
|
|
set
|
|
{
|
|
_AdjustSize = value;
|
|
AdjustSizeForContents(false);
|
|
}
|
|
}
|
|
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)
|
|
//{
|
|
// updates to the info panel were not always occurring when the previous two
|
|
// lines were active
|
|
_MyLinkText = value;
|
|
OnLinkChanged(this, new StepPanelLinkEventArgs(_MyStepItem, _MyLinkText));
|
|
//}
|
|
}
|
|
}
|
|
#endregion
|
|
#region Constructors
|
|
public StepRTB()
|
|
{
|
|
InitializeComponent();
|
|
SetUpStepRTB();
|
|
AddEventHandlers();
|
|
}
|
|
public StepRTB(IContainer container)
|
|
{
|
|
container.Add(this);
|
|
InitializeComponent();
|
|
_Container = container;
|
|
SetUpStepRTB();
|
|
AddEventHandlers();
|
|
}
|
|
protected override void OnMouseWheel(MouseEventArgs e)
|
|
{
|
|
_MyStepItem.MyStepPanel.MouseWheel(e);
|
|
//base.OnMouseWheel(e);
|
|
}
|
|
private void RemoveEventHandlers()
|
|
{
|
|
ContentsResized -= new ContentsResizedEventHandler(StepRTB_ContentsResized);
|
|
this.Click -= new EventHandler(StepRTB_Click);
|
|
this.KeyPress -= new KeyPressEventHandler(StepRTB_KeyPress);
|
|
this.KeyDown -= new KeyEventHandler(StepRTB_KeyDown);
|
|
this.KeyUp -= new KeyEventHandler(StepRTB_KeyUp);
|
|
this.TextChanged -= new EventHandler(StepRTB_TextChanged);
|
|
this.MouseUp -= new MouseEventHandler(StepRTB_MouseUp);
|
|
this.MouseDown -= new MouseEventHandler(StepRTB_MouseDown);
|
|
this.MouseLeave -= new EventHandler(StepRTB_MouseLeave);
|
|
this.SelectionChanged -= new EventHandler(StepRTB_SelectionChanged);
|
|
}
|
|
private void AddEventHandlers()
|
|
{
|
|
BorderStyle = System.Windows.Forms.BorderStyle.None;
|
|
this.DetectUrls = true;
|
|
ContentsResized += new ContentsResizedEventHandler(StepRTB_ContentsResized);
|
|
this.Click +=new EventHandler(StepRTB_Click);
|
|
this.KeyPress += new KeyPressEventHandler(StepRTB_KeyPress);
|
|
this.KeyDown += new KeyEventHandler(StepRTB_KeyDown);
|
|
this.KeyUp += new KeyEventHandler(StepRTB_KeyUp);
|
|
this.TextChanged += new EventHandler(StepRTB_TextChanged);
|
|
this.MouseUp += new MouseEventHandler(StepRTB_MouseUp);
|
|
this.MouseDown += new MouseEventHandler(StepRTB_MouseDown);
|
|
this.MouseLeave += new EventHandler(StepRTB_MouseLeave);
|
|
this.SelectionChanged +=new EventHandler(StepRTB_SelectionChanged);
|
|
this.ContextMenuStripChanged += new EventHandler(StepRTB_ContextMenuStripChanged);
|
|
this.RTBSelectionChanged += new StepRTBEvent(StepRTB_RTBSelectionChanged);
|
|
}
|
|
|
|
void StepRTB_RTBSelectionChanged(object sender, EventArgs args)
|
|
{
|
|
//Console.WriteLine("RTBSelectionChanged id= {0}", MyItemInfo.ItemID);
|
|
if (!Focused) Focus();
|
|
}
|
|
|
|
void StepRTB_ContextMenuStripChanged(object sender, EventArgs e)
|
|
{
|
|
//Console.WriteLine("********** StepRTB_ContextMenuStripChanged");
|
|
int sublocation = 0;
|
|
try
|
|
{
|
|
//Console.WriteLine("{0}", ContextMenuStrip.GetType().FullName);
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ClearContextMenu();
|
|
sublocation = 1;
|
|
_ContextMenuStripChanged = true;
|
|
sublocation = 2;
|
|
_ContextMenuStepRTB = this;
|
|
sublocation = 3;
|
|
_ContextMenuStrip = ContextMenuStrip;
|
|
sublocation = 4;
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
Console.WriteLine("StepRTB_ContextMenuStripChanged {0} - {1} [{2}]", ex.GetType().Name, ex.Message, sublocation);
|
|
}
|
|
}
|
|
private void SetUpStepRTB()
|
|
{
|
|
C1SpellChecker2.SetActiveSpellChecking(this, true);
|
|
this.Height = 10; // initialize the height to 10, the default height was too big for the cells in grid tables
|
|
BorderStyle = System.Windows.Forms.BorderStyle.None;
|
|
this.ScrollBars = RichTextBoxScrollBars.None;
|
|
this.DetectUrls = true;
|
|
}
|
|
// An event is needed to set MouseDown to false on mouse leave, because additional rtb's may
|
|
// have been exposed based on entering a step, which causes the underlying item/rtb for which
|
|
// the mouse event occurs to not be the current rtb. RTB gets selected on MouseDown, MouseEnter
|
|
// and MouseUp are
|
|
void StepRTB_MouseLeave(object sender, EventArgs e)
|
|
{
|
|
_MouseDown = false;
|
|
}
|
|
void MyConfig_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
SaveConfig();
|
|
}
|
|
private void StepRTB_Click(object sender, EventArgs e)
|
|
{
|
|
if (ReadOnly) return;
|
|
}
|
|
public bool inRoAdd = false;
|
|
void StepRTB_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
//Console.WriteLine("StepRTB_SelectionChanged id= {0}", MyItemInfo.ItemID);
|
|
if (_InitializingRTB) return;
|
|
HandleSelectionChange();
|
|
}
|
|
private bool _MouseDown = false;
|
|
private bool _ContextMenuStripChanged = false;
|
|
private void StepRTB_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
_MouseDown = true;
|
|
//Console.WriteLine("vvvvvvvvvv StepRTB Mouse Down id= {0}",MyItemInfo.ItemID);
|
|
if (!_ContextMenuStripChanged && this.MyStepItem != null)
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.SetContextMenu();
|
|
_ContextMenuStripChanged = false;
|
|
}
|
|
void StepRTB_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
_MouseDown = false;
|
|
//Console.WriteLine("^^^^^^^^^^ StepRTB Mouse Up id= {0}", MyItemInfo.ItemID);
|
|
|
|
if(this.Focused) // Only HandleSelectionChange if this control has focus.
|
|
{
|
|
HandleSelectionChange();
|
|
// save our context menu to add to the spell checker's context menu
|
|
ThisContextMenuStrip = this.ContextMenuStrip;
|
|
}
|
|
}
|
|
#endregion
|
|
#region ApplicationSupport
|
|
public void ToggleEditView()
|
|
{
|
|
SaveText();
|
|
//ItemInfo tmp = MyItemInfo;
|
|
//MyItemInfo = null;
|
|
ReadOnly = !ReadOnly;
|
|
EpMode = ReadOnly ? E_EditPrintMode.Print : E_EditPrintMode.Edit;
|
|
VwMode = ReadOnly ? E_ViewMode.View : E_ViewMode.Edit;
|
|
ViewRTB = ReadOnly;
|
|
Clear();
|
|
RTBFillIn(!ViewRTB);
|
|
//MyItemInfo = tmp;
|
|
SelectionStart = 0;
|
|
SelectionLength = 0;
|
|
OnModeChange(this, new StepRTBModeChangeEventArgs(ViewRTB?E_ViewMode.View:E_ViewMode.Edit));
|
|
}
|
|
public void InsertRO(string value, string link)
|
|
{
|
|
AddRtfLink(value, link);
|
|
}
|
|
public void InsertTran(string value, string link)
|
|
{
|
|
AddRtfLink(value, link);
|
|
}
|
|
public void InsertSymbol(int symbcode)
|
|
{
|
|
string sym = string.Format(symbcode < 256 ? "\'{0:X2}" : @"\u{0}", symbcode);
|
|
if (symbcode < 256)
|
|
AddText(((char)symbcode).ToString());
|
|
else
|
|
AddSymbol(sym); // Adds font commands around symbol, needed for higher codes
|
|
}
|
|
public void InsertSymbol(string symbol)
|
|
{
|
|
AddSymbol(symbol);
|
|
}
|
|
public void InsertIndent()
|
|
{
|
|
string indentToken = _MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.IndentToken;
|
|
if (indentToken == null) indentToken = "\x5";
|
|
AddText(indentToken);
|
|
}
|
|
public void InsertText(string txt)
|
|
{
|
|
AddText(txt);
|
|
}
|
|
|
|
private void ToggleCase()
|
|
{
|
|
char type = 'l';
|
|
// do not change case on linked text
|
|
RangeStatus rs = FindRangeStatus();
|
|
string tmp = null;
|
|
if (rs != RangeStatus.NoContainedLinks)
|
|
{
|
|
int start = SelectionStart;
|
|
int ostart = SelectionStart;
|
|
int end = SelectionStart + SelectionLength;
|
|
bool processed = false;
|
|
while (!processed && start <= end)
|
|
{
|
|
foreach (LinkLocation ll in LinkLocations)
|
|
{
|
|
if (ll.Start >= start && ll.End <= end)
|
|
{
|
|
processed = true;
|
|
if (start < ll.Start)
|
|
{
|
|
SelectionStart = start;
|
|
SelectionLength = ll.Start - start;
|
|
}
|
|
start = ll.End + 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
string ostring = SelectedText;
|
|
if ((char.IsUpper(ostring, 0) && char.IsUpper(ostring, 1)) ||
|
|
(char.IsLower(ostring, 0) && char.IsUpper(ostring, 1))) type = 'l'; // lower case
|
|
else if ((char.IsUpper(ostring, 0) && char.IsLower(ostring, 1))) type = 'U'; // upper case
|
|
else type = 'T'; // Title case
|
|
SetSelectedCase(type);
|
|
}
|
|
|
|
public void SetSelectedCase(char type)
|
|
{
|
|
// do not change case on linked text
|
|
RangeStatus rs = FindRangeStatus();
|
|
string tmp = null;
|
|
if (rs == RangeStatus.NoContainedLinks)
|
|
SetCase(type);
|
|
else
|
|
{
|
|
int start = SelectionStart;
|
|
int ostart = SelectionStart;
|
|
int end = SelectionStart + SelectionLength;
|
|
StringBuilder sb = new StringBuilder();
|
|
while (start <= end)
|
|
{
|
|
bool processed = false;
|
|
foreach (LinkLocation ll in LinkLocations)
|
|
{
|
|
if (ll.Start >= start && ll.End <= end)
|
|
{
|
|
processed = true;
|
|
if (start < ll.Start)
|
|
{
|
|
SelectionStart = start;
|
|
SelectionLength = ll.Start - start;
|
|
SetCase(type);
|
|
}
|
|
start = ll.End + 1;
|
|
break;
|
|
}
|
|
}
|
|
// if none were processed, no more links, copy over any remaining text.
|
|
if (!processed)
|
|
{
|
|
SelectionStart = start;
|
|
SelectionLength = end-start;
|
|
SetCase(type);
|
|
start = end + 1;
|
|
}
|
|
}
|
|
SelectionStart = ostart;
|
|
SelectionLength = end - ostart;
|
|
}
|
|
}
|
|
|
|
private void SetCase(char type)
|
|
{
|
|
int ostart = SelectionStart;
|
|
int olen = SelectionLength;
|
|
string ostring = SelectedText;
|
|
string tmp = null;
|
|
bool docap = true;
|
|
// go character by character. Because of symbols, setting entire
|
|
// to upper or lower set symbols incorrectly some of time (depending
|
|
// on symbol) .
|
|
for (int i = 0; i < olen; i++)
|
|
{
|
|
SelectionStart = ostart + i;
|
|
SelectionLength = 1;
|
|
switch (type)
|
|
{
|
|
case 'l':
|
|
if (SelectedText[0] >= 'A' && SelectedText[0] <= 'Z')
|
|
SelectedText = SelectedText.ToLower();
|
|
break;
|
|
case 'U':
|
|
if (SelectedText[0] >= 'a' && SelectedText[0] <= 'z')
|
|
SelectedText = SelectedText.ToUpper();
|
|
break;
|
|
case 'T':
|
|
if (docap && SelectedText[0] >= 'a' && SelectedText[0] <= 'z')
|
|
SelectedText = SelectedText.ToUpper();
|
|
else if (!docap && SelectedText[0] >= 'A' && SelectedText[0] <= 'Z')
|
|
SelectedText = SelectedText.ToLower();
|
|
docap = ostring[i] == ' ';
|
|
break;
|
|
}
|
|
}
|
|
SelectionStart = ostart;
|
|
SelectionLength = olen;
|
|
}
|
|
#endregion
|
|
#region SaveData
|
|
public void SaveText(bool force)
|
|
{
|
|
if (ReadOnly) return;
|
|
if (ViewRTB) return;
|
|
if (!force && !_IsDirty && Text.Contains("(Resolved Transition Text)") == false) return;
|
|
bool success = _origDisplayText.Save((RichTextBox)this);
|
|
if (success)
|
|
{
|
|
FindAllLinks();
|
|
_origRTF = Rtf;
|
|
ClearUndo();
|
|
}
|
|
}
|
|
public void SaveText()
|
|
{
|
|
if (ReadOnly) return;
|
|
if (ViewRTB) return;
|
|
if (!_IsDirty && Text.Contains("(Resolved Transition Text)") == false) return;
|
|
bool success = _origDisplayText.Save((RichTextBox)this);
|
|
if (success)
|
|
{
|
|
FindAllLinks();
|
|
_origRTF = Rtf;
|
|
ClearUndo();
|
|
}
|
|
}
|
|
public void SaveConfig()
|
|
{
|
|
if (!_MyItemInfo.MyConfig.IsDirty) return;
|
|
using (Item itm = _MyItemInfo.Get())
|
|
{
|
|
itm.MyContent.Config = _MyItemInfo.MyConfig.ToString();
|
|
itm.Save();
|
|
}
|
|
_MyItemInfo.MyConfig.IsDirty = false;
|
|
}
|
|
#endregion
|
|
#region AddRtfTextAndStyles
|
|
private void AddRtfText(string txt)
|
|
{
|
|
AddFontTable();
|
|
_RtfPrefix = _SelectedRtfSB.ToString();
|
|
_SelectedRtfSB.Append(txt);
|
|
SelectedRtf = _SelectedRtfSB.ToString() + "}";
|
|
FindAllLinks();
|
|
}
|
|
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 + @"}}";
|
|
if (!FontIsFixed())
|
|
_SelectedRtfSB.Append(@"{\f1\fnil\fcharset0 Arial Unicode MS;}}{\colortbl ;\red255\green0\blue0;}");
|
|
else
|
|
_SelectedRtfSB.Append(@"{\f1\fnil\fcharset0 VESymbFix;}}{\colortbl ;\red255\green0\blue0;}");
|
|
_SelectedRtfSB.Append("\r\n");
|
|
// use styles to construct rtf commands to insert into next line (where \b, etc is)
|
|
_SelectedRtfSB.Append(@"\viewkind4\uc1\pard\sl-240\slmult0" + sbbeg.ToString() + @"\fs" + Convert.ToInt32(this.Font.SizeInPoints * 2).ToString() + @" "); // \f0\fs" + this.Font.SizeInPoints * 2 + @" " + myDisplayTextElement.Text + @"}";
|
|
}
|
|
|
|
private bool FontIsFixed()
|
|
{
|
|
Graphics grph = Graphics.FromHwnd(this.Handle);
|
|
SizeF sfW = grph.MeasureString("W", this.Font);
|
|
SizeF sfE = grph.MeasureString("!", this.Font);
|
|
if (sfW.Width == sfE.Width) return true;
|
|
return false;
|
|
}
|
|
private void AddRtf(string str)
|
|
{
|
|
// Because we're inserting rtf with { }, the surrounding styles are not included. Get the font
|
|
// style of current position & use it after the insert to set the style.
|
|
RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(this);
|
|
int positionStart = SelectionStart;
|
|
SelectedRtf = @"{\rtf1{\fonttbl{\f0\fcharset2 " + this.Font.FontFamily.Name + @";}}\f0\fs" + this.Font.SizeInPoints * 2 + @" " + str + @"}}";
|
|
// Note that SelectedRtf does not contain the inserted text after the previous line. We need
|
|
// to determine how long the inserted string is in order to set its style. SelectionStart contains
|
|
// the location after the insertion.
|
|
int positionAfter = SelectionStart;
|
|
Select(positionStart, positionAfter - positionStart);
|
|
RTBAPI.SetFontStyle(this, fs);
|
|
Select(positionAfter, 0);
|
|
}
|
|
private void AddText(string str)
|
|
{
|
|
// See comments in AddRtf(string str) to explain the font style setting
|
|
RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(this);
|
|
int positionStart = SelectionStart;
|
|
SelectedText = str;
|
|
int positionAfter = SelectionStart;
|
|
Select(positionStart, positionAfter - positionStart);
|
|
RTBAPI.SetFontStyle(this, fs);
|
|
Select(positionAfter, 0);
|
|
}
|
|
private void AddSymbol(string str)
|
|
{
|
|
// See comments in AddRtf(string str) to explain the font style setting
|
|
RTBAPI.E_FontStyle fs = RTBAPI.GetFontStyle(this);
|
|
int position = SelectionStart;
|
|
SelectedRtf = _RtfPrefix + @"\f1\fs" + this.Font.SizeInPoints * 2 + @" " + str + @"}";
|
|
Select(position, 1);
|
|
RTBAPI.SetFontStyle(this, fs);
|
|
Select(position + 1, 0);
|
|
SelectionFont = _origDisplayText.TextFont.WindowsFont;
|
|
}
|
|
private string GetAddSymbolText(string symtxt)
|
|
{
|
|
return (@"{\f0\fs" + this.Font.SizeInPoints * 2 + @" " + symtxt + @"}");
|
|
}
|
|
public void AddRtfLink(string linkUrl, string linkValue)
|
|
{
|
|
if (CreateParams.ClassName == "RICHEDIT50W")
|
|
|
|
AddLink50(linkUrl, linkValue);
|
|
else
|
|
AddLink20(linkUrl, linkValue);
|
|
}
|
|
private string FontTable
|
|
{
|
|
get
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(@"{\fonttbl{\f0\fnil\fcharset2 " + this.Font.FontFamily.Name + @";}");
|
|
if (!FontIsFixed())
|
|
sb.Append(@"{\f1\fnil\fcharset0 Arial Unicode MS;}}");
|
|
else
|
|
sb.Append(@"{\f1\fnil\fcharset0 VESymbFix;}}");
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
private string FontSize
|
|
{
|
|
get
|
|
{
|
|
Match match = Regex.Match(Rtf, @"\\fs[0-9]*");
|
|
return match.Value;
|
|
}
|
|
}
|
|
|
|
private void AddLink20(string linkValue, string linkUrl)
|
|
{
|
|
string fonttab = FontTable;
|
|
string fontsize = FontSize;
|
|
this.DetectUrls = false;
|
|
//if (SelectionLength > 0) DeleteCurrentSelection(null);
|
|
if (SelectionLength > 0)HandleDeleteKeyWithSelectedText(new KeyEventArgs(Keys.None), null);
|
|
int position = SelectionStart;
|
|
SelectionLength = 0;
|
|
//Console.WriteLine(this.Rtf);
|
|
linkValue = linkValue.Replace("\\u8209?", "\\f1\\u8209?\\f0 ");
|
|
SelectedRtf = @"{\rtf1\ansi"+FontTable+@"{\colortbl ;\red255\green0\blue0;}\v"+FontSize+@" <START]\v0\cf1 " + linkValue + @"\cf0\v " + linkUrl + @"[END>\v0 }";
|
|
//Console.WriteLine(this.Rtf);
|
|
this.SelectionLength = 0;
|
|
this.SelectionStart = position;
|
|
FindAllLinks();
|
|
}
|
|
private void AddLink50(string linkValue, string linkUrl)
|
|
{
|
|
this.DetectUrls = false;
|
|
int position = SelectionStart;
|
|
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);
|
|
}
|
|
// Bug Fix
|
|
// The code below was changed to select all of the text and then
|
|
// apply the underlining to the selected text, because if the
|
|
// the underlining was applied to RTBAPI.RTBSelection.SCF_ALL
|
|
// the Links were changed so that they were no longer hidden.
|
|
if ((_origDisplayText.TextFont.Style & E_Style.Underline) > 0)
|
|
// RTBAPI.ToggleUnderline(true, this, RTBAPI.RTBSelection.SCF_ALL);
|
|
{
|
|
this.SelectAll();
|
|
RTBAPI.ToggleUnderline(true, this, RTBAPI.RTBSelection.SCF_SELECTION);
|
|
this.Select(0, 0);
|
|
}
|
|
// Bug Fix
|
|
// The code below was changed to select all of the text and then
|
|
// apply the italics to the selected text, because if the
|
|
// the italics was applied to RTBAPI.RTBSelection.SCF_ALL
|
|
// the Links were changed so that they were no longer hidden.
|
|
if ((_origDisplayText.TextFont.Style & E_Style.Italics) > 0)
|
|
// RTBAPI.ToggleItalic(true, this, RTBAPI.RTBSelection.SCF_ALL);
|
|
{
|
|
this.SelectAll();
|
|
RTBAPI.ToggleItalic(true, this, RTBAPI.RTBSelection.SCF_SELECTION);
|
|
this.Select(0, 0);
|
|
}
|
|
}
|
|
#endregion
|
|
#region HeightSupport
|
|
public event StepRTBEvent HeightChanged;
|
|
private void OnHeightChanged(object sender, EventArgs args)
|
|
{
|
|
if (HeightChanged != null) HeightChanged(sender, args);
|
|
}
|
|
private void AdjustSizeForContents(bool adjustWidth)
|
|
{
|
|
if (!_InitializingRTB)
|
|
{
|
|
Size offset = Size - ClientSize;
|
|
int widthNew = ContentsSize.Width + offset.Width + AdjustSize.Width ;
|
|
int heightNew = ContentsSize.Height + offset.Height + AdjustSize.Height;
|
|
// Don't make the window narrower unless it has text - RHM - 20100107
|
|
Size szNew = new Size(((Text != "" && adjustWidth) ? widthNew : (widthNew > Width ? widthNew : Width)), heightNew);
|
|
if (this.Size != szNew)
|
|
{
|
|
this.Size = szNew;
|
|
OnHeightChanged(this, new EventArgs());
|
|
}
|
|
}
|
|
}
|
|
private float GetStringWidth(string strMeasureString)
|
|
{
|
|
using (Graphics g = Graphics.FromHwnd(Handle))
|
|
{
|
|
return g.MeasureString(strMeasureString, Font).Width;
|
|
}
|
|
}
|
|
private int Ceiling(float f)
|
|
{
|
|
return (int)(Math.Ceiling(f));
|
|
}
|
|
public void AdjustWidthForContent()
|
|
{
|
|
int widthNL = Ceiling(GetStringWidth("\n"));
|
|
int widthMax = 0;
|
|
int widthMaxWW = 0;
|
|
int indexStart = 0;
|
|
int lineCountFromLines = Lines.Length;
|
|
int lineCountFromGet = GetLineFromCharIndex(TextLength)+1;
|
|
for (int i = 0; i < Lines.Length; i++)
|
|
{
|
|
int lineStart = GetLineFromCharIndex(indexStart);
|
|
int indexEnd = indexStart + Lines[i].Length;
|
|
int lineEnd = GetLineFromCharIndex(indexEnd);
|
|
Point pointStart = GetPositionFromCharIndex(indexStart);
|
|
Point pointEnd = GetPositionFromCharIndex(indexEnd);
|
|
int indexEndPos = GetCharIndexFromPosition(pointEnd);
|
|
if (indexEndPos + 1 < indexEnd) // This indicates that the text is wider than the Rich Text Box
|
|
{
|
|
int w = pointEnd.X + (indexEnd - indexEndPos) * widthNL;
|
|
if (w > widthMaxWW)
|
|
{
|
|
widthMaxWW = w;
|
|
}
|
|
}
|
|
if (lineEnd > lineStart)// this indicates that there was word-wrap on this line.
|
|
{
|
|
int w = pointEnd.X + Width * (lineEnd - lineStart);
|
|
if (w > widthMaxWW)
|
|
widthMaxWW = w;
|
|
}
|
|
else
|
|
{
|
|
if (pointEnd.X > widthMax)
|
|
widthMax = pointEnd.X;
|
|
}
|
|
indexStart = indexEnd + 1;
|
|
}
|
|
if (widthMaxWW == 0)
|
|
{
|
|
int widthBorder = Width - ClientSize.Width;
|
|
int w = widthMax + widthNL + widthBorder;
|
|
if (Width != w)
|
|
{
|
|
Width = w;
|
|
AdjustWidthForContent();// Try one more time
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Width = widthMaxWW;
|
|
AdjustWidthForContent();
|
|
}
|
|
}
|
|
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;
|
|
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);
|
|
}
|
|
#endregion
|
|
#region TextAndContentsEvents
|
|
void StepRTB_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (_InitializingRTB) return;
|
|
// Was setting _IsDirty to true here, but this was getting called from
|
|
// 'dotnetbar' when text was NOT Changed. So _IsDirty was made into
|
|
// a property and compared original rtf versus current richtextbox's
|
|
// rtf.
|
|
FindAllLinks();
|
|
}
|
|
void StepRTB_ContentsResized(object sender, ContentsResizedEventArgs e)
|
|
{
|
|
ContentsRectangle = e.NewRectangle;
|
|
}
|
|
#endregion
|
|
#region Selection Handlers
|
|
bool _AdjustingSelection = false;
|
|
private bool _ProcessingDelete;
|
|
private bool _HandlingCtrlA = false;
|
|
private void HandleLocalSelectionChange()
|
|
{
|
|
if (MyStepItem.MyStepPanel.SelectedStepRTB != this)
|
|
return;
|
|
|
|
HandleSelectionChange();
|
|
}
|
|
private void HandleSelectionChange()
|
|
{
|
|
if (_HandlingCtrlA) return;
|
|
if (!_HandlingCtrlA && this.TextLength == this.SelectionLength && this.SelectedRtf.EndsWith("\\par\r\n}\r\n"))
|
|
{
|
|
_HandlingCtrlA = true;
|
|
SelectAll();
|
|
_HandlingCtrlA = false;
|
|
}
|
|
//HandleOverWrite();
|
|
//vlnStackTrace.ShowStackLocal("HandleSelectionChangeStack", 1, 10);
|
|
bool startingValue = _AdjustingSelection;
|
|
if (_IdentifyingLinks || _ProcessingDelete) return;
|
|
if (ProcessKeystrokes)
|
|
{
|
|
if (!_MouseDown && !_AdjustingSelection)
|
|
{
|
|
if (_LinkLocations != null)
|
|
{
|
|
DebugPrint("HSC===================>Beginning: SelectionStart {0}, SelectionLength {1}", SelectionStart, SelectionLength);
|
|
_AdjustingSelection = true;
|
|
LinkLocation ll = FindLinkLocation();
|
|
LinkLocation llend = null;
|
|
if (SelectionLength != 0)
|
|
llend = FindLinkLocation(SelectionStart + SelectionLength - 1);
|
|
if (ll != null)
|
|
{
|
|
if (SelectionStart == ll.Start && SelectionLength == 0)
|
|
{
|
|
if (SelectionStart >= 7)
|
|
{
|
|
DebugPrint("HSC===================>ll Insert: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, ll.Start, ll.Length);
|
|
SelectionStart = ll.Start - 7;
|
|
}
|
|
}
|
|
else if (SelectionStart + SelectionLength > ll.End) // Beyond the end of the starting link
|
|
{
|
|
int end = SelectionStart + SelectionLength;
|
|
if (llend != null) end = llend.End; // If it extends into another link extend the end to the end of that link
|
|
DebugPrint("HSC===================>ll After: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, ll.Start, ll.Length);
|
|
SetSelection(ll.Start, end - ll.Start);
|
|
}
|
|
else if (SelectionStart >= ll.Start || SelectionLength > 0)// Within the starting link
|
|
{
|
|
DebugPrint("HSC===================>ll: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, ll.Start, ll.Length);
|
|
SetSelection(ll);
|
|
}
|
|
}
|
|
else if (llend != null)
|
|
{
|
|
DebugPrint("HSC===================>llend: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", SelectionStart, SelectionLength, llend.Start, llend.Length);
|
|
// Check to see if the beginning starts before the <START] token. If it does, adjust the start
|
|
int newStart = SelectionStart + (SelectedText.StartsWith("<START]") ? 7 : 0);
|
|
SetSelection(newStart, llend.End - newStart);
|
|
}
|
|
else
|
|
{
|
|
if (SelectedText.EndsWith("<START]") && !SelectedText.EndsWith("[END><START]"))
|
|
{
|
|
DebugPrint("HSC===================>Removing ending <START] token");
|
|
SelectionLength = SelectionLength - 7;
|
|
}
|
|
if (SelectedText.StartsWith("<START]"))
|
|
{
|
|
DebugPrint("HSC===================>Removing starting <START] token");
|
|
SetSelection(SelectionStart + 7, SelectionLength - 7);
|
|
}
|
|
}
|
|
_AdjustingSelection = false;
|
|
}
|
|
}
|
|
}
|
|
if (startingValue != _AdjustingSelection)
|
|
DebugPrint("================> _AdjustingSelection problem");
|
|
DebugPrint("RS------ SelectionChange > {0}", FindRangeStatus());
|
|
if (SelectionLength > 0 && IsSelectionLinked(SelectionStart, SelectionLength))
|
|
{
|
|
if (SelectedText.IndexOf(@"[END>") > 0) MyLinkText = SelectedText.Substring(0, SelectedText.IndexOf(@"[END>"));
|
|
else MyLinkText = SelectedText;
|
|
}
|
|
else
|
|
MyLinkText = null;
|
|
OnRTBSelectionChanged(this, new EventArgs());
|
|
}
|
|
|
|
//private void HandleOverWrite()
|
|
//{
|
|
// if (!_OverWrite) return;
|
|
// if (SelectionLength > 0) return;
|
|
// if (SelectionStart == TextLength) return;
|
|
// Console.WriteLine("Handle Overwrite, SelectionStart = {0}, SelectionLength = {1}", SelectionStart, SelectionLength);
|
|
// SelectionLength = 1;
|
|
//}
|
|
private bool _CheckSelection = false;
|
|
#endregion
|
|
#region Delete Handlers
|
|
private void HandleDeleteKeyWithSelectedText(KeyEventArgs e, string keychars)
|
|
{
|
|
_ProcessingDelete = true;
|
|
FindRangeStatus();
|
|
//DebugPrint("RS---------------- Delete > {0}", _RTBRangeStatus);
|
|
switch (_RTBRangeStatus)
|
|
{
|
|
case RangeStatus.NoContainedLinks:
|
|
case RangeStatus.Before_After:
|
|
case RangeStatus.Before_EndLink:
|
|
case RangeStatus.Before_EndBox:
|
|
default:
|
|
DeleteCurrentSelection(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.Before_Between: //myRTB1.SelectedText.EndsWith(@"[END><START]")
|
|
DeleteEndBetweenLinks(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.Between_EndBox:
|
|
case RangeStatus.Between_EndLink:
|
|
case RangeStatus.Between_After:
|
|
DeleteStartBetweenLinks(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.Between_Between:
|
|
DeleteBetweenBetweenLinks(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.StartLink_EndBox:
|
|
case RangeStatus.StartLink_EndLink:
|
|
case RangeStatus.StartLink_After:
|
|
ExpandSelectionToIncludeStart();
|
|
DeleteCurrentSelection(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.StartLink_Between:
|
|
ExpandSelectionToIncludeStart();
|
|
DeleteEndBetweenLinks(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.StartBox_EndLink:
|
|
case RangeStatus.StartBox_EndBox:
|
|
case RangeStatus.StartBox_After:
|
|
DeleteFromStartOfBox(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
case RangeStatus.StartBox_Between:
|
|
DeleteFromStartOfBoxEndBetweenLinks(keychars);
|
|
e.SuppressKeyPress = true;
|
|
break;
|
|
// REMOVE THESE CASES OR PUT A MESSAGE OUT SAYING ERROR IN CODE - CASE
|
|
// NOT HANDLED
|
|
case RangeStatus.Before_StartLink:
|
|
case RangeStatus.Between_StartLink:
|
|
case RangeStatus.StartLink_StartLink:
|
|
case RangeStatus.StartBox_StartLink:
|
|
break;
|
|
}
|
|
_ProcessingDelete = false;
|
|
StepRTB_TextChanged(this, new EventArgs());
|
|
}
|
|
private void InsertCharBetweenLinks(LinkLocation ll)
|
|
{
|
|
InsertCharBetweenLinks(ll, ' ', false);
|
|
}
|
|
private void InsertCharBetweenLinks(LinkLocation ll, string strToAdd)
|
|
{
|
|
InsertCharBetweenLinks(ll, strToAdd, true);
|
|
}
|
|
private void InsertCharBetweenLinks(LinkLocation ll, string strToAdd, bool setSelect)
|
|
{
|
|
Rtf = Rtf.Substring(0, ll.StartRtf) + @"\v0 " + strToAdd + @"\v " + Rtf.Substring(ll.StartRtf);
|
|
if (setSelect)
|
|
SelectionStart = ll.Start - 6; // account for <START] - 1 for the character typed
|
|
}
|
|
/// <summary>
|
|
/// This inserts a space in between two links.
|
|
/// It actually inserts "\v0 {space}\v " between the END tag and the START tag
|
|
/// </summary>
|
|
/// <param name="ll"></param>
|
|
/// <param name="charToAdd"></param>
|
|
/// <param name="setSelect"></param>
|
|
private void InsertCharBetweenLinks(LinkLocation ll, char charToAdd, bool setSelect)
|
|
{
|
|
//_InsertingSpaceBetweenLinks = true;
|
|
DebugPrint("ICBLvvvvvvvvvvvvvvv>>>");
|
|
Rtf = Rtf.Substring(0, ll.StartRtf) + @"\v0 " + charToAdd.ToString() + @"\v " + Rtf.Substring(ll.StartRtf);
|
|
//_InsertingSpaceBetweenLinks = false;
|
|
if (setSelect)
|
|
SelectionStart = ll.Start - 6; // account for <START] - 1 for the character typed
|
|
DebugPrint("ICBL^^^^^^^^^^^^^^^>>>");
|
|
}
|
|
private void ExpandSelectionToIncludeStart()
|
|
{
|
|
//_AdjustingSelection = true;
|
|
SetSelection(SelectionStart - 7, SelectionLength + 7); // Expand selection to include start
|
|
//_AdjustingSelection = false;
|
|
}
|
|
private void DeleteBetweenBetweenLinks(string keychars)
|
|
{
|
|
|
|
DebugSelection("DeleteBetweenBetweenLinks");
|
|
int selStart = SelectionStart - 7;
|
|
int selLength = SelectionLength + 2; // Include the two added spaces
|
|
InsertCharBetweenLinks(_RangeEndLink.NextLink); // Add a space at the end link
|
|
InsertCharBetweenLinks(_RangeStartLink); // Add a space a the start link
|
|
SetSelection(selStart, selLength);// Select everything including the spaces
|
|
DeleteCurrentSelection(keychars);// Delete Selection
|
|
}
|
|
/// <summary>
|
|
/// This is added to handle a glitch in richtextbox. Depending on
|
|
/// which direction that selection is made (left -> right or right -> left)
|
|
/// a replacement or delete may not work, you'll just get a 'beep'.
|
|
/// This approach consistently works.
|
|
/// </summary>
|
|
public bool WasXDelete = false;
|
|
private void DeleteCurrentSelection(string keys)
|
|
{
|
|
DebugPrint("vvvvvvvvvvvvxxxxxxxxxxxx>");
|
|
DebugSelection("Before X");
|
|
|
|
SelectedText = keys==null?"X":keys; // replace text with X
|
|
WasXDelete = (keys == null);
|
|
DebugSelection("After X");
|
|
DebugPrint("------------xxxxxxxxxxxx>");
|
|
if (keys == null)
|
|
{
|
|
_SendBackSpace = true;
|
|
RtbSendKeys("{BS}"); // remove X
|
|
//this.ClearUndo(); // undo was redisplay 'X' and then deleted text
|
|
Application.DoEvents();
|
|
DebugSelection("After BS");
|
|
}
|
|
DebugPrint("^^^^^^^^^^^^xxxxxxxxxxxx>");
|
|
}
|
|
private void DeleteSelection(int start, int length, string keychars)
|
|
{
|
|
SetSelection(start, length);
|
|
DeleteCurrentSelection(keychars);
|
|
}
|
|
private void DeleteEndBetweenLinks(string keychars)
|
|
{
|
|
_ProcessingKeys++;
|
|
DebugSelection("DeleteEndBetweenLinks");
|
|
int sstart = SelectionStart;
|
|
int slen = SelectionLength + 1 - 7;
|
|
// This puts a space at the link that starts at the end of the selection
|
|
InsertCharBetweenLinks(_RangeEndLink.NextLink);
|
|
//_AdjustingSelection = true;
|
|
DeleteSelection(sstart, slen, keychars);
|
|
//_AdjustingSelection = false;
|
|
_ProcessingKeys--;
|
|
}
|
|
private void DeleteStartBetweenLinks(string keychars)
|
|
{
|
|
_ProcessingKeys++;
|
|
DebugSelection("DeleteStartBetweenLinks");
|
|
int slen = SelectionLength + 8;
|
|
int sstart = SelectionStart - 7;
|
|
//LinkLocation ll = FindBetweenLinks(SelectionStart);
|
|
InsertCharBetweenLinks(_RangeStartLink);
|
|
DeleteSelection(sstart, slen, keychars);
|
|
_ProcessingKeys--;
|
|
}
|
|
private void DeleteFromStartOfBox(string keychars)
|
|
{
|
|
_ProcessingKeys++;
|
|
DebugSelection("DeleteFromStartOfBox");
|
|
int slen = SelectionLength;
|
|
SetSelection(0, 0);
|
|
//RtbSendKeys(" "); // open for space between links which separates END/START tokens
|
|
SelectedText = " ";
|
|
DeleteSelection(0, slen + 8, keychars);
|
|
_ProcessingKeys--;
|
|
}
|
|
private void DeleteFromStartOfBoxEndBetweenLinks(string keychars)
|
|
{
|
|
_ProcessingKeys++;
|
|
DebugSelection("DeleteFromStartOfBoxEndBetweenLinks");
|
|
// This puts a space at the link that starts at the end of the selection
|
|
int sLen = SelectionStart + SelectionLength - 7 + 2;// -7 for <START] + 2 for the spaces that are added
|
|
//LinkLocation ll = FindBetweenLinks(SelectionStart + SelectionLength);
|
|
InsertCharBetweenLinks(_RangeEndLink.NextLink);
|
|
//RtbSendKeys("{RIGHT} "); // open for space between links which separates END/START tokens
|
|
//int sLen = myRTB1.SelectionStart;
|
|
SetSelection(0, 0);
|
|
//RtbSendKeys(" "); // open for space between links which separates END/START tokens
|
|
SelectedText = " "; // open for space between links which separates END/START tokens
|
|
DeleteSelection(0, sLen, keychars);
|
|
_ProcessingKeys--;
|
|
}
|
|
#endregion
|
|
#region KeyboardHandling
|
|
void StepRTB_KeyUp(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.Control)
|
|
{
|
|
if (this.MyStepItem != null)
|
|
{
|
|
if (e.Alt)
|
|
{
|
|
switch (e.KeyCode)
|
|
{
|
|
case Keys.M:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.btnAnnots_Click(sender, e);
|
|
e.Handled = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (e.Shift)
|
|
{
|
|
switch (e.KeyCode)
|
|
{
|
|
case Keys.F:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsFigure");
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.T:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsTable");
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.N:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsNote");
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.C:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsCaution");
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.S:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsSubStps");
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.H:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsHLS");
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.R:
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("InsRNO");
|
|
e.Handled = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!e.Shift) return;
|
|
switch (e.KeyCode)
|
|
{
|
|
// this was put here rather than in the KeyDown event like the others
|
|
// so that processing of keystroke (StepRTB_KeyDown) would position selectionstart
|
|
// and selectionlength
|
|
case Keys.Down:
|
|
int newend = FindEndDown();
|
|
if (newend > 0) SetSelection(SelectionStart, newend - SelectionStart);
|
|
break;
|
|
case Keys.Space:
|
|
if (e.Control) // Hardspace - Ctrl+Shift+Space
|
|
InsertSymbol(@"\u160?");
|
|
break;
|
|
case Keys.F3: // shift F3
|
|
e.Handled = true;
|
|
ToggleCase(); // toggle through Upper, Lower, and Title case
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private string GetSelectedDisplayableText()
|
|
{
|
|
StepRTB srtb = new StepRTB();
|
|
srtb.Rtf = this.SelectedRtf.Replace(@"\u8209?", "-");
|
|
string rtnstr = "";
|
|
string ctxt = srtb.Text;//this.SelectedText;
|
|
if (ctxt.EndsWith("<START]"))
|
|
ctxt = ctxt.Substring(0, ctxt.Length - 7);
|
|
int idx = 0;
|
|
int strtidx = ctxt.IndexOf("<START]");
|
|
int lnkidx = ctxt.IndexOf("#Link");
|
|
int endidx = ctxt.IndexOf("[END>");
|
|
if ((strtidx == -1 || strtidx > lnkidx) && lnkidx > -1 && endidx > -1)
|
|
{
|
|
rtnstr += ctxt.Substring(idx, lnkidx);
|
|
idx = endidx + 5;
|
|
strtidx = ctxt.IndexOf("<START]", idx);
|
|
lnkidx = ctxt.IndexOf("#Link:", idx);
|
|
endidx = ctxt.IndexOf("[END>", idx);
|
|
}
|
|
while (strtidx > -1)
|
|
{
|
|
rtnstr += ctxt.Substring(idx, strtidx - idx);
|
|
idx = strtidx + 7;
|
|
rtnstr += ctxt.Substring(idx, lnkidx - idx);
|
|
idx = endidx + 5;
|
|
strtidx = ctxt.IndexOf("<START]", idx);
|
|
lnkidx = ctxt.IndexOf("#Link:", idx);
|
|
endidx = ctxt.IndexOf("[END>", idx);
|
|
}
|
|
if (idx < ctxt.Length)
|
|
rtnstr += ctxt.Substring(idx);
|
|
return rtnstr;
|
|
}
|
|
|
|
private bool IsControlChar = false;
|
|
private bool _SendBackSpace = false;
|
|
void StepRTB_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.Control)
|
|
{
|
|
IsControlChar = true;
|
|
switch (e.KeyCode)
|
|
{
|
|
case Keys.X: //ctrl-X
|
|
case Keys.C: //ctrl-C
|
|
// handle the clipboard copy and cut when a Transition or RO is selected
|
|
// For now, we are coping/cutting just the displayed text to the clipboard (like 16-bit VE-PROMS)
|
|
Clipboard.SetText(GetSelectedDisplayableText());
|
|
e.Handled = true;
|
|
e.SuppressKeyPress = true;
|
|
if (e.KeyCode == Keys.X) // cut to clipboard - delete the selected text
|
|
HandleDeleteKeyWithSelectedText(e, null);
|
|
break;
|
|
case Keys.V:
|
|
IDataObject iData = Clipboard.GetDataObject();
|
|
if (!iData.GetDataPresent(DataFormats.Text) && !iData.GetDataPresent(DataFormats.Rtf))
|
|
{
|
|
MessageBox.Show("Cannot paste, text has special characters or symbols that will not paste correctly.");
|
|
}
|
|
else
|
|
{
|
|
Paste();
|
|
if (SelectionLength == 0) SelectionFont = MyStyleFont.WindowsFont;
|
|
}
|
|
e.Handled = true;
|
|
return;
|
|
case Keys.Home:
|
|
StepRTB_HomeEndPressed(e);
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.End:
|
|
StepRTB_HomeEndPressed(e);
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.Enter:
|
|
if (this.MyStepItem != null)
|
|
{
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.btnInsPgBrk_Click(sender, e);
|
|
e.Handled = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
switch (e.KeyCode)
|
|
{
|
|
case Keys.Left:
|
|
if (e.Shift)
|
|
{
|
|
int newstart = FindStart(); // find start of link ending on.
|
|
// if not link, don't do special processing
|
|
if (newstart == SelectionStart - 1) return;
|
|
int len = SelectionLength + SelectionStart - newstart;
|
|
SetSelection(newstart, len);
|
|
e.Handled = true;
|
|
return;
|
|
}
|
|
if (e.Control || SelectionStart == 0)
|
|
{
|
|
StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlLeft : E_ArrowKeys.Left);
|
|
e.Handled = true;
|
|
}
|
|
HandleLocalSelectionChange();
|
|
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;
|
|
}
|
|
// if shift-up & at selection had a link, handle this as special case.
|
|
if (e.Shift && SelectionLength > 0)
|
|
{
|
|
RangeStatus rs = FindRangeStatus();
|
|
if (rs != RangeStatus.NoContainedLinks)
|
|
{
|
|
int curend = SelectionStart + SelectionLength;
|
|
SelectionLength = 0;
|
|
RtbSendKeys("{Up}");
|
|
Application.DoEvents();
|
|
Select(SelectionStart, curend - SelectionStart);
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HandleLocalSelectionChange();
|
|
}
|
|
break;
|
|
case Keys.Right:
|
|
// If at beginning of box that starts with a link, don't worry about shift or not,
|
|
// because selection is first character or link without any other selection. Don't
|
|
// need to write code to handle link at beginning of box in Shift Right code because
|
|
// it's handled in HandleSelectionChange.
|
|
if (e.Shift && ((SelectionStart > 0) || (SelectionStart==0 && _LinkLocations.Count>0 && _LinkLocations[0].Start!=7)))
|
|
{
|
|
int newlen = FindEnd();
|
|
int len = SelectionLength + newlen;
|
|
SetSelection(SelectionStart, len);
|
|
e.Handled = true;
|
|
return;
|
|
}
|
|
if (e.Control || SelectionStart == this.Text.Length)
|
|
{
|
|
StepRTB_ArrowPressed(e.Control ? E_ArrowKeys.CtrlRight : E_ArrowKeys.Right);
|
|
e.Handled = true;
|
|
}
|
|
HandleLocalSelectionChange();
|
|
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);
|
|
HandleLocalSelectionChange();
|
|
e.Handled = true;
|
|
return;
|
|
}
|
|
if (!e.Shift) HandleLocalSelectionChange();
|
|
// if shift-down & on link at beginning of box - do special processing (regular processing
|
|
// didn't handle it correctly.
|
|
if (e.Shift && lastLine > 0 && SelectionStart==0 && _LinkLocations.Count>0 && _LinkLocations[0].Start==7)
|
|
{
|
|
Point cpos = GetPositionFromCharIndex(SelectionStart);
|
|
int addon = ClientRectangle.Height / (lastLine + 1);
|
|
cpos.Y = cpos.Y + addon;
|
|
int selend = GetCharIndexFromPosition(cpos);
|
|
Select(7, selend-7);
|
|
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 (SelectionLength == 0)
|
|
{
|
|
foreach (LinkLocation lls in _LinkLocations)
|
|
{
|
|
if (SelectionStart >= lls.Start - 7 && SelectionStart < lls.End)
|
|
{
|
|
SetSelection(lls);// Select the link to the right
|
|
HandleDeleteKeyWithSelectedText(e, null);
|
|
e.SuppressKeyPress = true;
|
|
return;
|
|
}
|
|
}
|
|
if (SelectionStart != TextLength)
|
|
{
|
|
SelectionStart++;// A Delete can be accomplished with a right arrow followed by a backspace.
|
|
RtbSendKeys("{BS}"); // This is done due to a glitch in the RichTextBox that sometimes causes a beep rather than a delete
|
|
e.SuppressKeyPress = true;
|
|
}
|
|
}
|
|
else
|
|
HandleDeleteKeyWithSelectedText(e, null);
|
|
break;
|
|
case Keys.Back:
|
|
if (_SendBackSpace)
|
|
{
|
|
_SendBackSpace = false;
|
|
return;
|
|
}
|
|
_CheckSelection = true;
|
|
if (SelectionLength == 0)
|
|
{
|
|
foreach (LinkLocation lls in _LinkLocations)
|
|
{
|
|
if (SelectionStart > lls.Start - 7 && SelectionStart <= lls.End)
|
|
{
|
|
SetSelection(lls);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (SelectionLength > 0) HandleDeleteKeyWithSelectedText(e, null);
|
|
break;
|
|
case Keys.Insert:
|
|
//_OverWrite = !_OverWrite;
|
|
//if (_OverWrite)
|
|
//{
|
|
// HandleSelectionChange();
|
|
//}
|
|
//else
|
|
//{
|
|
// SelectionLength = 0;
|
|
// HandleSelectionChange();
|
|
//}
|
|
// For now, don't allow for toggling between insert/overwrite mode - see
|
|
// comment on _OverWrite
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.F5:
|
|
if (this.MyStepItem != null)
|
|
{
|
|
if (e.Shift)
|
|
{
|
|
e.Handled = true;
|
|
if (MyStepItem.MyStepPanel.MyStepTabPanel.MyDisplayTabControl.MyCopyStep == null) return;
|
|
MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ShortCutContextMenu("StepPaste");
|
|
}
|
|
else if (!e.Control && !e.Alt)
|
|
{
|
|
e.Handled = true;
|
|
this.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.DoCopyStep();
|
|
}
|
|
}
|
|
break;
|
|
case Keys.F6:
|
|
e.Handled = true;
|
|
SendKeys.Send("%H{ESC}");
|
|
break;
|
|
case Keys.Tab:
|
|
e.SuppressKeyPress = true;
|
|
e.Handled = true;
|
|
break;
|
|
case Keys.Enter:
|
|
if (!e.Control && !e.Shift && !e.Alt)
|
|
{
|
|
if (MyStepItem != null && !MyStepItem.MyItemInfo.IsTablePart)
|
|
{
|
|
e.Handled = true;
|
|
MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.ProcessEnterKey();
|
|
}
|
|
}
|
|
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); // Replaced with an event
|
|
if (keyargs.Control) OnCursorKeyPress(this, keyargs);
|
|
}
|
|
private void StepRTB_PageKeyPressed(KeyEventArgs keyargs)
|
|
{
|
|
if (MyItemInfo.IsProcedure || MyItemInfo.IsSection) return;
|
|
//_MyStepItem.MyStepPanel.StepCursorKeys(this, keyargs); Replaced with an event
|
|
OnCursorKeyPress(this, keyargs);
|
|
}
|
|
public void StepRTB_ArrowPressed(E_ArrowKeys key)
|
|
{
|
|
Point cp = PointToClient(Cursor.Position);
|
|
//_MyStepItem.MyStepPanel.CursorMovement(this, cp, key); Replaced with an event
|
|
OnCursorMovement(this, new StepRTBCursorMovementEventArgs(cp, key));
|
|
}
|
|
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)
|
|
{
|
|
string strpressed = null;
|
|
if (e.KeyChar == '-')
|
|
strpressed = GetAddSymbolText(@"\u8209?");
|
|
else
|
|
strpressed = e.KeyChar.ToString();
|
|
if (e.KeyChar >= ' ')
|
|
{
|
|
LinkLocation ll = FindBetweenLinks();
|
|
if (ll != null && SelectionLength == 0) // SelectionLength = 0 means insert
|
|
{
|
|
if (e.KeyChar == '}')
|
|
strpressed = @"\}";
|
|
else if (e.KeyChar == '{')
|
|
strpressed = @"\{";
|
|
InsertCharBetweenLinks(ll, strpressed); // e.KeyChar);
|
|
e.Handled = true;
|
|
}
|
|
else if (SelectionLength != 0)
|
|
{
|
|
HandleDeleteKeyWithSelectedText(new KeyEventArgs(Keys.None), strpressed);
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
if (!e.Handled)
|
|
{
|
|
if (e.KeyChar == '-')
|
|
AddSymbol(@"\u8209?");
|
|
else if (e.KeyChar == '{')
|
|
AddRtf(@"\{");
|
|
else if (e.KeyChar == '}')
|
|
AddRtf(@"\}");
|
|
else
|
|
return;
|
|
e.Handled = true; // flag that it's been handled, otherwise, will get 2 chars.
|
|
}
|
|
if (e.Handled && SelectionLength != 0) SelectionFont = MyStyleFont.WindowsFont;
|
|
}
|
|
IsControlChar = false;
|
|
}
|
|
}
|
|
private void RtbSendKeys(string keys)
|
|
{
|
|
Focus();
|
|
SendKeys.Send(keys); // With .Net Framework 3.0 this can be replaced with EditingCommands
|
|
// http://msdn.microsoft.com/en-us/library/ms771634.aspx
|
|
}
|
|
|
|
private void DoDeleteEndBetweenLinks()
|
|
{
|
|
DebugSelection("Beginning");
|
|
int sstart = SelectionStart;
|
|
RtbSendKeys("{RIGHT} "); // open for space between links which separates END/START tokens
|
|
SetSelection(sstart, SelectionStart - sstart - 1); // 1 is accounting for typed space
|
|
DebugSelection("SetSelection");
|
|
RtbSendKeys("{DELETE}"); // deletes text including link
|
|
RtbSendKeys("{RIGHT}{BS}"); // deletes space that was added
|
|
}
|
|
private void DoDeleteStartBetweenLinks()
|
|
{
|
|
int slen = SelectionLength;
|
|
RtbSendKeys("{LEFT} ");
|
|
SetSelection(SelectionStart, slen + 7);
|
|
RtbSendKeys("{DELETE}");
|
|
RtbSendKeys("{BS}");
|
|
}
|
|
#endregion
|
|
#region LinkSelectionAndHandling
|
|
public bool IsSelectionLinked(int index, int len)
|
|
{
|
|
if (_LinkLocations == null)return false;
|
|
int sel = index;
|
|
int selLength = len;
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
// When the selector moved to the right of a link, the GOTO button was still lit.
|
|
// Removing the "+7" seems to have fixed this. - jsj 1/08/2010
|
|
//if (sel >= ll.Start && sel < ll.Start + ll.Length + 7) return true;
|
|
if (sel >= ll.Start && sel < ll.Start + ll.Length) return true;
|
|
}
|
|
return false;
|
|
}
|
|
/// <summary>
|
|
/// For use in Find/Replace.
|
|
/// If text is found is part of the link information and not the link value,
|
|
/// then we want to continue searching.
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="len"></param>
|
|
/// <returns></returns>
|
|
public bool SkipLinkInfo(int index, int len)
|
|
{
|
|
if (_LinkLocations == null)return false;
|
|
int sel = index;
|
|
int selLength = len;
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
if (sel >= ll.Start - 7 && sel < ll.Start + ll.Length)
|
|
{
|
|
int pos = ll.Text.IndexOf("#Link:");
|
|
if (sel < ll.Start || sel >= ll.Start-7+pos)
|
|
return (true);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
#region SelectionStack
|
|
Stack<SelectionData> _SelectionStack = new Stack<SelectionData>();
|
|
public void PushSelection()
|
|
{
|
|
_SelectionStack.Push(new SelectionData(this));
|
|
}
|
|
public void PopSelection()
|
|
{
|
|
SelectionData selection = _SelectionStack.Pop();
|
|
Select(selection.SelectionStart, selection.SelectionLength);
|
|
}
|
|
public class SelectionData
|
|
{
|
|
int _SelectionStart;
|
|
public int SelectionStart
|
|
{
|
|
get { return _SelectionStart; }
|
|
set { _SelectionStart = value; }
|
|
}
|
|
int _SelectionLength;
|
|
public int SelectionLength
|
|
{
|
|
get { return _SelectionLength; }
|
|
set { _SelectionLength = value; }
|
|
}
|
|
public SelectionData(RichTextBox richTextBox)
|
|
{
|
|
_SelectionStart = richTextBox.SelectionStart;
|
|
_SelectionLength = richTextBox.SelectionLength;
|
|
}
|
|
}
|
|
#endregion
|
|
#region Link Support
|
|
int _ProcessingKeys = 0;
|
|
|
|
List<LinkLocation> _LinkLocations;
|
|
public List<LinkLocation> LinkLocations
|
|
{
|
|
get { return _LinkLocations; }
|
|
}
|
|
private int _FALLevel = 0;
|
|
private bool _IdentifyingLinks = false;
|
|
public void FindAllLinks()
|
|
{
|
|
if (_IdentifyingLinks || _ProcessingDelete) return;
|
|
//DebugPrint("FAL{0}vvvvvvvvvvvvvvvvvvvvvvvvv>>", ++_FALLevel);
|
|
_AdjustingSelection = true;
|
|
PushSelection();
|
|
FindLinks();
|
|
//IdentifyLinks();
|
|
PopSelection();
|
|
LinkLocation llx = FindLinkLocation();
|
|
if (_CheckSelection)
|
|
{
|
|
if (llx != null) SetSelection(llx.End, 0);
|
|
_CheckSelection = false;
|
|
}
|
|
_AdjustingSelection = false;
|
|
if (!_ProcessingDelete)
|
|
OnLinkLocationChanged(this, new EventArgs());
|
|
//DebugPrint("FAL{0}^^^^^^^^^^^^^^^^^^^^^^^^^>>", _FALLevel--);
|
|
|
|
}
|
|
private void FindLinks()
|
|
{
|
|
string str = Text;
|
|
_LinkLocations = new List<LinkLocation>();
|
|
MatchCollection matches = Regex.Matches(str, @"<START](.*?)[[]END>", RegexOptions.Singleline);
|
|
MatchCollection matchesRtf = Regex.Matches(Rtf, "<START](.*?)[[]END>", RegexOptions.Singleline);
|
|
LinkLocation thisLink = null;
|
|
for (int i = 0; i < matches.Count; i++) //each (Match match in matches)
|
|
{
|
|
Match match = matches[i];
|
|
Match matchrtf = matchesRtf[i];
|
|
thisLink = new LinkLocation(match.Index + 7, // If the [END> is immediately followed by <START] include it
|
|
match.Length - (((match.Index + match.Length + 7 <= str.Length) && (str.Substring(match.Index + match.Length, 7) == "<START]")) ? 0 : 7),
|
|
match.Value, matchrtf.Index, matchrtf.Length, thisLink);
|
|
_LinkLocations.Add(thisLink);
|
|
}
|
|
}
|
|
private LinkLocation FindBetweenLinks()
|
|
{
|
|
return FindBetweenLinks(SelectionStart);
|
|
}
|
|
private LinkLocation FindBetweenLinks(int start)
|
|
{
|
|
DebugPrint("FL----------------Between>");
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
if (ll.Start == start && ll.StartsBetween)
|
|
return ll;
|
|
return null;
|
|
}
|
|
private LinkLocation FindLinkLocation()
|
|
{
|
|
return FindLinkLocation(SelectionStart);
|
|
}
|
|
private LinkLocation FindLinkLocation(int sel)
|
|
{
|
|
//DebugPrint("FL----------------Location>");
|
|
if (_LinkLocations == null) return null;
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
// Moving right:
|
|
// if less than, allows stopping between two links
|
|
if (ll.Start < sel && ll.End > sel)
|
|
{
|
|
DebugPrint("Greater Than {0} {1} {2}", sel, ll.Start, ll.End);
|
|
return ll;
|
|
}
|
|
// if less than or equal, does not stop between two links
|
|
if ((!ll.StartsBetween) && ll.Start <= sel && ll.End > sel)
|
|
{
|
|
DebugPrint("Greater Than or Equal {0} {1} {2}", sel, ll.Start, ll.End);
|
|
return ll;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
public DialogResult ReplaceText(string rpltxt, string fndstr, bool caseSensitive, bool matchWholeWord, bool reverse, bool prompt, IWin32Window fndrpldlg)
|
|
{
|
|
DialogResult dlgrslt = DialogResult.Yes;
|
|
if (SelectionLength > 0)
|
|
{
|
|
if (IsSelectionLinked(SelectionStart, SelectionLength))
|
|
{
|
|
MessageBox.Show(fndrpldlg,"Cannot replace linked text!", "Find/Replace");
|
|
dlgrslt = DialogResult.No;
|
|
}
|
|
else
|
|
{
|
|
if (prompt)
|
|
dlgrslt = MessageBox.Show(fndrpldlg,"Replace This Occurence?", "Replace Text", MessageBoxButtons.YesNoCancel);
|
|
if (dlgrslt == DialogResult.Yes)
|
|
SelectedText = rpltxt;
|
|
}
|
|
}
|
|
return dlgrslt;
|
|
}
|
|
private RichTextBoxFinds _FindOptions = RichTextBoxFinds.None;
|
|
public bool FindText(string str, bool caseSensitive, bool matchWholeWord, bool reverse)
|
|
{
|
|
StepRTB savRTF = new StepRTB();
|
|
int startpos = SelectionStart + SelectionLength;
|
|
savRTF.Text = this.Text;
|
|
|
|
_FindOptions = RichTextBoxFinds.None;
|
|
if (caseSensitive)
|
|
_FindOptions |= RichTextBoxFinds.MatchCase;
|
|
if (matchWholeWord)
|
|
_FindOptions |= RichTextBoxFinds.WholeWord;
|
|
if (reverse)
|
|
{
|
|
_FindOptions |= RichTextBoxFinds.Reverse;
|
|
savRTF.Text = this.Text.Substring(0, SelectionStart);
|
|
startpos = savRTF.Text.Length;
|
|
if (startpos == 0)
|
|
return false; // at beginning of rtfbox during a reverse find
|
|
}
|
|
else
|
|
{
|
|
if (startpos >= savRTF.Text.Length)
|
|
return false; // at end of rtfbox during a forward find
|
|
}
|
|
// look for the find string in the temporary rtfbox
|
|
// then set the cursor selection in the real rtfbox
|
|
bool keepgoing = true;
|
|
while (keepgoing)
|
|
{
|
|
int pos = savRTF.Find(str, startpos, _FindOptions);
|
|
keepgoing = false;
|
|
if (pos >= 0)
|
|
{
|
|
if (this.SkipLinkInfo(pos, str.Length))
|
|
{
|
|
if (reverse)
|
|
{
|
|
startpos--;
|
|
savRTF.Text = savRTF.Text.Substring(0, startpos);
|
|
}
|
|
else
|
|
startpos++;
|
|
if (startpos > 0 && startpos < savRTF.Text.Length)
|
|
keepgoing = true;
|
|
}
|
|
else
|
|
{
|
|
SelectionStart = pos;
|
|
SelectionLength = str.Length;
|
|
}
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
private int FindStart()
|
|
{
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
if (SelectionStart == ll.End) return ll.Start;
|
|
if (SelectionStart == ll.Start)
|
|
{
|
|
if (ll.Start == 7) return 7;
|
|
return ll.Start - 8;
|
|
}
|
|
}
|
|
if (SelectionStart > 0) return SelectionStart - 1;
|
|
return 0;
|
|
}
|
|
private int FindEnd()
|
|
{
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
if (SelectionStart + SelectionLength + 7 == ll.Start) return ll.Length + 7;
|
|
// this is for in-between links
|
|
if (SelectionStart + SelectionLength == ll.Start) return ll.Length;
|
|
}
|
|
if (SelectionStart + SelectionLength < TextLength) return 1;
|
|
return 0;
|
|
}
|
|
private int FindEndDown()
|
|
{
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
if (SelectionStart + SelectionLength >= ll.Start && SelectionStart + SelectionLength <= ll.End) return ll.End;
|
|
}
|
|
return 0;
|
|
}
|
|
private int FindStartUp()
|
|
{
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
if ((SelectionStart >= ll.Start) && (SelectionStart <= ll.End)) return ll.Start;
|
|
}
|
|
return -1;
|
|
}
|
|
public void SetSelection(LinkLocation ll)
|
|
{
|
|
SetSelection(ll.Start, ll.Length);
|
|
}
|
|
public void SetSelection(int locStart, int locLength)
|
|
{
|
|
//Application.DoEvents(); // Not needed since SendKeys is always done last.
|
|
if (_IdentifyingLinks)
|
|
DebugPrint("SS------------------------> {0} {1}", locStart, locLength);
|
|
else
|
|
DebugPrint("SS========================> {0} {1}", locStart, locLength);
|
|
Select(locStart, locLength);
|
|
}
|
|
#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
|
|
#region EnumsSelectionRange
|
|
private enum StartStatus : int
|
|
{
|
|
Before = 100,
|
|
Between = 200,
|
|
StartLink = 300,
|
|
StartBox = 400
|
|
};
|
|
private enum EndStatus : int
|
|
{
|
|
After = 1,
|
|
Between = 2,
|
|
EndLink = 3,
|
|
EndBox = 4,
|
|
StartLink = 5
|
|
};
|
|
public enum RangeStatus : int
|
|
{
|
|
NoContainedLinks = 0,
|
|
Before_After = StartStatus.Before + EndStatus.After,
|
|
Before_Between = StartStatus.Before + EndStatus.Between,
|
|
Before_EndLink = StartStatus.Before + EndStatus.EndLink,
|
|
Before_EndBox = StartStatus.Before + EndStatus.EndBox,
|
|
Before_StartLink = StartStatus.Before + EndStatus.StartLink,
|
|
Between_After = StartStatus.Between + EndStatus.After,
|
|
Between_Between = StartStatus.Between + EndStatus.Between,
|
|
Between_EndLink = StartStatus.Between + EndStatus.EndLink,
|
|
Between_EndBox = StartStatus.Between + EndStatus.EndBox,
|
|
Between_StartLink = StartStatus.Between + EndStatus.StartLink,
|
|
StartLink_After = StartStatus.StartLink + EndStatus.After,
|
|
StartLink_Between = StartStatus.StartLink + EndStatus.Between,
|
|
StartLink_EndLink = StartStatus.StartLink + EndStatus.EndLink,
|
|
StartLink_EndBox = StartStatus.StartLink + EndStatus.EndBox,
|
|
StartLink_StartLink = StartStatus.StartLink + EndStatus.StartLink,
|
|
StartBox_After = StartStatus.StartBox + EndStatus.After,
|
|
StartBox_Between = StartStatus.StartBox + EndStatus.Between,
|
|
StartBox_EndLink = StartStatus.StartBox + EndStatus.EndLink,
|
|
StartBox_EndBox = StartStatus.StartBox + EndStatus.EndBox,
|
|
StartBox_StartLink = StartStatus.StartBox + EndStatus.StartLink
|
|
};
|
|
private RangeStatus _RTBRangeStatus;
|
|
public RangeStatus RTBRangeStatus
|
|
{
|
|
get { return _RTBRangeStatus; }
|
|
set
|
|
{
|
|
_RTBRangeStatus = value;
|
|
if (!_ProcessingDelete) OnRTBRangeStatusChanged(this, new EventArgs());
|
|
}
|
|
}
|
|
private LinkLocation _RangeStartLink = null;
|
|
private LinkLocation _RangeEndLink = null;
|
|
public RangeStatus FindRangeStatus()
|
|
{
|
|
_RangeStartLink = null;
|
|
_RangeEndLink = null;
|
|
if (_LinkLocations == null || _LinkLocations.Count == 0)
|
|
{
|
|
return RTBRangeStatus = RangeStatus.NoContainedLinks;
|
|
}
|
|
LinkLocation foundLink = null;
|
|
int start = SelectionStart;
|
|
int end = start + SelectionLength;
|
|
|
|
foreach (LinkLocation ll in _LinkLocations)
|
|
{
|
|
if (foundLink == null && ((ll.Start >= start && ll.Start < end) || (ll.End >= start && ll.End < end)))
|
|
foundLink = ll;
|
|
if (_RangeStartLink == null && start >= ll.Start - 7 && start < ll.End)
|
|
_RangeStartLink = ll;
|
|
if (_RangeEndLink == null && end >= ll.Start && end <= ll.End)
|
|
_RangeEndLink = ll;
|
|
}
|
|
DebugPrint("SelectionStart {0}, SelectionEnd {1}, TextLength {2}",
|
|
SelectionStart, SelectionStart + SelectionLength,
|
|
TextLength);
|
|
//if (_RangeStartLink != null)
|
|
// _RangeStartLink.Show("startLink");
|
|
//if (_RangeEndLink != null)
|
|
// _RangeEndLink.Show("endLink");
|
|
//if (foundLink != null)
|
|
// foundLink.Show("foundLink");
|
|
|
|
if (foundLink == null)
|
|
return RTBRangeStatus = RangeStatus.NoContainedLinks;
|
|
|
|
StartStatus myStartStatus = StartStatus.Before;
|
|
EndStatus myEndStatus = EndStatus.After;
|
|
if (_RangeStartLink != null)
|
|
{
|
|
if (_RangeStartLink.Start == 7)
|
|
myStartStatus = StartStatus.StartBox;
|
|
else if (_RangeStartLink.StartsBetween)
|
|
myStartStatus = StartStatus.Between;
|
|
else
|
|
myStartStatus = StartStatus.StartLink;
|
|
}
|
|
if (_RangeEndLink != null)
|
|
{
|
|
if (_RangeEndLink.End == TextLength)
|
|
myEndStatus = EndStatus.EndBox;
|
|
else if (_RangeEndLink.NextStart == _RangeEndLink.End)
|
|
myEndStatus = EndStatus.Between;
|
|
else if (end == _RangeEndLink.Start)
|
|
myEndStatus = EndStatus.StartLink; // Should not happen because of code in HandleSelectionChange
|
|
else //if (end == endLink.End)
|
|
myEndStatus = EndStatus.EndLink;
|
|
}
|
|
return RTBRangeStatus = (RangeStatus)((int)myStartStatus + (int)myEndStatus);
|
|
}
|
|
#endregion
|
|
#region OutlineTable
|
|
private string _CheckRight = "-\u2500\u2011";
|
|
public string CheckRight
|
|
{
|
|
get { return _CheckRight; }
|
|
set { _CheckRight = value; }
|
|
}
|
|
private string _CheckAbove = "|\u2502\u2514\u252c\u253c\u251c\u250c\u2534\u2510\u2524";
|
|
public string CheckAbove
|
|
{
|
|
get { return _CheckAbove; }
|
|
set { _CheckAbove = value; }
|
|
}
|
|
private string _CheckLeft = "-\u2500\u2524\u252c\u251c\u253c\u250c\u2510\u2514\u2011";
|
|
public string CheckLeft
|
|
{
|
|
get { return _CheckLeft; }
|
|
set { _CheckLeft = value; }
|
|
}
|
|
private string _CheckBelow = "|\u2502";
|
|
public string CheckBelow
|
|
{
|
|
get { return _CheckBelow; }
|
|
set { _CheckBelow = value; }
|
|
}
|
|
// This is a table of graphics characters
|
|
// The index into this table (0-15) is a bitmask with each bit representing
|
|
// a different direction from the current character.
|
|
// Right is Bit 0 (0 or 1)
|
|
// Above is Bit 1 (0 or 2)
|
|
// Left is Bit 2 (0 or 4)
|
|
// Below is Bit 3 (0 or 8)
|
|
// The index is contolled in the following way:
|
|
// If there is a graphics character to the right, then you add 1
|
|
// If there is a graphics character above, then you add 2
|
|
// If there is a graphics character left, then you add 4
|
|
// If there is a graphics character below, then you add 8
|
|
// The total results in an index into this array and gives the appropriate character
|
|
// combining horizontal and vertical lines.
|
|
|
|
static private string [] TableCharsU = {
|
|
"\x0", // HEX"\x0", // No character
|
|
@"\u9472", // HEX@"\u2500",// - Horizontal line - 16-bit char: '\xC4'
|
|
@"\u9474", // HEX@"\u2502",// | Vertical line - 16-bit char: '\xB3'
|
|
@"\u9492", // HEX@"\u2514",// L Bottom Left corner - 16-bit char: '\xC0'
|
|
@"\u9472", // HEX@"\u2500",// - Horizontal line - 16-bit char: '\xC4'
|
|
@"\u9472", // HEX@"\u2500",// - Horizontal line - 16-bit char: '\xC4'
|
|
@"\u9496", // HEX@"\u2518",// Bottom Right Corner - 16-bit char: '\xD9'
|
|
@"\u9524", // HEX@"\u2534",// Bottom Tee - 16-bit char: '\xC1'
|
|
@"\u9474", // HEX@"\u2502",// | Vertical Bar - 16-bit char: '\xB3'
|
|
@"\u9484", // HEX@"\u250c",// Upper Left corner - 16-bit char: '\xDA'
|
|
@"\u9474", // HEX@"\u2502",// | Vertical Bar - 16-bit char: '\xB3'
|
|
@"\u9500", // HEX@"\u251c",// Left Tee - 16-bit char: '\xC3'
|
|
@"\u9488", // HEX@"\u2510",// Upper Right corner - 16-bit char: '\xBF'
|
|
@"\u9516", // HEX@"\u252c",// T Top Tee - 16-bit char: '\xC2'
|
|
@"\u9508", // HEX@"\u2524",// Right Tee - 16-bit char: '\xB4'
|
|
@"\u9532", // HEX@"\u253c" // + Plus - 16-bit char: '\xC5'
|
|
};
|
|
|
|
private int MaxCharacterWidth()
|
|
{
|
|
// loop through lines and get the width in characters
|
|
int w = 0;
|
|
foreach (string line in Lines)
|
|
{
|
|
string cleanLine = RemoveLinkComments(line);
|
|
if (w < cleanLine.Length)
|
|
w = cleanLine.Length;
|
|
}
|
|
return w;
|
|
}
|
|
internal static string RemoveLinkComments(string line)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
int lastIndex = 0;
|
|
MatchCollection mc = Regex.Matches(line, @"<START\](.*?)#Link.*?\[END>");
|
|
foreach (Match m in mc)
|
|
{
|
|
sb.Append(line.Substring(lastIndex, m.Index - lastIndex)); // Append text before the link
|
|
sb.Append(m.Groups[1].Value); // Append the text portion of the link
|
|
lastIndex = m.Index + m.Length; // Calculate the beginning of the remaining text
|
|
}
|
|
sb.Append(line.Substring(lastIndex)); // Append the text following the last link
|
|
string result = sb.ToString();
|
|
result = result.Replace(@"<START]", "");
|
|
MatchCollection mcEnd = Regex.Matches(result, @"#Link.*?\[END>");
|
|
if (mcEnd.Count > 0)
|
|
{
|
|
result = result.Substring(0, mcEnd[0].Index) + result.Substring(mcEnd[0].Index + mcEnd[0].Length);
|
|
}
|
|
return result;
|
|
}
|
|
private void ReplaceLinesInTable(bool withBorder)
|
|
{
|
|
int rowWidth = Lines[0].Length;
|
|
for (int row=1;row<Lines.Length-1;row++)
|
|
{
|
|
string line = Lines[row];
|
|
string lineAbove = RemoveLinkComments(Lines[row-1]);
|
|
string lineBelow = RemoveLinkComments(Lines[row+1]);
|
|
int rowOffset = GetFirstCharIndexFromLine(row);
|
|
MatchCollection matchCollection = Regex.Matches(line, @"<START\](.*?)#Link.*?\[END>"); //, RegexOptions.Singleline);
|
|
if (matchCollection.Count == 0) matchCollection = Regex.Matches(line, @"<START\]");
|
|
if (matchCollection.Count == 0) matchCollection = Regex.Matches(line, @"#Link.*?\[END>");
|
|
Match match = matchCollection.Count > 0 ? matchCollection[0] : null;
|
|
int matchOffset = 0;
|
|
for (int col = 1; col < rowWidth - 1; col++)
|
|
{
|
|
if (match != null && match.Index == matchOffset + col)
|
|
{
|
|
matchOffset += match.Length - match.Groups[1].Length; // Increment the offset by the link comment length
|
|
col += match.Groups[1].Length; // increment the column by the link value length
|
|
if (col >= rowWidth - 1) break;// Don't continue if beyond the contents
|
|
match = match.NextMatch(); // Watch for the next match
|
|
}
|
|
int coll = matchOffset + col;
|
|
char chr = line[coll];
|
|
char chrLast = line[coll - 1];
|
|
char chrNext = line[coll + 1];
|
|
char chrAbove = lineAbove[col];
|
|
char chrBelow = lineBelow[col];
|
|
// The following is all using symbol font (either unicode for proportional or
|
|
// VeSymbFix for fixed font):
|
|
// if this character is a table line draw character, i.e. a dash or vertical bar, or
|
|
// graphics characters for those, look around it to see what table character it is
|
|
// replaced with
|
|
|
|
// Look for -||-- (last three are graphics chars or unicode dash)
|
|
if ("-|\u2500\u2502\u2011".IndexOf(chr) > -1)
|
|
{
|
|
bool horizontalCharacter = "-\u2500\u2011".IndexOf(chr) > -1;
|
|
int lineDrawRight = (CheckRight.IndexOf(chrNext) > -1 || (horizontalCharacter && "\u2502".IndexOf(chrNext) > -1)) ? 1 : 0;
|
|
int lineDrawAbove = (CheckAbove.IndexOf(chrAbove) > -1 || (!horizontalCharacter && "\u2500\u2011".IndexOf(chrAbove) > -1)) ? 2 : 0;
|
|
int lineDrawLeft = (CheckLeft.IndexOf(chrLast) > -1 || (horizontalCharacter && "\u2502".IndexOf(chrLast) > -1)) ? 4 : 0;
|
|
int lineDrawBelow = (CheckBelow.IndexOf(chrBelow) > -1 || (!horizontalCharacter && "-\u2500\u2011".IndexOf(chrBelow) > -1)) ? 8 : 0;
|
|
int tableCharIndx = lineDrawRight + lineDrawAbove + lineDrawLeft + lineDrawBelow;
|
|
if (tableCharIndx > 0)
|
|
{
|
|
SetTableChar(row, coll, tableCharIndx);
|
|
if (withBorder) // Adjust the border as it intersects with lines within the box
|
|
{
|
|
if (row == 1 && !horizontalCharacter ) SetTableChar(row - 1, col, 13); // Top Row
|
|
if (row == Lines.Length - 2 && !horizontalCharacter) SetTableChar(row + 1, col, 7); // Bottom Row
|
|
if (col == 1 && horizontalCharacter && ((tableCharIndx & 4)==4)) SetTableChar(row, col - 1, 11); // First Column
|
|
if (col == rowWidth - 2 && horizontalCharacter && ((tableCharIndx & 1) == 1)) SetTableChar(row, coll + 1, 14); // Last Column
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private void SetTableChar(int row, int col, int tableCharIndx)
|
|
{
|
|
int rowOffset = GetFirstCharIndexFromLine(row);
|
|
Select(rowOffset + col, 1);
|
|
string charToBeReplaced = SelectedText;
|
|
if (Text.Length > (rowOffset + col + 7) && Text.Substring(rowOffset + col + 1, 6) != "#Link:")
|
|
SelectedRtf = RtfPrefix + TableCharsU[tableCharIndx] + "?}";
|
|
else
|
|
{
|
|
SelectionStart++;
|
|
int lenComment = 1 + SelectionStart - (rowOffset + col);
|
|
//Console.WriteLine("{0},{1},{2}", rowOffset + col, SelectionStart, SelectionLength);
|
|
Select(rowOffset + col, 0);
|
|
SelectedRtf = RtfPrefix + TableCharsU[tableCharIndx] + "?}";
|
|
Select(rowOffset + col, lenComment);
|
|
//Console.WriteLine("'{0}',{1},{2},{3}", SelectedText, lenComment, SelectionLength, SelectionStart);
|
|
//Console.WriteLine("'{0}'", SelectedRtf);
|
|
SelectedRtf = SelectedRtf.Replace(" " + charToBeReplaced, "");
|
|
}
|
|
}
|
|
#endregion
|
|
#region SpellChecker
|
|
// We made the Spell Checker method a static so that all of the StepRTB boxes will sbare the same instace of the dictionary.
|
|
// This allow all the StepRTB's to automatically update when a new word is added.
|
|
private static C1.Win.C1SpellChecker.C1SpellChecker _C1SpellChecker2;
|
|
|
|
private static C1.Win.C1SpellChecker.C1SpellChecker C1SpellChecker2
|
|
{
|
|
get
|
|
{
|
|
if (_C1SpellChecker2 == null)
|
|
{
|
|
_C1SpellChecker2 = new C1.Win.C1SpellChecker.C1SpellChecker();
|
|
_C1SpellChecker2.ContextMenuCreated += new C1.Win.C1SpellChecker.ContextMenuEventHandler(_C1SpellChecker2_ContextMenuCreated);
|
|
//_C1SpellChecker2.UserDictionary.FileName = @"C:\Development\proms\VEPROMS User Interface\bin\Debug\MYDictionary.dct";
|
|
}
|
|
return StepRTB._C1SpellChecker2;
|
|
}
|
|
}
|
|
|
|
// Get or Save our context menu
|
|
// This is added to the the spell checker's context menu for a mis-spelled word
|
|
private static ContextMenuStrip _ThisContextMenuStrip;
|
|
public ContextMenuStrip ThisContextMenuStrip
|
|
{
|
|
get { return _ThisContextMenuStrip; }
|
|
set { _ThisContextMenuStrip = value; }
|
|
}
|
|
|
|
private static StepRTB _ContextMenuStepRTB;
|
|
private static object _ContextMenuStrip;
|
|
|
|
static void _C1SpellChecker2_ContextMenuCreated(object sender, C1.Win.C1SpellChecker.ContextMenuEventArgs e)
|
|
{
|
|
// Adjust their bad word context menu
|
|
//Console.WriteLine("==========> spell check context menu {0}",e.Menu.Items[0].Text);
|
|
if (e.Menu.Equals(_ContextMenuStrip))
|
|
{
|
|
// Add an item for our "Edit Menu" context menu on their spell check context menu
|
|
// This gives the user access to our regular context menu when on a mis-spelled word
|
|
ToolStripItem tsi = e.Menu.Items.Add("Edit Menu");
|
|
tsi.Click += new EventHandler(tsi_Click);
|
|
//Now replace their "Spell" item with ours, so that we can display our custom spell check dialog
|
|
for (int i = 0; i < e.Menu.Items.Count; i++)
|
|
{
|
|
ToolStripItem tsi1 = e.Menu.Items[i];
|
|
if (tsi1 is ToolStripMenuItem && tsi1.Text == "Spell")
|
|
{
|
|
e.Menu.Items.RemoveAt(i); // remove their spell check dialog item
|
|
ToolStripMenuItem tsi2 = new ToolStripMenuItem("Spell");
|
|
tsi2.Click += new EventHandler(tsi2_Click);
|
|
e.Menu.Items.Insert(i, tsi2); // add our spell check dialog item
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void tsi2_Click(object sender, EventArgs e)
|
|
{
|
|
C1SpellChecker2.CheckControl(_ContextMenuStepRTB, true, MySpellCheckDlg);
|
|
}
|
|
|
|
// Click event to display our "Edit Menu" (StepRTB context menu)
|
|
static void tsi_Click(object sender, EventArgs e)
|
|
{
|
|
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
|
|
_ContextMenuStepRTB.MyStepItem.MyStepPanel.MyStepTabPanel.MyStepTabRibbon.OpenContextMenu(tsmi.Owner.Location);
|
|
}
|
|
|
|
// This is our customized Spell Check dialog
|
|
// This is display when the use clicks the Spell button from the Ribbon
|
|
// or when the "Spell" item is selected from the context menu when on a mis-spelled word
|
|
static VlnSpellCheckDlg _MySpellCheckDlg;
|
|
public static VlnSpellCheckDlg MySpellCheckDlg
|
|
{
|
|
get
|
|
{
|
|
if (_MySpellCheckDlg == null)
|
|
_MySpellCheckDlg = new VlnSpellCheckDlg();
|
|
return _MySpellCheckDlg;
|
|
}
|
|
}
|
|
|
|
// This is used when walking through the section doing a spell check
|
|
// (from the Spell button on the ribbon)
|
|
public bool SpellCheckNext()
|
|
{
|
|
int nBad = C1SpellChecker2.CheckControl(this, false, MySpellCheckDlg);
|
|
return (nBad >= 0); // nBad = -1 means user pressed Cancel button
|
|
}
|
|
|
|
#endregion
|
|
#region Debug
|
|
private bool _ShowDebug = false;
|
|
public bool ShowDebug
|
|
{
|
|
get { return _ShowDebug; }
|
|
set { _ShowDebug = value; }
|
|
}
|
|
private void DebugPrint(string where, string format, params object[] myParams)
|
|
{
|
|
DebugPrint(where + string.Format(format, myParams));
|
|
}
|
|
private void DebugPrint(string format, params object[] myParams)
|
|
{
|
|
if (_ShowDebug)
|
|
Console.WriteLine(format, myParams);
|
|
}
|
|
private void DebugSelection(string where)
|
|
{
|
|
DebugPrint(where, ": {0} {1} '{2}'", SelectionStart, SelectionLength, SelectedText);
|
|
}
|
|
#endregion
|
|
|
|
private void StepRTB_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
|
|
{
|
|
//Console.WriteLine("StepRTB_PreviewKeyDown");
|
|
if ((e.KeyCode == Keys.Tab) && (!e.Alt && !e.Control))
|
|
e.IsInputKey = true;
|
|
}
|
|
}
|
|
public partial class StepRTBModeChangeEventArgs : EventArgs
|
|
{
|
|
private E_ViewMode _ViewMode;
|
|
public E_ViewMode ViewMode
|
|
{
|
|
get { return _ViewMode; }
|
|
set { _ViewMode = value; }
|
|
}
|
|
public StepRTBModeChangeEventArgs(E_ViewMode vmode)
|
|
{
|
|
_ViewMode = vmode;
|
|
}
|
|
}
|
|
public class StepRTBCursorMovementEventArgs
|
|
{
|
|
private Point _CursorLocation;
|
|
public Point CursorLocation
|
|
{
|
|
get { return _CursorLocation; }
|
|
set { _CursorLocation = value; }
|
|
}
|
|
private E_ArrowKeys _Key;
|
|
public E_ArrowKeys Key
|
|
{
|
|
get { return _Key; }
|
|
set { _Key = value; }
|
|
}
|
|
public StepRTBCursorMovementEventArgs(Point pt, E_ArrowKeys key)
|
|
{
|
|
_CursorLocation = pt;
|
|
_Key = key;
|
|
}
|
|
}
|
|
#region LinkLocation Class
|
|
public class LinkLocation
|
|
{
|
|
private int _Start;
|
|
public int Start
|
|
{
|
|
get { return _Start; }
|
|
set { _Start = value; }
|
|
}
|
|
private int _Length;
|
|
public int Length
|
|
{
|
|
get { return _Length; }
|
|
set { _Length = value; }
|
|
}
|
|
public int End
|
|
{
|
|
get { return _Length + _Start; }
|
|
}
|
|
private int _StartRtf;
|
|
public int StartRtf
|
|
{
|
|
get { return _StartRtf; }
|
|
set { _StartRtf = value; }
|
|
}
|
|
private int _LengthRtf;
|
|
public int LengthRtf
|
|
{
|
|
get { return _LengthRtf; }
|
|
set { _LengthRtf = value; }
|
|
}
|
|
public int EndRtf
|
|
{
|
|
get { return _LengthRtf + _StartRtf; }
|
|
}
|
|
private string _Text;
|
|
public string Text
|
|
{
|
|
get { return _Text; }
|
|
set { _Text = value; }
|
|
}
|
|
private LinkLocation _PreviousLink = null;
|
|
public LinkLocation PreviousLink
|
|
{
|
|
get { return _PreviousLink; }
|
|
set
|
|
{
|
|
_PreviousLink = value;
|
|
value.NextLink = this;
|
|
}
|
|
}
|
|
private LinkLocation _NextLink = null;
|
|
public LinkLocation NextLink
|
|
{
|
|
get { return _NextLink; }
|
|
set { _NextLink = value; }
|
|
}
|
|
public int PreviousEnd
|
|
{
|
|
get { return PreviousLink == null ? -1 : PreviousLink.End; }
|
|
}
|
|
public bool StartsBetween
|
|
{
|
|
get { return PreviousEnd == Start; }
|
|
}
|
|
public int NextStart
|
|
{
|
|
get { return NextLink == null ? -1 : NextLink.Start; }
|
|
}
|
|
public bool EndsBetween
|
|
{
|
|
get { return NextStart == End; }
|
|
}
|
|
public LinkLocation(int start, int length, string text, int startRtf, int lengthRtf, LinkLocation previousLink)
|
|
{
|
|
_Start = start;
|
|
_Length = length;
|
|
_Text = text;
|
|
_StartRtf = startRtf;
|
|
_LengthRtf = lengthRtf;
|
|
if (previousLink != null) PreviousLink = previousLink;
|
|
}
|
|
public override string ToString()
|
|
{
|
|
return (string.Format("{0}, {1}", Start, End));
|
|
}
|
|
public void Show(string str)
|
|
{
|
|
if (PreviousLink != null)
|
|
Console.WriteLine("LinkLocation: {0}.PreviousLink {1}", str, PreviousLink);
|
|
Console.WriteLine("LinkLocation: {0} {1}", str, this);
|
|
if (NextLink != null)
|
|
Console.WriteLine("LinkLocation: {0}.NextLink {1}", str, NextLink);
|
|
}
|
|
// #region ClipboardHandler
|
|
// private const int WM_CUT = 0x0300;
|
|
// private const int WM_COPY = 0x0301;
|
|
// private const int WM_PASTE = 0x0302;
|
|
|
|
// public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);
|
|
|
|
// [Category("Clipboard")]
|
|
// public event ClipboardEventHandler CutText;
|
|
// [Category("Clipboard")]
|
|
// public event ClipboardEventHandler CopiedText;
|
|
// [Category("Clipboard")]
|
|
// public event ClipboardEventHandler PastedText;
|
|
|
|
// protected override void WndProc(ref Message m)
|
|
// {
|
|
// if (m.Msg == WM_CUT)
|
|
// {
|
|
// if (CutText != null)
|
|
// CutText(this, new ClipboardEventArgs(this.SelectedText));
|
|
// }
|
|
// else if (m.Msg == WM_COPY)
|
|
// {
|
|
// if (CopiedText != null)
|
|
// CopiedText(this, new ClipboardEventArgs(this.SelectedText));
|
|
// }
|
|
// else if (m.Msg == WM_PASTE)
|
|
// {
|
|
// if (PastedText != null)
|
|
// PastedText(this, new ClipboardEventArgs(Clipboard.GetText()));
|
|
// }
|
|
|
|
// base.WndProc(ref m);
|
|
// }
|
|
//}
|
|
|
|
//public class ClipboardEventArgs : EventArgs
|
|
//{
|
|
// private string clipboardText;
|
|
// public string ClipboardText
|
|
// {
|
|
// get
|
|
// {
|
|
// return clipboardText;
|
|
// }
|
|
|
|
// set
|
|
// {
|
|
// clipboardText = value;
|
|
// }
|
|
// }
|
|
|
|
// public ClipboardEventArgs(string clipboardText)
|
|
// {
|
|
// this.clipboardText = clipboardText;
|
|
// }
|
|
// #endregion
|
|
|
|
}
|
|
#endregion
|
|
}
|