Netrix supports some advanced features to manipulate and highlight text.
Using the TextSelector class you can easily manipulate text. The class supports several ways to deal with parts of text. Before start using it, you should understand the basic concepts.
First, there are two views onto a document:
The content view works with the real content. Moving to a character, for example, moves to a character as defined in the documents markup. In display view, the rendered text determines what and where the character is. While in content view there is no such concept such as a line break, in display view it is. Markup might force a line break (BR) but in display view virtual line breaks are added depending on the actual window size.
The most text manipulation operations work with the content view. Here we need ways to get and write text. To select text from a document, pointers are used. Instead of the caret, that points to a specific position and usually reflects mouse operations, a selection needs to points - an endpoint and a startpoint. Internally these pointers are called MarkupPointers and named FirstPointer and SecondPointer.
To deal with whatever is between pointers, a range can be defined. Operations such as highlighting work with ranges. A range is an active selection between pointers.
The following example shows a common function that changes the current word's case (in MS Word, use the Shift-F3 hotkey for same).
private void SetTextCase(string tocase) { ITextSelector ts = EditorDocument.HtmlEditor.TextSelector; ts.MovePointersToCaret(); ts.MoveFirstPointer(MoveTextPointer.PrevWordBegin); ts.MoveSecondPointer(MoveTextPointer.PrevWordEnd); ts.MoveSecondPointer(MoveTextPointer.NextWordEnd); string word = ts.GetTextBetweenPointers(); switch (tocase) { case "upper": word = word.ToUpper(); break; case "lower": word = word.ToLower(); break; case "title": word = (word.Length > 0) ? word[0].ToString().ToUpper() + word.Substring(1) : word; break; } ts.SetTextBetweenPointers(word); }
First, an instance of the TextSelector class is retrieved. Then, the pointers are both moved to the caret's position. Then, the pointers select the current word by being moved around. Then, the text is read. After some custom operation the text is written back to the pointers area. In this example there is no range used, because the text is changed immediately and not selected.
In spellchecker the same technique is used to move from one word to another and highlight it if not found in the dictionary.
Here we highlight text using this code:
void _buttonTextHighLightInvoke_ExecuteEvent(object sender, ExecuteEventArgs e) { // remove first, we can store one collection of pattern only _buttonTextHighLightRemove_ExecuteEvent(sender, e); // reset textHighlightSegments = new List<IHighLightSegment>(); // set properties string searchFor = _comboboxTextHighLightText.StringValue.Trim(); if (String.IsNullOrEmpty(searchFor)) { MessageBox.Show(this, "You cannot invoke this method because there is no text to look for.", "Error Using Function", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { // search and highlight EditorDocument.HtmlEditor.TextSelector.SetHighLightStyle(currentStyle); while (EditorDocument.HtmlEditor.TextSelector.FindTextBetweenPointers(searchFor, false, false, true)) { EditorDocument.HtmlEditor.TextSelector.HighLightRange(); textHighlightSegments.Add(EditorDocument.HtmlEditor.TextSelector.LastSegment); } } }
The idea is to show user positions in the text without changing the markup. Each range found can be stored as a so-called Segment and this segment can be used to keep a list of selections and subsequently removing the highlights properly.
The selection option are based on three classes: HtmlSelection (to retrieve), HtmlFormatting (to invoke SelectAll method), and TextSelector (all more advanced options). In this example you can programmatically retrieve the current selection the user has made and set the selection to a word, sentence, paragraph, or whole document. The code for all these options is very straight forward (ExecuteEvent handler being invoked by the ribbon):
void _buttonGroupTextSelectAll_ExecuteEvent(object sender, ExecuteEventArgs e) { EditorDocument.HtmlEditor.TextFormatting.SelectAll(); } void _buttonGroupTextSelectParagraph_ExecuteEvent(object sender, ExecuteEventArgs e) { ITextSelector ts = EditorDocument.HtmlEditor.TextSelector; ts.ResetRangePointers(); ts.MovePointersToCaret(); ts.MoveFirstPointer(MoveTextPointer.PrevBlock); ts.MoveSecondPointer(MoveTextPointer.NextBlock); ts.SelectPointerRange(true); } void _buttonGroupTextSelectSentence_ExecuteEvent(object sender, ExecuteEventArgs e) { ITextSelector ts = EditorDocument.HtmlEditor.TextSelector; ts.ResetRangePointers(); ts.MovePointersToCaret(); ts.MoveFirstPointer(MoveTextPointer.PrevSentence); ts.MoveSecondPointer(MoveTextPointer.NextSentence); ts.MoveSecondPointer(MoveTextPointer.PrevClusterEnd); ts.SelectPointerRange(true); } void _buttonGroupTextSelectWord_ExecuteEvent(object sender, ExecuteEventArgs e) { ITextSelector ts = EditorDocument.HtmlEditor.TextSelector; ts.ResetRangePointers(); ts.MovePointersToCaret(); ts.MoveFirstPointer(MoveTextPointer.PrevWordBegin); ts.MoveSecondPointer(MoveTextPointer.PrevWordEnd); ts.MoveSecondPointer(MoveTextPointer.NextWordEnd); ts.SelectPointerRange(true); } void _buttonGroupTextShowSelection_ExecuteEvent(object sender, ExecuteEventArgs e) { if (EditorDocument.HtmlEditor.Selection.HasTextSelection) { MessageBox.Show(this, String.Format("Current selection in the document is:\n\n{0}", EditorDocument.HtmlEditor.Selection.Text), "Selection", MessageBoxButtons.OK); } }
The MoveTextPointer enum gives the available options to move the pointers subsequently used to create the selection. The pointers mark the selection's boundaries, then. The select the exact boundaries of the text's fragment you're looking for it's often necessary to move the pointer twice. For example, to get the beginning of a word, the PrevXXX and NextXXX options would move away from the current word (because of the lack of a "CurrentXXX" option). Hence, you have to move to the word before and to the right position of the next word (which is the former "current" word), then. The word selection code shows exactly this.
Add a search text, usually a word found one or more times in the document in the textbox on the ribbon. Set a line pattern you like. Click "Highlight Text", then.
For manipulate text operation, click a word and click a button, then.
For selection place cursor inside the text and click the options. To retrieve the selection, select a text fragment and click the button.