/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/Microsoft.Management.UI.Internal/HelpWindow/ParagraphSearcher.cs
241 строка
9 KB
spaette
Fix typos in comments (#19064)
03 фев 2023, 08:40
Не верифицирован
03 фев 2023, 08:40
ec0eb22
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Diagnostics; using System.Windows.Documents; using System.Windows.Media; namespace Microsoft.Management.UI.Internal { /// <summary> /// Moves through search highlights built in a ParagraphBuilder /// changing the color of the current highlight. /// </summary> internal class ParagraphSearcher { /// <summary> /// Highlight for all matches except the current. /// </summary> internal static readonly Brush HighlightBrush = Brushes.Yellow; /// <summary> /// Highlight for the current match. /// </summary> private static readonly Brush CurrentHighlightBrush = Brushes.Cyan; /// <summary> /// Current match being highlighted in search. /// </summary> private Run currentHighlightedMatch; /// <summary> /// Initializes a new instance of the ParagraphSearcher class. /// </summary> internal ParagraphSearcher() { } /// <summary> /// Move to the next highlight starting at the <paramref name="caretPosition"/>. /// </summary> /// <param name="forward">True for next false for previous.</param> /// <param name="caretPosition">Caret position.</param> /// <returns>The next highlight starting at the <paramref name="caretPosition"/>.</returns> internal Run MoveAndHighlightNextNextMatch(bool forward, TextPointer caretPosition) { Debug.Assert(caretPosition != null, "a caret position is always valid"); Debug.Assert(caretPosition.Parent != null && caretPosition.Parent is Run, "a caret Parent is always a valid Run"); Run caretRun = (Run)caretPosition.Parent; Run currentRun; if (this.currentHighlightedMatch != null) { // restore the curent highlighted background to plain highlighted this.currentHighlightedMatch.Background = ParagraphSearcher.HighlightBrush; } // If the caret is in the end of a highlight we move to the adjacent run // It has to be in the end because if there is a match at the beginning of the file // and the caret has not been touched (so it is in the beginning of the file too) // we want to highlight this first match. // Considering the caller always set the caret to the end of the highlight // The condition below works well for successive searchs // We also need to move to the adjacent run if the caret is at the first run and we // are moving backwards so that a search backwards when the first run is highlighted // and the caret is at the beginning will wrap to the end if ((!forward && IsFirstRun(caretRun)) || ((caretPosition.GetOffsetToPosition(caretRun.ContentEnd) == 0) && ParagraphSearcher.Ishighlighted(caretRun))) { currentRun = ParagraphSearcher.GetNextRun(caretRun, forward); } else { currentRun = caretRun; } currentRun = ParagraphSearcher.GetNextMatch(currentRun, forward); if (currentRun == null) { // if we could not find a next highlight wraparound currentRun = ParagraphSearcher.GetFirstOrLastRun(caretRun, forward); currentRun = ParagraphSearcher.GetNextMatch(currentRun, forward); } this.currentHighlightedMatch = currentRun; if (this.currentHighlightedMatch != null) { // restore the curent highlighted background to current highlighted this.currentHighlightedMatch.Background = ParagraphSearcher.CurrentHighlightBrush; } return currentRun; } /// <summary> /// Resets the search for fresh calls to MoveAndHighlightNextNextMatch. /// </summary> internal void ResetSearch() { this.currentHighlightedMatch = null; } /// <summary> /// Returns true if <paramref name="run"/> is highlighted. /// </summary> /// <param name="run">Run to check if is highlighted.</param> /// <returns>True if <paramref name="run"/> is highlighted.</returns> private static bool Ishighlighted(Run run) { if (run == null) { return false; } SolidColorBrush background = run.Background as SolidColorBrush; if (background != null && background == ParagraphSearcher.HighlightBrush) { return true; } return false; } /// <summary> /// Get the next or previous run according to <paramref name="forward"/>. /// </summary> /// <param name="currentRun">The current run.</param> /// <param name="forward">True for next false for previous.</param> /// <returns>The next or previous run according to <paramref name="forward"/>.</returns> private static Run GetNextRun(Run currentRun, bool forward) { Bold parentBold = currentRun.Parent as Bold; Inline nextInline; if (forward) { nextInline = parentBold != null ? ((Inline)parentBold).NextInline : currentRun.NextInline; } else { nextInline = parentBold != null ? ((Inline)parentBold).PreviousInline : currentRun.PreviousInline; } return GetRun(nextInline); } /// <summary> /// Gets the run of an inline. Inlines in a ParagrahBuilder are either a Run or a Bold /// which contains a Run. /// </summary> /// <param name="inline">Inline to get the run from.</param> /// <returns>The run of the inline.</returns> private static Run GetRun(Inline inline) { Bold inlineBold = inline as Bold; if (inlineBold != null) { return (Run)inlineBold.Inlines.FirstInline; } return (Run)inline; } /// <summary> /// Gets the next highlighted run starting and including <paramref name="currentRun"/> /// according to the direction specified in <paramref name="forward"/>. /// </summary> /// <param name="currentRun">The current run.</param> /// <param name="forward">True for next false for previous.</param> /// <returns> /// the next highlighted run starting and including <paramref name="currentRun"/> /// according to the direction specified in <paramref name="forward"/>. /// </returns> private static Run GetNextMatch(Run currentRun, bool forward) { while (currentRun != null) { if (ParagraphSearcher.Ishighlighted(currentRun)) { return currentRun; } currentRun = ParagraphSearcher.GetNextRun(currentRun, forward); } return currentRun; } /// <summary> /// Gets the run's paragraph. /// </summary> /// <param name="run">Run to get the paragraph from.</param> /// <returns>The run's paragraph.</returns> private static Paragraph GetParagraph(Run run) { Bold parentBold = run.Parent as Bold; Paragraph parentParagraph = (parentBold != null ? parentBold.Parent : run.Parent) as Paragraph; Debug.Assert(parentParagraph != null, "the documents we are saerching are built with ParagraphBuilder, which builds the document like this"); return parentParagraph; } /// <summary> /// Returns true if the run is the first run of the paragraph. /// </summary> /// <param name="run">Run to check.</param> /// <returns>True if the run is the first run of the paragraph.</returns> private static bool IsFirstRun(Run run) { Paragraph paragraph = GetParagraph(run); Run firstRun = ParagraphSearcher.GetRun(paragraph.Inlines.FirstInline); return run == firstRun; } /// <summary> /// Gets the first or lasr run in the paragraph containing <paramref name="caretRun"/>. /// </summary> /// <param name="caretRun">Run containing the caret.</param> /// <param name="forward">True for first false for last.</param> /// <returns>The first or last run in the paragraph containing <paramref name="caretRun"/>.</returns> private static Run GetFirstOrLastRun(Run caretRun, bool forward) { Debug.Assert(caretRun != null, "a caret run is always valid"); Paragraph paragraph = GetParagraph(caretRun); Inline firstOrLastInline; if (forward) { firstOrLastInline = paragraph.Inlines.FirstInline; } else { firstOrLastInline = paragraph.Inlines.LastInline; } return GetRun(firstOrLastInline); } } }