Example #1
0
 private void buttonReplaceAll_Click(object sender, EventArgs e)
 {
     foreach (var result in _resultMap)
     {
         FinderHelpers.ReplaceText(result.Value, tbSearchKey.Text, tbReplaceKey.Text);
     }
 }
Example #2
0
        private void buttonReplace_Click(object sender, EventArgs e)
        {
            var key = int.Parse(listResults.SelectedItems[0].SubItems[0].Text);

            Microsoft.Office.Interop.Word.Range selRng = listResults.SelectedItems.Count != 0 ? _resultMap[key] : null;
            if (selRng != null)
            {
                FinderHelpers.ReplaceText(selRng, tbSearchKey.Text, tbReplaceKey.Text);
            }
        }
Example #3
0
        /// <summary>
        /// DoFind is the helper for a regular Find (no proximity).  Very simple logic:
        /// Given a Regex Match, it will iterate through the match adding matches to
        /// the OberservableConcurrentDictionary
        /// </summary>
        /// <param name="match">The regex match based on the Find box text value</param>
        /// <param name="startRange">The Paragraph's start range - we need this for highlighting</param>
        /// <param name="endRange">The Paragraph's end range - we need this for highlighting</param>
        /// <param name="observableResults">The concurrent dictionary we are writing results to</param>
        public static void DoFind(SysRegex.Match match,
                                  int startRange,
                                  int endRange,
                                  OCDictionary observableResults)
        {
            while (match.Success)
            {
                // get actual match start and end range locations
                var beginRangeMatch = startRange + match.Index;
                var endRangeMatch   = beginRangeMatch + match.Length;

                // get some context for the match
                var beginContext = beginRangeMatch >= 5 ? (beginRangeMatch - 5) : beginRangeMatch;
                var endContext   = (endRangeMatch + 5) < endRange ? (endRangeMatch + 5) : endRange;
                FinderHelpers.AddResults(beginRangeMatch, endRangeMatch, beginContext, endContext, observableResults);

                match = match.NextMatch();
            }
        }
Example #4
0
        public static Task FindText(string searchKey,
                                    bool searchKeyCaseSensitive,
                                    ObservableConcurrentDictionary <Word.Range, string> observableResults,
                                    IProgress <int> progress,
                                    CancellationToken cancelToken,
                                    ProxSearchSettings prox = null)
        {
            return(Task.Run(() =>
            {
                var paraVisitedCount = 0;
                var proxIsNull = (prox == null);
                int totalParaCount = DocumentHelpers.ActiveDocument.Paragraphs.Count;
                var pOpts = new ParallelOptions {
                    CancellationToken = cancelToken
                };
                var sKeyRegOpts = searchKeyCaseSensitive ? SysRegex.RegexOptions.None : SysRegex.RegexOptions.IgnoreCase;
                var searchKeyRegex = proxIsNull
                                ? new SysRegex.Regex(searchKey, sKeyRegOpts)
                                : new SysRegex.Regex(searchKey + ".*?" + prox.SearchKey + "|" + prox.SearchKey + ".*?" + searchKey + "|" + searchKey, sKeyRegOpts);

                Parallel.ForEach(DocumentHelpers.GetParagraphsEnumerator(),
                                 pOpts,
                                 (currentParagraph, loopState, index) =>
                {
                    // Catch this cancellation throw in the FindPane to update the pane/results
                    pOpts.CancellationToken.ThrowIfCancellationRequested();
                    var paraRange = ((Word.Paragraph)currentParagraph).Range;

                    // Find all of the single Find matches
                    if (proxIsNull)
                    {
                        FinderHelpers.DoFind(searchKeyRegex.Match(paraRange.Text),
                                             paraRange.Start,
                                             paraRange.End,
                                             observableResults);
                    }

                    #region Proximity Matching
                    // Proximity matching

                    else
                    {
                        // If we are doing interparagraph matching, let's make sure we don't
                        // try to access a paragraph out of bounds
                        if (prox.ParaProximity)
                        {
                            int lookaheadPosition = (int)index + prox.ParaThreshold;
                            int topRange = (lookaheadPosition > totalParaCount)
                                    ? totalParaCount
                                    : lookaheadPosition;
                            //Debug.WriteLine("LAP: " + lookaheadPosition.ToString() +
                            //                "Total: " + totalParaCount.ToString() +
                            //                "topRng: " + topRange.ToString());
                            paraRange.End = prox.ParaEndingRanges[topRange - 1];
                        }

                        IEnumerable <SysRegex.Match> matches = null;
                        if (paraRange.Text != null)
                        {
                            if (!prox.LogicalNot)
                            {
                                searchKeyRegex = new SysRegex.Regex(searchKey + ".*?" + prox.SearchKey, sKeyRegOpts);
                                var proxKeyRegex = new SysRegex.Regex(prox.SearchKey + ".*?" + searchKey, sKeyRegOpts);


                                var skMatches = searchKeyRegex.Matches(paraRange.Text);
                                var pkMatches = proxKeyRegex.Matches(paraRange.Text);
                                matches = skMatches.OfType <SysRegex.Match>()
                                          .Concat(pkMatches.OfType <SysRegex.Match>())
                                          .Where(m => m.Success);
                            }

                            else
                            {
                                // why didn't we do this in the assignment of matches and let the if statement
                                // override its value?  imagine all of the wasted ops this call does
                                // if its not needed!
                                matches = searchKeyRegex.Matches(paraRange.Text).OfType <SysRegex.Match>();
                            }

                            FinderHelpers.DoFindProximity(matches,
                                                          paraRange.Start,
                                                          paraRange.End,
                                                          new SysRegex.Regex(searchKey, sKeyRegOpts),
                                                          prox,
                                                          observableResults);
                        }
                    }
                    #endregion Proximity Matching

                    // Report back our progress
                    progress.Report(++paraVisitedCount);
                });
            }, cancelToken));
        }
