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 }