/// <summary> /// Searches for a string in the reverse direction of <see cref="FindForward"/>. /// </summary> /// <param name="Txt">The text to search for.</param> /// <param name="StartLoc">The starting location of the search.</param> /// <param name="EndLoc">The ending location of the search.</param> /// <param name="Flags">Flags controlling how the searching is conducted.</param> /// <param name="Result">Receives the results of the search.</param> /// <returns>True if a match was found.</returns> private bool FindReverse(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result) { bool bFound = false; bool bMatchWord; bool bIsWord; StringComparison ComparisonFlags; SetupFindState(Txt, ref StartLoc, ref EndLoc, Flags, out Result, out bIsWord, out ComparisonFlags, out bMatchWord); for(int CurLineIndex = StartLoc.Line; CurLineIndex >= EndLoc.Line && !bFound; --CurLineIndex) { if(GetLineLength(CurLineIndex) == 0) { continue; } DocumentLine CurLineBldr = mLines[CurLineIndex]; string LineTxt; int ColumnIndex = 0; if(CurLineIndex == StartLoc.Line && StartLoc.Column < GetLineLength(CurLineIndex)) { LineTxt = CurLineBldr.ToString(0, StartLoc.Column); } else if(CurLineIndex == EndLoc.Line && EndLoc.Column > 0) { LineTxt = CurLineBldr.ToString(EndLoc.Column, CurLineBldr.Length - EndLoc.Column); ColumnIndex = EndLoc.Column; } else { LineTxt = CurLineBldr.ToString(); } int Index = LineTxt.LastIndexOf(Txt, ComparisonFlags); if(Index != -1) { ColumnIndex += Index; CheckForWholeWord(Txt, ref Result, bMatchWord, ref bFound, bIsWord, CurLineIndex, CurLineBldr, ColumnIndex, Index); } } return bFound; }
/// <summary> /// Performs general housekeeping for setting up a search. /// </summary> /// <param name="Txt">The text to search for.</param> /// <param name="StartLoc">The location to begin searching from.</param> /// <param name="EndLoc">The location to stop searching at.</param> /// <param name="Flags">Flags controlling how the search is performed.</param> /// <param name="Result">Receives the resulting location if a match is found.</param> /// <param name="bIsWord">Set to true if <paramref name="Txt"/> is a valid word.</param> /// <param name="ComparisonFlags">Receives flags controlling how strings are compared.</param> /// <param name="bMatchWord">Is set to true if only full words are to be matched.</param> private void SetupFindState(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result, out bool bIsWord, out StringComparison ComparisonFlags, out bool bMatchWord) { Result = FindResult.Empty; if(!IsValidTextLocation(StartLoc)) { throw new ArgumentException("StartLoc is an invalid text location!"); } if(!IsValidTextLocation(EndLoc)) { throw new ArgumentException("EndLoc is an invalid text location!"); } if((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse) { if(StartLoc < EndLoc) { throw new ArgumentException("StartLoc must be greater than EndLoc when doing a reverse search!"); } } else { if(StartLoc > EndLoc) { throw new ArgumentException("StartLoc must be less than EndLoc when doing a forward search!"); } } bMatchWord = (Flags & RichTextBoxFinds.WholeWord) == RichTextBoxFinds.WholeWord; bIsWord = IsWord(0, Txt); ComparisonFlags = StringComparison.OrdinalIgnoreCase; if((Flags & RichTextBoxFinds.MatchCase) == RichTextBoxFinds.MatchCase) { ComparisonFlags = StringComparison.Ordinal; } }
/// <summary> /// Finds the first occurence of the specified string within the document if it exists. /// </summary> /// <param name="Txt">The string to find.</param> /// <param name="StartLoc">The position within the document to begin searching.</param> /// <param name="EndLoc">The position within the document to end searching.</param> /// <param name="Flags">Flags telling the document how to conduct its search.</param> /// <param name="Result">The location within the document of the supplied text.</param> /// <returns>True if the text was found.</returns> public bool Find(string Txt, TextLocation StartLoc, TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result) { if((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse) { return FindReverse(Txt, ref StartLoc, ref EndLoc, Flags, out Result); } else { return FindForward(Txt, ref StartLoc, ref EndLoc, Flags, out Result); } }
/// <summary> /// Checks to see if a text location is a matching word. /// </summary> /// <param name="Txt">The text being searched for.</param> /// <param name="Result">Receives the result if the text location is a matching word.</param> /// <param name="bMatchWord">True if an entire word is to be matched.</param> /// <param name="bFound">Set to true if a matching word is found.</param> /// <param name="bIsWord">True if <paramref name="Txt"/> is a valid word.</param> /// <param name="CurLineIndex">The index of the current line.</param> /// <param name="CurLineBldr">The text of the current line.</param> /// <param name="ColumnIndex">The character index within the line of text where the matching will begin.</param> /// <param name="Index">The index of a match within the range of searchable characters for the current line. The true line index is <paramref name="ColumnIndex"/> + <paramref name="Index"/>.</param> private static void CheckForWholeWord(string Txt, ref FindResult Result, bool bMatchWord, ref bool bFound, bool bIsWord, int CurLineIndex, DocumentLine CurLine, int ColumnIndex, int Index) { int FinalCharIndex = ColumnIndex + Txt.Length; if(bMatchWord && bIsWord) { if((FinalCharIndex >= CurLine.Length || !IsWordCharacter(CurLine[FinalCharIndex])) && (ColumnIndex == 0 || !IsWordCharacter(CurLine[ColumnIndex - 1]))) { bFound = true; } } else { bFound = true; } if(bFound) { Result.Line = CurLineIndex; Result.Column = ColumnIndex; Result.Length = Txt.Length; } }
/// <summary> /// Finds the first occurence of the specified string within the document if it exists. /// </summary> /// <param name="Txt">The string to find.</param> /// <param name="StartLoc">The position within the document to begin searching.</param> /// <param name="EndLoc">The position within the document to end searching.</param> /// <param name="Flags">Flags telling the document how to conduct its search.</param> /// <param name="Result">The location within the document of the supplied text.</param> /// <returns>True if the text was found.</returns> public bool Find(string Txt, TextLocation StartLoc, TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result) { bool bResult = false; if(mDocument == null) { Result = FindResult.Empty; } else { bResult = mDocument.Find(Txt, StartLoc, EndLoc, Flags, out Result); } if(bResult && (Flags & RichTextBoxFinds.NoHighlight) != RichTextBoxFinds.NoHighlight) { Select(Result); } return bResult; }
/// <summary> /// Selects a range of text and brings the selection into view. /// </summary> /// <param name="Range">The location of the selection and its length.</param> public void Select(FindResult Range) { if(mDocument != null) { TextLocation StartLoc = new TextLocation(Range.Line, Range.Column); if(!IsValidTextLocation(StartLoc)) { throw new ArgumentOutOfRangeException("Range"); } TextLocation EndLoc = new TextLocation(Range.Line, Math.Min(Range.Column + Range.Length, mDocument.GetLineLength(Range.Line))); Select(StartLoc, EndLoc); } }
/// <summary> /// Searches for a string in the reverse direction of <see cref="FindForward"/>. /// </summary> /// <param name="Txt">The text to search for.</param> /// <param name="StartLoc">The starting location of the search.</param> /// <param name="EndLoc">The ending location of the search.</param> /// <param name="Flags">Flags controlling how the searching is conducted.</param> /// <param name="Result">Receives the results of the search.</param> /// <returns>True if a match was found.</returns> private bool FindReverse(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result) { bool bFound = false; bool bMatchWord; bool bIsWord; StringComparison ComparisonFlags; SetupFindState(Txt, ref StartLoc, ref EndLoc, Flags, out Result, out bIsWord, out ComparisonFlags, out bMatchWord); for (int CurLineIndex = StartLoc.Line; CurLineIndex >= EndLoc.Line && !bFound; --CurLineIndex) { if (GetLineLength(CurLineIndex) == 0) { continue; } DocumentLine CurLineBldr = mLines[CurLineIndex]; string LineTxt; int ColumnIndex = 0; if (CurLineIndex == StartLoc.Line && StartLoc.Column < GetLineLength(CurLineIndex)) { LineTxt = CurLineBldr.ToString(0, StartLoc.Column); } else if (CurLineIndex == EndLoc.Line && EndLoc.Column > 0) { LineTxt = CurLineBldr.ToString(EndLoc.Column, CurLineBldr.Length - EndLoc.Column); ColumnIndex = EndLoc.Column; } else { LineTxt = CurLineBldr.ToString(); } int Index = LineTxt.LastIndexOf(Txt, ComparisonFlags); if (Index != -1) { ColumnIndex += Index; CheckForWholeWord(Txt, ref Result, bMatchWord, ref bFound, bIsWord, CurLineIndex, CurLineBldr, ColumnIndex, Index); } } return(bFound); }
/// <summary> /// Performs general housekeeping for setting up a search. /// </summary> /// <param name="Txt">The text to search for.</param> /// <param name="StartLoc">The location to begin searching from.</param> /// <param name="EndLoc">The location to stop searching at.</param> /// <param name="Flags">Flags controlling how the search is performed.</param> /// <param name="Result">Receives the resulting location if a match is found.</param> /// <param name="bIsWord">Set to true if <paramref name="Txt"/> is a valid word.</param> /// <param name="ComparisonFlags">Receives flags controlling how strings are compared.</param> /// <param name="bMatchWord">Is set to true if only full words are to be matched.</param> private void SetupFindState(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result, out bool bIsWord, out StringComparison ComparisonFlags, out bool bMatchWord) { Result = FindResult.Empty; if (!IsValidTextLocation(StartLoc)) { throw new ArgumentException("StartLoc is an invalid text location!"); } if (!IsValidTextLocation(EndLoc)) { throw new ArgumentException("EndLoc is an invalid text location!"); } if ((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse) { if (StartLoc < EndLoc) { throw new ArgumentException("StartLoc must be greater than EndLoc when doing a reverse search!"); } } else { if (StartLoc > EndLoc) { throw new ArgumentException("StartLoc must be less than EndLoc when doing a forward search!"); } } bMatchWord = (Flags & RichTextBoxFinds.WholeWord) == RichTextBoxFinds.WholeWord; bIsWord = IsWord(0, Txt); ComparisonFlags = StringComparison.OrdinalIgnoreCase; if ((Flags & RichTextBoxFinds.MatchCase) == RichTextBoxFinds.MatchCase) { ComparisonFlags = StringComparison.Ordinal; } }
/// <summary> /// Finds the first occurence of the specified string within the document if it exists. /// </summary> /// <param name="Txt">The string to find.</param> /// <param name="StartLoc">The position within the document to begin searching.</param> /// <param name="EndLoc">The position within the document to end searching.</param> /// <param name="Flags">Flags telling the document how to conduct its search.</param> /// <param name="Result">The location within the document of the supplied text.</param> /// <returns>True if the text was found.</returns> public bool Find(string Txt, TextLocation StartLoc, TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result) { if ((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse) { return(FindReverse(Txt, ref StartLoc, ref EndLoc, Flags, out Result)); } else { return(FindForward(Txt, ref StartLoc, ref EndLoc, Flags, out Result)); } }