Esempio n. 1
0
        /// <summary>
        /// Applies one step of the async highlighting against the main scheme.
        /// </summary>
        /// <returns>Whether another step should be called.</returns>
        protected bool StepHiliteMain(AsyncHighlightState state)
        {
            if (!state.Enum.MoveNext())
            {
                state.ActualSearchHits = state.Words; // As the main scheme has succeeded, the original word list is the same as the final one
                return(false);                        // Over!
            }

            // Get the current word
            WordPtr word = (WordPtr)state.Enum.Current;

            if (word.StartOffset < 0)
            {
                return(StartHiliteBackup(state));                  // Fallback to the backup scheme
            }
            // Choose a color for highlighting this word
            state.PickNextColor(word.Original);

            // Select the supposed search hit location
            Select(word.StartOffset, word.Text.Length);

            // Check whether we've selected the proper thing
            if (String.Compare(SelectedText, word.Text, true, CultureInfo.InvariantCulture) != 0)
            {
                Trace.WriteLine(String.Format("Main highlighting expected to find \"{0}\" but got \"{1}\", aborting.", word.Text, SelectedText), "[JRTB]");
                return(StartHiliteBackup(state));                  // Fallback to the backup scheme
            }

            // Apply the coloring!!
            Win32Declarations.SendMessage(Handle, EditMessage.SETCHARFORMAT, SCF.SELECTION, ref state.Fmt);

            return(true);            // Call more
        }