Example #5
0
        /// <summary>
        /// DoFindProximity takes matches and decides if they are truly proximity based on
        ///  1. Stripping the match of special characters and extra whitespace
        ///  2. Splitting the match into a list based on whitespace
        /// Once we have a list, we can just walk through the X proximity words to see if a match
        /// exists.  This means you can't search for a word within X words of a hyphen.
        /// </summary>
        /// <param name="matches">Enumberable list of possible matches</param>
        /// <param name="startRange">The Paragraph's start range - we need this for highlighting</param>
        /// <param name="endRange">The Paragraph's end range - we need this for highlighting</param>
        /// <param name="searchKeyRegex">SearchKey</param>
        /// <param name="prox">Prox object, to tell us ProxRegKey, proximity, case sensitive, etc</param>
        /// <param name="observableResults">The concurrent dictionary we are writing results to</param>
        public static void DoFindProximity(IEnumerable <SysRegex.Match> matches,
                                           int startRange,
                                           int endRange,
                                           SysRegex.Regex searchKeyRegex,
                                           ProxSearchSettings prox,
                                           OCDictionary observableResults)
        {
            foreach (var match in matches)
            {
                //  so if our searchKey is "this " and the proxKey is "search", we will match the following with threshold = 5
                //  1. this sentence represents a search string that has a hit
                //      Match:  this.*search
                //  2. search string in this sentence
                //      Match:  search.*this

                //  first lets find our search key
                var searchKeyMatch = searchKeyRegex.Match(match.Value);

                while (searchKeyMatch.Success)
                {
                    var pKeyRegOpts            = prox.CaseSensitive ? SysRegex.RegexOptions.None : SysRegex.RegexOptions.IgnoreCase;
                    var proximityKeyRegex      = new SysRegex.Regex(prox.SearchKey, pKeyRegOpts);
                    var searchKeyMatchEndpoint = searchKeyMatch.Index + searchKeyMatch.Length;

                    //  so if our searchKey is "this " and the proxKey is "search", with a threshold = 5
                    //
                    //  1. this sentence represents a search string that has a hit
                    //     |   ||                     |    |       |
                    //      \ /  \                     \  /       /
                    //  searchKey \                  proxKey     /
                    //             \________afterWords__________/
                    //
                    //  2. search string in this sentence
                    //    ||    |          ||   ||       |
                    //    | \  /           | \ / |       |
                    //    | proxKey        |searchKey    |
                    //    \               /       \     /
                    //     \_beforeWords_/       afterWords

                    string beforeWords = FinderHelpers.GetProximityWords(match.Value.Substring(0, searchKeyMatch.Index), prox.WordThreshold, true);
                    string afterWords  = FinderHelpers.GetProximityWords(match.Value.Substring(searchKeyMatchEndpoint), prox.WordThreshold, false);

                    var beforeMatch = proximityKeyRegex.Match(beforeWords);
                    var afterMatch  = proximityKeyRegex.Match(afterWords);

                    var successPredicate = prox.LogicalNot
                                           ? (!beforeMatch.Success && !afterMatch.Success)
                                           : (beforeMatch.Success || afterMatch.Success);

                    while (successPredicate)
                    {
                        // Find where the match starts - before or after search key
                        int matchIndex = beforeMatch.Success
                            ? ((beforeWords.Length - beforeMatch.Index + 2) * -1)
                            : afterMatch.Success
                              ? afterMatch.Index + afterMatch.Length + 3
                              : 0;

                        int searchKeyIndex = startRange + match.Index + searchKeyMatch.Index;
                        int proxKeyIndex   = searchKeyIndex + matchIndex;
                        int startIndex     = searchKeyIndex < proxKeyIndex ? searchKeyIndex : proxKeyIndex;
                        int endIndex       = searchKeyIndex > proxKeyIndex ? searchKeyIndex : proxKeyIndex;

                        FinderHelpers.AddResults(startIndex, endIndex + searchKeyMatch.Length, observableResults);

                        // So, if we are searching IN proximity, then let's get all matches IN proximity
                        // both the before matches, AND the after matches
                        if (!prox.LogicalNot)
                        {
                            beforeMatch      = beforeMatch.NextMatch();
                            afterMatch       = afterMatch.NextMatch();
                            successPredicate = (beforeMatch.Success || afterMatch.Success);
                        }
                        // Otherwise, we found a match that is NOT in proximity (before/after) of the search word,
                        // so let's take it and break out of the loop (no need to search further...)
                        else
                        {
                            break;
                        }
                    }
                    searchKeyMatch = searchKeyMatch.NextMatch();
                }
            }
        }