493 lines
16 KiB
C#
493 lines
16 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;
|
|
|
|
namespace TestWndProc
|
|
{
|
|
public partial class MyPanel : UserControl
|
|
{
|
|
private bool _TextChanging=false;
|
|
private const int WM_NOTIFY = 0x4E;
|
|
public MyPanel()
|
|
{
|
|
InitializeComponent();
|
|
//RTBAPI.SetNotifyProtect(myRTB1);
|
|
//myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}\r\n" +
|
|
// @"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
// @"\v <START]\v0 Not Protected Link\v #Link data including URL\v0 \v [END>\v0\par" +
|
|
// @"\v <START]\v0 30 gpm\v #Link Reference Object A.1[END>\v0\v <START]\v0 20 gpm\v #Link Reference Object A.2[END>\v0\par" +
|
|
// @"Not Protected\par " +
|
|
// @"Not Protected\par " +
|
|
// @"Not Protected\par " +
|
|
// @"Not Protected\par}";
|
|
// KBR's Testing for delete link basic cases (text before & after link):
|
|
//myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}\r\n" +
|
|
// @"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
// @"Add some text before \v <START]\v0 Link at middle of box\v #Link data including URL\v0 \v [END>\v0 and some more text after}";
|
|
// KBR's Testing for delete link at beginning of box (BASIC CASE):
|
|
//myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}\r\n" +
|
|
// @"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
// @"\v <START]\v0 Link at beginning of box\v #Link data including URL\v0 \v [END>\v0 and some more text after}";
|
|
// KBR's Testing for delete link with two links in a row:
|
|
myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}\r\n" +
|
|
@"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
@"Add some text before \v <START]\v0 First Link in box\v #Link data including URL\v0 \v [END>\v0 "+
|
|
@"\v <START]\v0 Second Link in box\v #Link data including URL\v0 \v [END>\v0 and some more text after}";
|
|
// RHM's latest:
|
|
//myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}\r\n" +
|
|
// @"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
// @"\v <START]\v0 Not Protected Link\v #Link data including URL\v0 \v [END>\v0\par" +
|
|
// @"\v <START]\v0 30 gpm\v #Link Reference Object A.1[END>\v0\v <START]\v0 20 gpm\v #Link Reference Object A.2[END>\v0\par" +
|
|
// @"Not Protected\par " +
|
|
// @"Make sure the flow is at \b least \v <START]\v0 40 GPM\v #Link data including URL\v0 \v [END>\v0 \b0 coming from the Aux Feed Pump\par " +
|
|
// @"Not Protected\par " +
|
|
// @"Not Protected\par}";
|
|
//myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}{\colortbl{\red0\green0\blue0;\red255\green0\blue0}}\r\n" +
|
|
// @"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
// @"\cf1 Not Protected Link\v #Link data including URL\v0\par" +
|
|
// @"30 gpm\v #Link Reference Object A.1\v0 \cf1 20 gpm\v #Link Reference Object A.2\v0\par" +
|
|
// @"Not Protected\par " +
|
|
// @"Make sure the flow is at least \v <START]\v0 40 GPM\v #Link data including URL\v0 \v [END>\v0 coming from the Aux Feed Pump\par " +
|
|
// @"Not Protected\par " +
|
|
// @"Not Protected\par}";
|
|
//FindAllLinks();
|
|
this.myRTB1.SelectionChanged += new System.EventHandler(this.myRTB1_SelectionChanged);
|
|
}
|
|
private void myRTB1_Protected(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show("Cannot change protected text that way!");
|
|
}
|
|
private void btnBoldOn_Click(object sender, EventArgs e)
|
|
{
|
|
RTBAPI.ToggleBold(true, myRTB1, RTBAPI.RTBSelection.SCF_SELECTION);
|
|
}
|
|
|
|
private void btnBoldOff_Click(object sender, EventArgs e)
|
|
{
|
|
RTBAPI.ToggleBold(false, myRTB1, RTBAPI.RTBSelection.SCF_SELECTION);
|
|
}
|
|
|
|
private void myRTB1_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (_TextChanging == false)
|
|
{
|
|
_TextChanging = true;
|
|
tbRTF.Text = myRTB1.Rtf;
|
|
FindAllLinks();
|
|
ShowSelection();
|
|
_TextChanging = false;
|
|
}
|
|
}
|
|
|
|
private void ShowSelection()
|
|
{
|
|
lblFind.Text = string.Format("{0}-{1}", myRTB1.SelectionStart, myRTB1.SelectionStart + myRTB1.SelectionLength);
|
|
tbSelRTF.Text = myRTB1.SelectedRtf;
|
|
tbSelText.Text = myRTB1.SelectedText;
|
|
UpdateNudsFromSelection();
|
|
|
|
}
|
|
|
|
private void UpdateNudsFromSelection()
|
|
{
|
|
nudStart.Value = myRTB1.SelectionStart;
|
|
nudLength.Value = myRTB1.SelectionLength;
|
|
}
|
|
|
|
private void UpdateNuds(int start, int length)
|
|
{
|
|
nudStart.Value = start;
|
|
nudLength.Value = length;
|
|
}
|
|
private void btnLinkOn_Click(object sender, EventArgs e)
|
|
{
|
|
RTBAPI.Link(myRTB1);
|
|
}
|
|
private void btnLinkOff_Click(object sender, EventArgs e)
|
|
{
|
|
RTBAPI.UnLink(myRTB1);
|
|
}
|
|
private void btnProtectOn_Click(object sender, EventArgs e)
|
|
{
|
|
RTBAPI.Protect(myRTB1);
|
|
}
|
|
private void btnProtectOff_Click(object sender, EventArgs e)
|
|
{
|
|
RTBAPI.UnProtect(myRTB1);
|
|
}
|
|
private void SetSelection(int locStart, int locLength)
|
|
{
|
|
Application.DoEvents();
|
|
//myRTB1.SelectionStart = myRTB1.TextLength; // Pointing to the end forces the length to zero at the same time.
|
|
//myRTB1.SelectionStart = locStart;
|
|
//myRTB1.SelectionLength = locLength;
|
|
myRTB1.Select(locStart, locLength);
|
|
}
|
|
private void tbRTF_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (_TextChanging == false)
|
|
{
|
|
_TextChanging = true;
|
|
myRTB1.Rtf = tbRTF.Text;
|
|
_TextChanging = false;
|
|
}
|
|
}
|
|
private void UpdateSelectionFromNuds()
|
|
{
|
|
SetSelection((int)(nudStart.Value),(int)(nudLength.Value));
|
|
}
|
|
private void myRTB1_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
_MouseDown = false;
|
|
HandleSelectionChange();
|
|
}
|
|
List<LinkLocation> _linkLocations;
|
|
private void btnFindAllLinks_Click(object sender, EventArgs e)
|
|
{
|
|
FindAllLinks();
|
|
}
|
|
private void FindAllLinks()
|
|
{
|
|
string str = myRTB1.Text;
|
|
_AdjustingSelection = true;
|
|
myRTB1.PushSelection();
|
|
_linkLocations = new List<LinkLocation>();
|
|
MatchCollection matches = Regex.Matches(str, "<START](.*?)[[]END>");
|
|
MatchCollection matchesRtf = Regex.Matches(myRTB1.Rtf, "<START](.*?)[[]END>");
|
|
for (int i = 0; i< matches.Count; i++) //each (Match match in matches)
|
|
{ //KBR
|
|
Match match = matches[i];
|
|
Match matchrtf = matchesRtf[i];
|
|
_linkLocations.Add(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));
|
|
} //KBR
|
|
foreach (LinkLocation ll in _linkLocations)
|
|
{
|
|
myRTB1.Select(ll.Start, ll.Length); // subtract off start token!
|
|
RTBAPI.CharFormatTwo charFormat = RTBAPI.GetCharFormat(myRTB1, RTBAPI.RTBSelection.SCF_SELECTION);
|
|
// Protect the link text to avoid manual changes
|
|
charFormat.dwMask = RTBAPI.CharFormatMasks.CFM_LINK; // | RTBAPI.CharFormatMasks.CFM_PROTECTED;
|
|
charFormat.dwEffects = RTBAPI.CharFormatEffects.CFE_LINK; // | RTBAPI.CharFormatEffects.CFE_PROTECTED;
|
|
RTBAPI.SetCharFormat(myRTB1, RTBAPI.RTBSelection.SCF_SELECTION, charFormat);
|
|
}
|
|
myRTB1.PopSelection();
|
|
LinkLocation llx = FindLinkLocation();
|
|
if (_CheckSelection)
|
|
{
|
|
if (llx != null) SetSelection(llx.End, 0);
|
|
_CheckSelection = false;
|
|
}
|
|
_AdjustingSelection = false;
|
|
myRTB1.Focus();
|
|
dgv.DataSource = _linkLocations;
|
|
}
|
|
private void dgv_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
if (dgv.SelectedRows.Count == 1)
|
|
{
|
|
LinkLocation ll = _linkLocations[dgv.SelectedRows[0].Index];
|
|
SetSelection(ll.Start,ll.Length);
|
|
}
|
|
}
|
|
bool _AdjustingSelection = false;
|
|
private void myRTB1_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
HandleSelectionChange();
|
|
}
|
|
|
|
private void HandleSelectionChange()
|
|
{
|
|
Console.WriteLine("CHECK MOUSE: Sel {0} Length {1}", myRTB1.SelectionStart, myRTB1.SelectionLength);
|
|
if (cbProcess.Checked)
|
|
{
|
|
|
|
// Can I limit cursor movement to the ranges of link locations
|
|
if (!_MouseDown && !_AdjustingSelection)
|
|
{
|
|
if (_linkLocations != null)
|
|
{
|
|
LinkLocation ll = FindLinkLocation();
|
|
//if (_CheckSelection)
|
|
//{
|
|
// //if (ll != null) SetSelection(ll.End, 0);
|
|
// _CheckSelection = false;
|
|
//}
|
|
LinkLocation llend = null;
|
|
if (myRTB1.SelectionLength!=0)
|
|
llend = FindLinkLocation(myRTB1.SelectionStart + myRTB1.SelectionLength-1);
|
|
if (ll != null)
|
|
{
|
|
Console.WriteLine("SELECTIONCHANGED: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", myRTB1.SelectionStart, myRTB1.SelectionLength, ll.Start, ll.Length);
|
|
_AdjustingSelection = true;
|
|
if (myRTB1.SelectionStart == ll.Start && myRTB1.SelectionLength == 0)
|
|
{
|
|
// won't work between two links
|
|
SendKeys.Send("{LEFT}");
|
|
}
|
|
if (myRTB1.SelectionStart + myRTB1.SelectionLength > ll.End)
|
|
{
|
|
int end = myRTB1.SelectionStart + myRTB1.SelectionLength;
|
|
SetSelection(ll.Start, end - ll.Start);
|
|
}
|
|
else
|
|
{
|
|
SetSelection(ll.Start, ll.Length);
|
|
}
|
|
_AdjustingSelection = false;
|
|
}
|
|
else if (llend != null)
|
|
{
|
|
Console.WriteLine("LLEND: Sel {0}, Length {1}, Link Start {2}, Link Length {3}", myRTB1.SelectionStart, myRTB1.SelectionLength, llend.Start, llend.Length);
|
|
_AdjustingSelection = true;
|
|
SetSelection(myRTB1.SelectionStart, llend.End - myRTB1.SelectionStart);
|
|
_AdjustingSelection = false;
|
|
}
|
|
//else
|
|
//{
|
|
// if (myRTB1.SelectedText.EndsWith("<START]") && !myRTB1.SelectedText.EndsWith("[END><START]"))
|
|
// myRTB1.SelectionLength = myRTB1.SelectionLength - 7;
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
ShowSelection();
|
|
UpdateNudsFromSelection();
|
|
}
|
|
private bool _CheckSelection = false;
|
|
int processingkeys = 0;
|
|
private void myRTB1_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (processingkeys > 0)
|
|
Console.WriteLine("Key down: {0} processing keys = {1}", e.KeyCode, processingkeys);
|
|
if (!cbProcess.Checked) return;
|
|
//Console.WriteLine("{0}", e.KeyCode);
|
|
switch (e.KeyCode)
|
|
{
|
|
case Keys.Left:
|
|
LinkLocation ll = FindLinkSelected();
|
|
if (ll != null)
|
|
{
|
|
_AdjustingSelection = true;
|
|
Console.WriteLine("Adjusting SelectionStart {0} to {1}", myRTB1.SelectionStart, ll.Start - 7);
|
|
SetSelection(ll.Start - 7, 0);
|
|
_AdjustingSelection = false;
|
|
// Does not allow you to stop between two links that are right next to
|
|
// each other
|
|
if (myRTB1.SelectionStart != ll.Start - 7)
|
|
{
|
|
Console.WriteLine(" Didn't work - SelectionStart {0}", myRTB1.SelectionStart);
|
|
//ll = FindLinkLocation(myRTB1.SelectionStart);
|
|
//SetSelection(ll.Start, ll.Length);
|
|
SetSelection(ll.Start, 0);
|
|
}
|
|
e.SuppressKeyPress = true;
|
|
}
|
|
break;
|
|
case Keys.Back:
|
|
_CheckSelection = true;
|
|
|
|
break;
|
|
case Keys.Delete:
|
|
//if (myRTB1.SelectionLength == 0)
|
|
//{
|
|
// e.SuppressKeyPress = true;
|
|
// SendKeys.Send("{RIGHT}{BS}");
|
|
//} else
|
|
if (myRTB1.SelectedText.EndsWith(@"[END><START]"))
|
|
{
|
|
DoDeleteEndBetweenLinks();
|
|
e.SuppressKeyPress = true;
|
|
}
|
|
else
|
|
{
|
|
myRTB1.SelectedText = "X";
|
|
SendKeys.Send("{BS}");
|
|
e.SuppressKeyPress = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
private void DebugPrint(string where, string format, params object[] myParams)
|
|
{
|
|
Application.DoEvents();
|
|
Console.WriteLine(where + string.Format(format, myParams));
|
|
}
|
|
private void DebugSelection(string where)
|
|
{
|
|
DebugPrint(where, ": {0} {1} {2}", myRTB1.SelectionStart, myRTB1.SelectionLength, myRTB1.SelectedText);
|
|
}
|
|
private void RtbSendKeys(string keys)
|
|
{
|
|
SendKeys.Send(keys);
|
|
DebugSelection(keys);
|
|
}
|
|
private void DoDeleteEndBetweenLinks()
|
|
{
|
|
processingkeys++;
|
|
DebugSelection("Beginning");
|
|
int sstart = myRTB1.SelectionStart;
|
|
RtbSendKeys("{RIGHT} "); // open for space between links which separates END/START tokens
|
|
SetSelection(sstart, myRTB1.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
|
|
processingkeys--;
|
|
}
|
|
private void DoDeleteStartBetweenLinks()
|
|
{
|
|
processingkeys++;
|
|
int slen = myRTB1.SelectionLength;
|
|
RtbSendKeys("{LEFT} ");
|
|
SetSelection(myRTB1.SelectionStart, slen + 7);
|
|
RtbSendKeys("{DELETE}");
|
|
RtbSendKeys("{BS}");
|
|
processingkeys--;
|
|
}
|
|
private LinkLocation FindLinkSelected()
|
|
{
|
|
if (_linkLocations == null) return null;
|
|
foreach (LinkLocation ll in _linkLocations)
|
|
if (ll.Start == myRTB1.SelectionStart && ll.Length == myRTB1.SelectionLength) return ll;
|
|
return null;
|
|
}
|
|
private LinkLocation FindLinkLocation()
|
|
{
|
|
return FindLinkLocation(myRTB1.SelectionStart);
|
|
}
|
|
private LinkLocation FindLinkLocation(int sel)
|
|
{
|
|
if (_linkLocations == null) return null;
|
|
int lastend = -1;
|
|
foreach (LinkLocation ll in _linkLocations)
|
|
{
|
|
// Moving right:
|
|
// if less than, allows stopping between two links
|
|
// if less than or equal, does not stop between two links
|
|
if (ll.Start < sel && ll.End > sel) return ll;
|
|
//if (ll.Start == lastend && ll.Start < sel && ll.End > sel) return ll;
|
|
if (ll.Start != lastend && ll.Start <= sel && ll.End > sel) return ll;
|
|
lastend = ll.End;
|
|
}
|
|
return null;
|
|
}
|
|
private bool _MouseDown = false;
|
|
private void myRTB1_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
_MouseDown = true;
|
|
}
|
|
|
|
private void btnUpdateSel_Click(object sender, EventArgs e)
|
|
{
|
|
UpdateSelectionFromNuds();
|
|
myRTB1.Focus();
|
|
}
|
|
|
|
private void myRTB1_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
Console.WriteLine("KeyPress: {0},{1}", e.KeyChar, (int)e.KeyChar);
|
|
if (e.KeyChar >= ' ')
|
|
{
|
|
LinkLocation ll = FindBetweenLinks();
|
|
if (ll != null&&myRTB1.SelectionLength==0)
|
|
{
|
|
myRTB1.Rtf = myRTB1.Rtf.Substring(0, ll.StartRtf) + @"\v0 " + e.KeyChar.ToString() + @"\v " + myRTB1.Rtf.Substring(ll.StartRtf);
|
|
e.Handled = true;
|
|
myRTB1.SelectionStart = ll.Start - 6; // account for <START] - 1 for the character typed
|
|
}
|
|
else if (ll != null)
|
|
{
|
|
DoDeleteStartBetweenLinks();
|
|
}
|
|
else if (myRTB1.SelectedText.EndsWith(@"[END><START]"))
|
|
{
|
|
DoDeleteEndBetweenLinks();
|
|
}
|
|
}
|
|
}
|
|
|
|
private LinkLocation FindBetweenLinks()
|
|
{
|
|
bool lastend = false;
|
|
foreach (LinkLocation ll in _linkLocations)
|
|
{
|
|
if (ll.End == myRTB1.SelectionStart) lastend = true;
|
|
if (ll.Start == myRTB1.SelectionStart && lastend) return ll;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void tbRTB_SelectionChanged(object sender, EventArgs e)
|
|
{
|
|
//lbTbSel.Text = string.Format("{0}, {1}", tbRTF.SelectionStart, tbRTF.SelectionLength);
|
|
}
|
|
|
|
private void btnRefreshText_Click(object sender, EventArgs e)
|
|
{
|
|
myRTB1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Arial;}}\r\n" +
|
|
@"\viewkind4\uc1\pard\sl-240\slmult0\f0\fs20 " +
|
|
@"Add some text before \v <START]\v0 First Link in box\v #Link data including URL\v0 \v [END>\v0 " +
|
|
@"\v <START]\v0 Second Link in box\v #Link data including URL\v0 \v [END>\v0 and some more text after}";
|
|
}
|
|
|
|
private void tbRTF_SelectionChange(object sender, EventArgs e)
|
|
{
|
|
lbTbSel.Text = string.Format("{0}, {1}", tbRTF.SelectionStart, tbRTF.SelectionLength);
|
|
}
|
|
}
|
|
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; }
|
|
}
|
|
public LinkLocation(int start, int length, string text, int startRtf, int lengthRtf)
|
|
{
|
|
_Start = start;
|
|
_Length = length;
|
|
_Text = text;
|
|
_StartRtf = startRtf;
|
|
_LengthRtf = lengthRtf;
|
|
}
|
|
}
|
|
}
|