using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
namespace Boxes
{
/// <summary>
/// Die Klasse stellt eine RichTextBox bereit, in der vordefinierte Wörter eingefärbt werden.
/// Wörter die eingefärbt werden sollen, werden durch vordefinierte Trennzeichen separiert,
/// geprüft und ggf. gefärbt.
/// </summary>
/// <remarks>
/// Autor: Daniel Lutz
/// Copyright: Daniel Lutz
/// Für private Nutzung kostenlos! Bei gewerblicher Nutzung wird vorhergehende Erleubnis benötigt!
/// Erstellt: Oktober 2011
/// </remarks>
public class HighLightingBox : RichTextBox
{
#region Variable
RichTextBox m_thisCopy;
List<string> m_SelectionWordList;
List<char>m_SeperatorList=new List<char>();
char[] m_Seperators;
Color m_Color;
int m_CursorPosition;
bool m_IsSingleWordColoring = false;
bool m_IsWholeTextColoring = false;
bool m_IsChangeColoring = false;
IDataObject m_objClipBoard;
int ClipBoardValueLenght;
#endregion
#region Konstruktor
/// <summary>
/// Konstruktor um die benötigten Werte zu initialisieren.
/// </summary>
/// <param name="_Seperators">Zu verwendene Trennzeichen</param>
/// <param name="_Words">Wörter die hervorgehoben werden soll</param>
/// <param name="_Font">Verwendete Schriftart</param>
/// <param name="_Color">Farbe der Hervorhebung</param>
public HighLightingBox(char[] _Seperators, List<string> _Words, Font _Font, Color _Color)
{
m_SelectionWordList = _Words;
m_Color = _Color;
m_Seperators = _Seperators;
this.Font = _Font;
this.TextChanged+=new EventHandler(this_TextChangedEvent);
this.KeyDown+=new KeyEventHandler(this_KeyDown);
ListCreate();
}
#endregion
#region Methode
/// <summary>
/// Erzeugt aus den übergebenden Trennzeichen eine Liste
/// </summary>
private void ListCreate()
{
foreach (char ch in m_Seperators)
{
m_SeperatorList.Add(ch);
}
}
/// <summary>
/// Färbt einzelne Wörte in einem definierten Bereich
/// </summary>
/// <param name="values">Wertebereich</param>
private void ColoringWord(int[] values)
{
m_IsSingleWordColoring = true;
int WordLengthCounter = 0;
this.Select(values[0], values[1] - values[0]);
foreach (string temp in (this.SelectedText.Split(m_Seperators)))
{
this.Select(values[0] + WordLengthCounter, temp.Length);
if (m_SelectionWordList.Contains(this.SelectedText.Trim()))
{
this.SelectionColor = m_Color;
this.SelectionFont = (new Font(this.SelectionFont, FontStyle.Bold));
}
else
{
this.SelectionColor = Color.Black;
this.SelectionFont = (new Font(this.SelectionFont, FontStyle.Regular));
}
WordLengthCounter += temp.Length + 1;
}
m_IsSingleWordColoring = false;
}
/// <summary>
/// Färbt Text in einem definierten Bereich
/// </summary>
/// <param name="position"></param>
private void ColoringText(int position)
{
int[] Borders = GetTextRange();
m_IsWholeTextColoring = true;
int merker;
int merker2;
for (m_thisCopy.SelectionStart = Borders[0]; m_thisCopy.SelectionStart < Borders[1]; m_thisCopy.SelectionStart++)
{
merker = m_thisCopy.SelectionStart;
m_thisCopy.Select(m_thisCopy.SelectionStart, 1);
if (!m_SeperatorList.Contains(m_thisCopy.SelectedText[0]))
{
for (int j = m_thisCopy.SelectionStart; j < Borders[1]; j++)
{
merker2 = j;
m_thisCopy.Select(j, 1);
if (j + 1 != Borders[1])
{
if (m_SeperatorList.Contains(m_thisCopy.SelectedText[0]))
{
m_thisCopy.Select(merker, merker2 - merker);
if (m_SelectionWordList.Contains(m_thisCopy.SelectedText.Trim()))
{
m_thisCopy.SelectionColor = m_Color;
m_thisCopy.SelectionFont = (new Font(m_thisCopy.SelectionFont, FontStyle.Bold));
}
else
{
m_thisCopy.SelectionColor = Color.Black;
m_thisCopy.SelectionFont = (new Font(m_thisCopy.SelectionFont, FontStyle.Regular));
}
m_thisCopy.SelectionStart = merker2;
break;
}
}
else
{
m_thisCopy.Select(merker, merker2+1 - merker);
if (m_SelectionWordList.Contains(m_thisCopy.SelectedText.Trim()))
{
m_thisCopy.SelectionColor = m_Color;
m_thisCopy.SelectionFont = (new Font(m_thisCopy.SelectionFont, FontStyle.Bold));
}
else
{
m_thisCopy.SelectionColor = Color.Black;
m_thisCopy.SelectionFont = (new Font(m_thisCopy.SelectionFont, FontStyle.Regular));
}
m_thisCopy.SelectionStart = merker2;
break;
}
}
}
}
this.Rtf = m_thisCopy.Rtf;
this.SelectionStart = position;
this.SelectionLength = 0;
m_IsWholeTextColoring = false;
m_thisCopy = null;
}
/// <summary>
/// Dininiert Wertebereich für das Färben einzelner Worte
/// </summary>
/// <returns>Definitionsbereich</returns>
private int[] GetWordRange()
{
int value_1;
int value_2;
string[] part_1 = this.Text.Substring(0, this.SelectionStart).Split(m_Seperators);
string[] part_2 = this.Text.Substring(this.SelectionStart).Split(m_Seperators);
if(part_1.Length > 1)
{
if (part_1[part_1.Length - 1].Length != 0)
{
value_1 = this.SelectionStart - part_1[part_1.Length - 1].Length;
}
else
{
value_1 = this.SelectionStart - part_1[part_1.Length - 1].Length - 1 - part_1[part_1.Length - 2].Length;
}
}
else
{
if (part_1.Length > 0)
{
value_1 = this.SelectionStart - part_1[0].Length;
}
else
{
value_1 = 0;
}
}
if (part_2.Length >= 2)
{
if (part_2[0].Length == 0)
{
value_2 = this.SelectionStart + part_2[0].Length + 1 + part_2[1].Length;
}
else
{
value_2 = this.SelectionStart + part_2[0].Length;
}
}
else
{
if (part_2.Length == 1 )
{
value_2 = this.SelectionStart + part_2[0].Length;
}
else
{
value_2 = 0;
}
}
return new int[] { value_1, value_2 };
}
/// <summary>
/// Deiniert Wertebereich für das Färben von Texten
/// </summary>
/// <returns>Definitionsbereich</returns>
private int[] GetTextRange()
{
if (m_IsChangeColoring)
{
m_IsChangeColoring = false;
return new int[]{0,m_thisCopy.Text.Length};
}
RichTextBox copy = new RichTextBox();
copy.Text = this.Text;
copy.SelectionStart = m_thisCopy.SelectionStart-ClipBoardValueLenght;
int position = copy.SelectionStart + ClipBoardValueLenght;
int value_1=0;
int value_2 = 0;
if (copy.SelectionStart == 0)
{ value_1 = 0; }
else
{
while (copy.SelectionStart > 0)
{
copy.SelectionStart -= 1;
m_thisCopy.Select(copy.SelectionStart,1);
if(m_SeperatorList.Contains(m_thisCopy.SelectedText[0]))
{
value_1=copy.SelectionStart+1;
break;
}
}
}
copy.Text = m_thisCopy.Text;
copy.SelectionStart = position + 1;
if (copy.SelectionStart == copy.Text.Length || copy.SelectionStart > copy.Text.Length)
{
value_2 = m_thisCopy.Text.Length;
}
else
{
while (copy.SelectionStart < copy.Text.Length)
{
copy.Select(copy.SelectionStart, 1);
if (m_SeperatorList.Contains(copy.SelectedText[0]))
{
value_2 = copy.SelectionStart;
break;
}
copy.SelectionStart += 1;
if (copy.SelectionStart == copy.Text.Length)
{
value_2 = copy.SelectionStart;
break;
}
}
}
return new int[] { value_1, value_2 };
}
/// <summary>
/// Setzt die Farbe für Hervorhebungen neu
/// </summary>
/// <param name="HColor">Neue Farbe</param>
public void SetColor(Color HColor)
{
m_Color = HColor;
m_thisCopy = new RichTextBox();
m_thisCopy.Rtf = this.Rtf;
m_IsChangeColoring = true;
ColoringText(this.SelectionStart);
}
/// <summary>
/// Verarbeitet Textänderungen in ColorBox
/// </summary>
/// <param name="sender">ColorBox Object</param>
/// <param name="e">Eventargs</param>
private void this_TextChangedEvent(object sender, EventArgs e)
{
if (!m_IsWholeTextColoring)
{
if (!m_IsSingleWordColoring)
{
int[] temp = GetWordRange();
m_CursorPosition = this.SelectionStart;
ColoringWord(temp);
this.SelectionStart = m_CursorPosition;
this.SelectionLength = 0;
}
}
}
/// <summary>
/// Verarbeitet Tastatureingaben und startet ggf. komplette Textüberprüfung
/// </summary>
/// <param name="sender">ColorBox Object</param>
/// <param name="e"></param>
private void this_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.Control|Keys.V))
{
e.Handled=true;
m_objClipBoard = Clipboard.GetDataObject();
try
{
m_thisCopy=new RichTextBox();
m_thisCopy.Rtf = this.Rtf;
string temp= m_objClipBoard.GetData(DataFormats.Text).ToString();
InsertText(temp);
ColoringText(m_thisCopy.SelectionStart);
}
catch (NullReferenceException)
{
MessageBox.Show(this, "Es befindet sich kein Text in der Zwischenablage!", "Fehlermeldung", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
m_objClipBoard = null;
}
}
/// <summary>
/// Fügt Text aus der Zwischenablage ein
/// </summary>
/// <param name="value">Zwischenablageninhalt</param>
private void InsertText(string value)
{
int position = this.SelectionStart;
int PreViewLenght = m_thisCopy.Text.Length;
m_IsWholeTextColoring = true;
if (this.SelectionLength == 0)
{
this.SelectionColor = Color.Black;
this.Select(this.SelectionStart, 0);
this.SelectedText=value;
m_thisCopy.Rtf = this.Rtf;
}
else
{
this.Select(this.SelectionStart, this.SelectionLength);
this.SelectedText = this.SelectedText.Remove(0, this.SelectedText.Length);
this.SelectionColor = Color.Black;
this.SelectedText = value;
m_thisCopy.Rtf = this.Rtf;
}
if (m_thisCopy.Text.Length != PreViewLenght)
{
m_thisCopy.SelectionStart = position + m_thisCopy.Text.Length - PreViewLenght;
ClipBoardValueLenght = m_thisCopy.Text.Length - PreViewLenght;
}
else
{
m_thisCopy.SelectionStart = m_thisCopy.Text.Length;
ClipBoardValueLenght = m_thisCopy.Text.Length;
}
}
#endregion
}
}