using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Eugen.ESystem.Windows.Forms
{
public partial class Search : UserControl
{
#region Version und Copyright
// Version und Copyright
string dllName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); //Den Programmnamen auslesen
string dllVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
static object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
string copyright = GenerateCopyright();
string icon = Application.StartupPath + "\\Info.bmp";
//Assembly Datum und Zeit
static DateTime value = AssemblyDateTime();
string date = value.ToShortDateString();
string time = value.ToLongTimeString();
private static DateTime AssemblyDateTime()
{
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
var buildDateTime = new DateTime(2000, 1, 1).Add(new TimeSpan(TimeSpan.TicksPerDay * version.Build + TimeSpan.TicksPerSecond * 2 * version.Revision));
//Tage seit dem 1. Januar 2000 und Sekunden seit Mitternacht, (multiplizier mit 2 ergibt das Original)
return buildDateTime;
}
private static string CurrentYear()
{
DateTime dtn = DateTime.Now;
return dtn.Year.ToString();
}
private static string StartYear()
{
string startYear = "";
if (((AssemblyCopyrightAttribute)attributes[0]).Copyright.Contains("Copyright © "))
{
startYear = ((AssemblyCopyrightAttribute)attributes[0]).Copyright.Replace("Copyright © ", "");
while (startYear.StartsWith(" "))
{
startYear = startYear.Remove(0, 1);
}
startYear = startYear.Remove(startYear.IndexOf(" "));
return startYear;
}
else
{
DateTime dtn = DateTime.Now;
return dtn.Year.ToString();
}
}
private static string GenerateCopyright()
{
string startYear = StartYear();
string currentYear = CurrentYear();
if (startYear == currentYear)
{
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
else
{
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright.Replace(startYear, String.Concat(startYear, "-", currentYear));
}
}
#endregion
#region DLL-Info
///
/// Contains the name of the program file
///
public static string DllName { set; get; }
///
/// Contains the version of the program file
///
public static string DllVersion { set; get; }
///
/// Contains the copyright notice
///
public static string Copyright { set; get; }
private void SetDllInfo()
{
//Name, Version und Copyright setzen
DllName = dllName;
DllVersion = dllVersion;
Copyright = copyright;
}
#endregion
///
/// Searches for a string in text
///
public Search()
{
InitializeComponent();
SetDllInfo();
FirstCall = false;
}
#region GlobaleVariablen
protected static string SearchText { set; get; }
protected static string SearchString { set; get; }
protected static int SearchStringLength { set; get; }
protected static bool NoCaseSensitve { set; get; }
protected static bool OnlyEntireWord { set; get; }
protected static int Index { set; get; }
///
/// Contains the current cursor position
///
protected static int CurrentCursorPosition { set; get; }
///
/// Contains a list with all found positions
///
protected static List AllPositions { set; get; }
///
/// Says whether the call was made for the first time
///
protected bool FirstCall { set; get; }
///
/// Is true if an error has occurred
///
public bool Error { private set; get; }
#endregion
#region Public Methodes
///
/// Searches the specified search string in the search text.
///
public void SearchAndFindString()
{
Error = false;
string searchText = SearchText;
string searchString = SearchString;
if (NoCaseSensitve)
{
//Groß-/Kleinschreibung ignorieren
searchText = searchText.ToLower();
searchString = searchString.ToLower();
}
if (!String.IsNullOrEmpty(searchString) && searchText.Contains(searchString))
{
AllPositions = Positions(searchText, searchString);
if (AllPositions.Count == 0)
{
Error = true; //Es wurde keine Übereinstimmung gefunden
}
}
else
{
Error = true;
}
if (!Error)
{
if (Index > AllPositions.Count - 1)
{
CurrentCursorPosition = AllPositions[AllPositions.Count - 1];
}
else
{
CurrentCursorPosition = AllPositions[Index];
}
//Bekanntgeben, dass ein Suchstring gefunden wurde
OnRefreshDisplay(CurrentCursorPosition, SearchStringLength);
}
else
{
//Cursor an die erste Position setzen
CurrentCursorPosition = 0;
//SearchString = "";
//SearchStringLength = 0;
//Suchstring wurde nicht gefunden
throw new StringNotMatchException();
}
}
///
/// Searches and selects the specified search string in the search text.
///
public void SearchAndSelect()
{
try
{
StartSearch(SearchText, SearchString, NoCaseSensitve, OnlyEntireWord);
if (!Error)
{
//Bekanntgeben, dass ein Suchstring gefunden wurde
OnRefreshDisplay(CurrentCursorPosition, SearchStringLength);
}
}
catch (StringNotMatchException)
{
//Cursor an die erste Position setzen
ClearSearchString();
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception)
{
//Cursor an die erste Position setzen
CurrentCursorPosition = 0;
SearchString = "";
SearchStringLength = 0;
MessageBox.Show(AppResources.messagebox003text, AppResources.messagebox003caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
///
/// Sets the text to be searched.
///
/// A valid string.
public void SetSearchText(string searchText)
{
SearchText = searchText;
}
///
/// Get the text to be searched.
///
/// Returns a string.
public string GetSearchText()
{
return SearchText;
}
///
/// Sets the search string.
///
public void SetSearchString()
{
SearchString = textBoxSearchString.Text;
}
///
/// Sets the search string.
///
/// A valid string.
public void SetSearchString(string searchString)
{
SearchString = searchString;
}
///
/// Deletes the search string.
///
public void ClearSearchString()
{
//textBoxSearchString.Clear();
//SearchString = textBoxSearchString.Text;
//textBoxSearchString.Refresh();
SearchStringLength = 0;
CurrentCursorPosition = 0;
if (AllPositions != null)
{
AllPositions.Clear();
}
}
///
/// Get the search string.
///
/// Returns a string.
public string GetSearchString()
{
return SearchString;
}
///
/// Sets the Search string length.
///
/// A valid int value.
public void SetSearchStringLength(int searchStringLength)
{
SearchStringLength = searchStringLength;
}
///
/// Get the Search string length.
///
/// Returns a int value.
public int GetSearchStringLength()
{
return SearchStringLength;
}
///
/// Sets the position for a found value in the array
///
/// A valid int value. Must be smaller / equal to the maximum number of elements.
public void SetIndex(int index)
{
Index = index;
}
///
/// Get the position for a found value in the array
///
/// Returns a int value.
public int GetIndex()
{
return Index;
}
///
/// Sets the current cursor position in the search text.
///
/// A valid int value.
public void SetCurrentCursorPosition(int currentCursorPosition)
{
CurrentCursorPosition = currentCursorPosition;
}
///
/// Get the current cursor position in the search text.
///
/// Returns a int value.
public int GetCurrentCursorPosition()
{
return CurrentCursorPosition;
}
///
/// Returns all positions where the search string was found in the search text.
///
/// Returns a int list.
public List GetAllPositions()
{
return AllPositions;
}
public int GetAllPositionsCount()
{
if (AllPositions == null)
{
return 0;
}
else
{
return AllPositions.Count();
}
}
#endregion
#region Private Methodes
private void SetValues(string searchText, string searchString, bool noCaseSensitve, bool onlyEntireWord)
{
SearchString = textBoxSearchString.Text;
SearchStringLength = SearchString.Length;
NoCaseSensitve = checkBoxCase.Checked;
OnlyEntireWord = checkBoxEntireWord.Checked;
}
private bool IsInputOK()
{
if (!String.IsNullOrEmpty(SearchString) && !String.IsNullOrEmpty(textBoxSearchString.Text))
{
return true; //Sind beide Werte vorhanden, dann ist Alles OK
}
else
{
if (!String.IsNullOrEmpty(textBoxSearchString.Text)) //Wenn ein Wert in der Textbox steht, aber noch nicht Return/Enter gedrückt wurde
{
SearchString = textBoxSearchString.Text;
FirstCall = true; //Wenn "Next match" ausgewählt wurde, dann soll immer das erste Vorkommen, bei "Previous match" immer das letzte Vorkommen ausgewählt werden
try
{
SearchAndFindString();
}
catch (StringNotMatchException)
{
ClearSearchString();
OnRefreshDisplay(CurrentCursorPosition, SearchStringLength); //Anzeige aktualisieren
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
return true;
}
else
{
return false; //Wenn die Eingabe unvollständig ist
}
}
}
private void StartSearch(string searchText, string searchString, bool noCaseSensitve, bool onlyEntireWord)
{
SearchText = searchText;
SearchString = searchString;
SearchStringLength = searchString.Length;
NoCaseSensitve = noCaseSensitve;
OnlyEntireWord = onlyEntireWord;
SearchEntities();
if (!Error)
{
//Index = 0;
if (Index > AllPositions.Count - 1)
{
Index = AllPositions.Count - 1;
}
CurrentCursorPosition = AllPositions[Index];
}
else
{
//Suchstring wurde nicht gefunden
throw new StringNotMatchException();
}
}
private void SearchEntities()
{
Error = false;
string searchText = SearchText;
string searchString = SearchString;
if (NoCaseSensitve)
{
//Groß-/Kleinschreibung ignorieren
searchText = searchText.ToLower();
searchString = searchString.ToLower();
}
if (!String.IsNullOrEmpty(searchString) && searchText.Contains(searchString))
{
AllPositions = Positions(searchText, searchString);
}
else
{
Error = true;
}
}
private List Positions(string searchText, string searchString)
{
//Von allen Vorkommen des Suchstrings im Suchtext die Startposition ermitteln
List positions = new List();
if (String.IsNullOrEmpty(searchText) || String.IsNullOrEmpty(searchString))
{
return positions;
}
int position = 0;
int currentPos = 0;
while (searchText.Contains(searchString))
{
if (OnlyEntireWord)
{
//Nur ganzes Wort suchen
currentPos = IndexOfWord(searchText, searchString);
}
else
{
//Suchstring suchen
currentPos = searchText.IndexOf(searchString);
}
if (currentPos == -1)
{
break;
}
else
{
position += currentPos;
positions.Add(position);
position += searchString.Length;
searchText = searchText.Remove(0, currentPos + searchString.Length);
}
}
return positions;
}
private Regex myRegex;
private int IndexOfWord(string myString, string myWord)
{
myRegex = new Regex("\\b" + Regex.Escape(myWord) + "\\b", RegexOptions.Compiled);
Match mtch = myRegex.Match(myString);
if (mtch.Success)
return mtch.Index;
else
return -1;
}
private void NextMatch()
{
if (IsInputOK())
{
if (!FirstCall)
{
Next(); //Nur ausführen, wenn es nicht der erste Aufruf über "Next match" ist
}
else
{
FirstCall = false; //Beim ersten Aufruf wird immer dar erste gefundene Suchstring ausgewählt
}
Refresh();
}
else
{
throw new IncompleteInputException();
}
}
private void Next()
{
if (AllPositions != null && AllPositions.Count > 0)
{
if (Index < AllPositions.Count - 1)
{
Index++;
}
else
{
Index = 0;
}
CurrentCursorPosition = AllPositions[Index];
//Bekanntgeben, dass ein Suchstring gefunden wurde
OnRefreshDisplay(CurrentCursorPosition, SearchStringLength);
}
else
{
//Suchstring wurde nicht gefunden
throw new StringNotMatchException();
}
}
private void PreviousMatch()
{
if (IsInputOK())
{
Previous();
}
else
{
throw new IncompleteInputException();
}
}
private void Previous()
{
if (AllPositions != null && AllPositions.Count > 0)
{
if (Index > 0)
{
Index--;
}
else
{
Index = AllPositions.Count - 1;
}
if (Index > AllPositions.Count - 1)
{
CurrentCursorPosition = AllPositions[AllPositions.Count - 1];
}
else
{
CurrentCursorPosition = AllPositions[Index];
}
//Bekanntgeben, dass sich die Position geändert hat
OnRefreshDisplay(CurrentCursorPosition, SearchStringLength);
}
else
{
//Suchstring wurde nicht gefunden
throw new StringNotMatchException();
}
}
#endregion
#region Event
// Der Delegat muß die gleiche Signatur aufweisen wie die Eventhandler-Methode.
public delegate void RefreshDelegate(int currentCursorPosition, int searchStringLenght);
// Das Event-Objekt ist vom Typ dieses Delegaten.
public event RefreshDelegate RefreshDisplay;
public void OnRefreshDisplay(int currentCursorPosition, int searchStringLength)
{
// Prüft ob das Event überhaupt einen Abonnenten hat.
RefreshDisplay?.Invoke(currentCursorPosition, searchStringLength);
}
// Der Delegat muß die gleiche Signatur aufweisen wie die Eventhandler-Methode.
public delegate void InputChangedDelegate();
// Das Event-Objekt ist vom Typ dieses Delegaten.
public event InputChangedDelegate InputChanged;
public void OnInputChanged()
{
// Prüft ob das Event überhaupt einen Abonnenten hat.
InputChanged?.Invoke();
}
#endregion
private void checkBoxCase_CheckedChanged(object sender, EventArgs e)
{
NoCaseSensitve = checkBoxCase.Checked;
if (IsInputOK())
{
SearchAndSelect();
OnInputChanged();
}
}
private void checkBoxEntireWord_CheckedChanged(object sender, EventArgs e)
{
OnlyEntireWord = checkBoxEntireWord.Checked;
if (IsInputOK())
{
try
{
SearchString = textBoxSearchString.Text;
SearchStringLength = SearchString.Length;
SearchAndFindString();
OnInputChanged();
}
catch (StringNotMatchException)
{
ClearSearchString();
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void textBoxSearchString_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
SetValues(SearchText, textBoxSearchString.Text, checkBoxCase.Checked, checkBoxEntireWord.Checked);
SearchAndFindString();
OnInputChanged();
}
catch (StringNotMatchException)
{
ClearSearchString();
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void buttonNextMatch_Click(object sender, EventArgs e)
{
try
{
SearchString = textBoxSearchString.Text;
SearchStringLength = SearchString.Length;
SearchAndFindString();
OnInputChanged();
NextMatch();
}
catch (IncompleteInputException)
{
MessageBox.Show(AppResources.messagebox001text, AppResources.messagebox001caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (StringNotMatchException)
{
ClearSearchString();
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void buttonPreviousMatch_Click(object sender, EventArgs e)
{
try
{
SearchString = textBoxSearchString.Text;
SearchStringLength = SearchString.Length;
SearchAndFindString();
OnInputChanged();
PreviousMatch();
}
catch (IncompleteInputException)
{
MessageBox.Show(AppResources.messagebox001text, AppResources.messagebox001caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (StringNotMatchException)
{
ClearSearchString();
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void textBoxSearchString_Leave(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(textBoxSearchString.Text))
{
SearchString = textBoxSearchString.Text;
try
{
SearchAndFindString();
OnInputChanged();
}
catch (Exception)
{
ClearSearchString();
MessageBox.Show(AppResources.messagebox002text, AppResources.messagebox002caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
#region Exceptions
public class StringNotMatchException : Exception
{
public StringNotMatchException() { }
public StringNotMatchException(string message)
: base(message) { }
public StringNotMatchException(string message, Exception inner)
: base(message, inner) { }
}
public class IncompleteInputException : Exception
{
public IncompleteInputException() { }
public IncompleteInputException(string message)
: base(message) { }
public IncompleteInputException(string message, Exception inner)
: base(message, inner) { }
}
#endregion
}