Esempio n. 2
0
        /// <summary>
        /// Initiates the async highlighting of the search hits.
        /// </summary>
        /// <param name="words">Words to be highlighted. MUST belong to a single document section.</param>
        public void HighlightWords(WordPtr[] words)
        {
            #region Preconditions
            if (words == null)
            {
                return;
            }

            // Validness check
            WordPtr.AssertValid(words, true);
            #endregion Preconditions

            _wordsSearchHits = null;             // Here the real search hits will be stored; in case of main highlighting they correspond to the ones passed in
            _statuswriter    = Core.UIManager.GetStatusWriter(this, StatusPane.UI);
            _statuswriter.ShowStatus("Highlighting search hits in the document…");

            // Initiate the async hilite process
            _stateHilite = new AsyncHighlightState(words);
            if (StartHiliteMain(_stateHilite))
            {
                Core.UserInterfaceAP.QueueJobAt(DateTime.Now.AddMilliseconds(500), "Highlight the search hits.", new MethodInvoker(StepHilite));                       // Succeeded — queue execution
            }
            else
            {             // Failed — deinitialize
                _stateHilite = null;
                _statuswriter.ClearStatus();
                _statuswriter = null;
                Trace.WriteLine("Failed to initiate the main highlighting scheme.", "[JRTB]");
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Does the asynchronous highlighting step.
        /// </summary>
        private void StepHilite()
        {
            if (_stateHilite == null)
            {
                return;                 // Has been shut down
            }
            uint dwStart = Win32Declarations.GetTickCount();
            uint dwLimit = 222;             // Allow running for this much milliseconds continuously

            // Freeze the control
            Win32Declarations.SendMessage(Handle, Win32Declarations.WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);

            try
            {
                int nIterations;
                for (nIterations = 0; Win32Declarations.GetTickCount() - dwStart < dwLimit; nIterations++) // Work for some limited time
                {
                    if (!_stateHilite.StepHiliteDelegate(_stateHilite))                                    // Invoke the individual highlighting step
                    {                                                                                      // Highlighting Completed!
                        // Reset the status bar dials
                        _statuswriter.ClearStatus();
                        _statuswriter = null;

                        // Retrieve the values
                        _wordsSearchHits   = _stateHilite.ActualSearchHits;
                        _nCurrentSearchHit = -1;

                        // Deinitialize the hilite search
                        _stateHilite = null;

                        // Jump to the next search hit
                        GotoNextSearchHit(true, false);

                        // Invalidate
                        Win32Declarations.SendMessage(Handle, Win32Declarations.WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
                        Invalidate();

                        // Done!
                        Trace.WriteLine(String.Format("The JetRichTextBox has completed the async highlighting with {0} hits total.", (_wordsSearchHits != null ? _wordsSearchHits.Length.ToString() : "#ERROR#")), "[JRTB]");
                        return;
                    }
                }
                Trace.WriteLine(String.Format("The JetRichTextBox async highlighting has done {0} highlightings on this step.", nIterations), "[JRTB]");
            }
            finally
            {
                // Unfreeze the events and repaint
                Win32Declarations.SendMessage(Handle, Win32Declarations.WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
                if ((_stateHilite != null) && (Win32Declarations.GetTickCount() - _stateHilite.LastRepaintTime > 2000))                  // Repaint rarely
                {
                    Invalidate();
                    _stateHilite.LastRepaintTime = Win32Declarations.GetTickCount();
                }
            }

            // Requeue the rest of execution
            Application.DoEvents();             // Without this, the painting events won't occur
            Core.UserInterfaceAP.QueueJob("Highlight the search hits.", new MethodInvoker(StepHilite));
        }
Esempio n. 4
0
        /// <summary>
        /// Starts applying the main highlighting scheme that uses the provided offsets for highlighting the text.
        /// In case the offsets do not hit the expected words, aborts the highlighting and returns <c>Null</c>,
        /// indicating that the backup scheme should be used.
        /// </summary>
        /// <returns>Success flag.</returns>
        protected bool StartHiliteMain(AsyncHighlightState state)
        {
            state.StepHiliteDelegate = new AsyncHighlightState.StepHiliteAny(StepHiliteMain);

            // Assign the entries for highlighting
            state.Enum = state.Words.GetEnumerator();

            return(true);
        }
Esempio n. 5
0
 protected override void Dispose(bool disposing)
 {
     base.Dispose(disposing);
     _stateHilite = null;             // Stop the currently-running highlighting
     if (_statuswriter != null)
     {
         _statuswriter.ClearStatus();
         _statuswriter = null;
     }
     _wordsSearchHits   = null;
     _nCurrentSearchHit = -1;
 }
Esempio n. 6
0
        /// <summary>
        /// Applies one step of the async highlighting against the backup scheme.
        /// </summary>
        /// <returns>Whether another step should be called.</returns>
        protected bool StepHiliteBackup(AsyncHighlightState state)
        {
            if (state.CurPos < 0)              // Should we pick a new word form for searching it?
            {
                if (!state.Enum.MoveNext())
                {                 // Completed!!
                    // Sort the search hits in order of appearance and supply to the storage
                    state.ActualSearchHitsCache.Sort(new WordPtrOffsetComparer());
                    state.ActualSearchHits = (WordPtr[])state.ActualSearchHitsCache.ToArray(typeof(WordPtr)); // Take the search hits
                    return(false);                                                                            // Finish it
                }
                state.CurPos = 0;                                                                             // Start looking for it from the beginning
            }
            string  sOriginal     = (string)state.Enum.Current;
            WordPtr wordSearchHit = (WordPtr)state.HashWordForms[sOriginal];

            // Choose a color for highlighting the hits of this text
            state.PickNextColor(wordSearchHit.Original);

            // Look for the next entry, starting from the very place we left it the prev time
            int nOldPos = state.CurPos;

            state.CurPos = Find(wordSearchHit.Text, state.CurPos, RichTextBoxFinds.NoHighlight | RichTextBoxFinds.WholeWord);
            if (state.CurPos < 0)        // If not found, will be negative
            {
                return(true);            // Switch to looking for the next entry, or complete the process if there are no more
            }
            if (state.CurPos <= nOldPos) // Sometimes the Find function will return a result BEFORE the search start :)
            {                            // Switch to looking for the next entry, or complete the process if there are no more
                state.CurPos = -1;
                return(true);
            }

            // Add the search hit data
            WordPtr hit = wordSearchHit;             // Make a copy of the hit

            hit.StartOffset = state.CurPos;          // The actual starting offset
            state.ActualSearchHitsCache.Add(hit);

            // Select the supposed search hit location
            Select(state.CurPos, wordSearchHit.Text.Length);
            state.CurPos += wordSearchHit.Text.Length;             // Skip the already-found entry (otherwise we'll keep finding it again and again, eternally)

            // Apply the coloring!!
            Win32Declarations.SendMessage(Handle, EditMessage.SETCHARFORMAT, SCF.SELECTION, ref state.Fmt);

            return(true);            // Try looking for the next entry
        }
Esempio n. 7
0
        /// <summary>
        /// Starts applying the backup hilite scheme that applies when the main scheme fails.
        /// It searches for the entries in the text and ignores the offsets given as they're assumed to be incorrect.
        /// </summary>
        /// <returns>Success flag.</returns>
        protected bool StartHiliteBackup(AsyncHighlightState state)
        {
            state.StepHiliteDelegate = new AsyncHighlightState.StepHiliteAny(StepHiliteBackup);

            // Make a hash of the words to highlight (the particular word forms)
            state.HashWordForms = new Hashtable(state.Words.Length);
            foreach (WordPtr word in state.Words)
            {
                state.HashWordForms[word.Text] = word;
            }
            Trace.WriteLine(String.Format("{0} unique forms were picked out of {1} original word-ptrs.", state.HashWordForms.Count, state.Words.Length), "[JRTB]");

            // Seed the process
            state.Enum = state.HashWordForms.Keys.GetEnumerator();
            state.ActualSearchHitsCache = new ArrayList(state.HashWordForms.Count);
            state.CurPos = -1;

            // Go on
            return(true);
        }