Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ParagraphSearcher.cs242 linesDownload Raw Back to HelpWindow
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Diagnostics;5using System.Windows.Documents;6using System.Windows.Media;7 8namespace Microsoft.Management.UI.Internal9{10    /// <summary>11    /// Moves through search highlights built in a ParagraphBuilder12    /// changing the color of the current highlight.13    /// </summary>14    internal class ParagraphSearcher15    {16        /// <summary>17        /// Highlight for all matches except the current.18        /// </summary>19        internal static readonly Brush HighlightBrush = Brushes.Yellow;20 21        /// <summary>22        /// Highlight for the current match.23        /// </summary>24        private static readonly Brush CurrentHighlightBrush = Brushes.Cyan;25 26        /// <summary>27        /// Current match being highlighted in search.28        /// </summary>29        private Run currentHighlightedMatch;30 31        /// <summary>32        /// Initializes a new instance of the ParagraphSearcher class.33        /// </summary>34        internal ParagraphSearcher()35        {36        }37 38        /// <summary>39        /// Move to the next highlight starting at the <paramref name="caretPosition"/>.40        /// </summary>41        /// <param name="forward">True for next false for previous.</param>42        /// <param name="caretPosition">Caret position.</param>43        /// <returns>The next highlight starting at the <paramref name="caretPosition"/>.</returns>44        internal Run MoveAndHighlightNextNextMatch(bool forward, TextPointer caretPosition)45        {46            Debug.Assert(caretPosition != null, "a caret position is always valid");47            Debug.Assert(caretPosition.Parent != null && caretPosition.Parent is Run, "a caret Parent is always a valid Run");48            Run caretRun = (Run)caretPosition.Parent;49 50            Run currentRun;51 52            if (this.currentHighlightedMatch != null)53            {54                // restore the curent highlighted background to plain highlighted55                this.currentHighlightedMatch.Background = ParagraphSearcher.HighlightBrush;56            }57 58            // If the caret is in the end of a highlight we move to the adjacent run59            // It has to be in the end because if there is a match at the beginning of the file60            // and the caret has not been touched (so it is in the beginning of the file too)61            // we want to highlight this first match.62            // Considering the caller always set the caret to the end of the highlight63            // The condition below works well for successive searchs64            // We also need to move to the adjacent run if the caret is at the first run and we65            // are moving backwards so that a search backwards when the first run is highlighted66            // and the caret is at the beginning will wrap to the end67            if ((!forward && IsFirstRun(caretRun)) ||68                ((caretPosition.GetOffsetToPosition(caretRun.ContentEnd) == 0) && ParagraphSearcher.Ishighlighted(caretRun)))69            {70                currentRun = ParagraphSearcher.GetNextRun(caretRun, forward);71            }72            else73            {74                currentRun = caretRun;75            }76 77            currentRun = ParagraphSearcher.GetNextMatch(currentRun, forward);78 79            if (currentRun == null)80            {81                // if we could not find a next highlight wraparound82                currentRun = ParagraphSearcher.GetFirstOrLastRun(caretRun, forward);83                currentRun = ParagraphSearcher.GetNextMatch(currentRun, forward);84            }85 86            this.currentHighlightedMatch = currentRun;87            if (this.currentHighlightedMatch != null)88            {89                // restore the curent highlighted background to current highlighted90                this.currentHighlightedMatch.Background = ParagraphSearcher.CurrentHighlightBrush;91            }92 93            return currentRun;94        }95 96        /// <summary>97        /// Resets the search for fresh calls to MoveAndHighlightNextNextMatch.98        /// </summary>99        internal void ResetSearch()100        {101            this.currentHighlightedMatch = null;102        }103 104        /// <summary>105        /// Returns true if <paramref name="run"/> is highlighted.106        /// </summary>107        /// <param name="run">Run to check if is highlighted.</param>108        /// <returns>True if <paramref name="run"/> is highlighted.</returns>109        private static bool Ishighlighted(Run run)110        {111            if (run == null)112            {113                return false;114            }115 116            SolidColorBrush background = run.Background as SolidColorBrush;117            if (background != null && background == ParagraphSearcher.HighlightBrush)118            {119                return true;120            }121 122            return false;123        }124 125        /// <summary>126        /// Get the next or previous run according to <paramref name="forward"/>.127        /// </summary>128        /// <param name="currentRun">The current run.</param>129        /// <param name="forward">True for next false for previous.</param>130        /// <returns>The next or previous run according to <paramref name="forward"/>.</returns>131        private static Run GetNextRun(Run currentRun, bool forward)132        {133            Bold parentBold = currentRun.Parent as Bold;134 135            Inline nextInline;136 137            if (forward)138            {139                nextInline = parentBold != null ? ((Inline)parentBold).NextInline : currentRun.NextInline;140            }141            else142            {143                nextInline = parentBold != null ? ((Inline)parentBold).PreviousInline : currentRun.PreviousInline;144            }145 146            return GetRun(nextInline);147        }148 149        /// <summary>150        /// Gets the run of an inline. Inlines in a ParagrahBuilder are either a Run or a Bold151        /// which contains a Run.152        /// </summary>153        /// <param name="inline">Inline to get the run from.</param>154        /// <returns>The run of the inline.</returns>155        private static Run GetRun(Inline inline)156        {157            Bold inlineBold = inline as Bold;158            if (inlineBold != null)159            {160                return (Run)inlineBold.Inlines.FirstInline;161            }162 163            return (Run)inline;164        }165 166        /// <summary>167        /// Gets the next highlighted run starting and including <paramref name="currentRun"/>168        /// according to the direction specified in <paramref name="forward"/>.169        /// </summary>170        /// <param name="currentRun">The current run.</param>171        /// <param name="forward">True for next false for previous.</param>172        /// <returns>173        /// the next highlighted run starting and including <paramref name="currentRun"/>174        /// according to the direction specified in <paramref name="forward"/>.175        /// </returns>176        private static Run GetNextMatch(Run currentRun, bool forward)177        {178            while (currentRun != null)179            {180                if (ParagraphSearcher.Ishighlighted(currentRun))181                {182                    return currentRun;183                }184 185                currentRun = ParagraphSearcher.GetNextRun(currentRun, forward);186            }187 188            return currentRun;189        }190 191        /// <summary>192        /// Gets the run's paragraph.193        /// </summary>194        /// <param name="run">Run to get the paragraph from.</param>195        /// <returns>The run's paragraph.</returns>196        private static Paragraph GetParagraph(Run run)197        {198            Bold parentBold = run.Parent as Bold;199            Paragraph parentParagraph = (parentBold != null ? parentBold.Parent : run.Parent) as Paragraph;200            Debug.Assert(parentParagraph != null, "the documents we are saerching are built with ParagraphBuilder, which builds the document like this");201            return parentParagraph;202        }203 204        /// <summary>205        /// Returns true if the run is the first run of the paragraph.206        /// </summary>207        /// <param name="run">Run to check.</param>208        /// <returns>True if the run is the first run of the paragraph.</returns>209        private static bool IsFirstRun(Run run)210        {211            Paragraph paragraph = GetParagraph(run);212            Run firstRun = ParagraphSearcher.GetRun(paragraph.Inlines.FirstInline);213            return run == firstRun;214        }215 216        /// <summary>217        /// Gets the first or lasr run in the paragraph containing <paramref name="caretRun"/>.218        /// </summary>219        /// <param name="caretRun">Run containing the caret.</param>220        /// <param name="forward">True for first false for last.</param>221        /// <returns>The first or last run in the paragraph containing <paramref name="caretRun"/>.</returns>222        private static Run GetFirstOrLastRun(Run caretRun, bool forward)223        {224            Debug.Assert(caretRun != null, "a caret run is always valid");225 226            Paragraph paragraph = GetParagraph(caretRun);227 228            Inline firstOrLastInline;229            if (forward)230            {231                firstOrLastInline = paragraph.Inlines.FirstInline;232            }233            else234            {235                firstOrLastInline = paragraph.Inlines.LastInline;236            }237 238            return GetRun(firstOrLastInline);239        }240    }241}242