public static swd.TextPointer GetTextPositionAtOffset(this swd.TextPointer position, int characterCount) { while (position != null) { if (position.GetPointerContext(swd.LogicalDirection.Forward) == swd.TextPointerContext.Text) { int count = position.GetTextRunLength(swd.LogicalDirection.Forward); if (count >= characterCount) { return(position.GetPositionAtOffset(characterCount)); } characterCount -= count; } var nextContextPosition = position.GetNextContextPosition(swd.LogicalDirection.Forward); if (nextContextPosition == null) { return(position); } position = nextContextPosition; } return(position); }
TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount) { while (position != null) { var context = position.GetPointerContext(LogicalDirection.Forward); if (context == TextPointerContext.Text) { var count = position.GetTextRunLength(LogicalDirection.Forward); if (characterCount <= count) { return position.GetPositionAtOffset(characterCount); } characterCount -= count; } else if (position.Parent is LineBreak) { var count = 2; if (characterCount <= count) { return position.GetPositionAtOffset(characterCount); } characterCount -= count; } var nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward); if (nextContextPosition == null) return position; position = nextContextPosition; } return position; }
/// <summary> /// Creates a new Run instance. /// </summary> /// <param name="text"> /// Optional text content. May be null. /// </param> /// <param name="insertionPosition"> /// Optional position at which to insert the new Run. May /// be null. /// </param> public Run(string text, TextPointer insertionPosition) { if (insertionPosition != null) { insertionPosition.TextContainer.BeginChange(); } try { if (insertionPosition != null) { // This will throw InvalidOperationException if schema validity is violated. insertionPosition.InsertInline(this); } if (text != null) { // No need to duplicate the string data in TextProperty here. TextContainer will // set the property to a deferred reference. this.ContentStart.InsertTextInRun(text); } } finally { if (insertionPosition != null) { insertionPosition.TextContainer.EndChange(); } } }
//------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors /// <summary> /// Creates a new AnchoredBlock instance. /// </summary> /// <param name="block"> /// Optional child of the new AnchoredBlock, may be null. /// </param> /// <param name="insertionPosition"> /// Optional position at which to insert the new AnchoredBlock. May /// be null. /// </param> protected AnchoredBlock(Block block, TextPointer insertionPosition) { if (insertionPosition != null) { insertionPosition.TextContainer.BeginChange(); } try { if (insertionPosition != null) { // This will throw InvalidOperationException if schema validity is violated. insertionPosition.InsertInline(this); } if (block != null) { this.Blocks.Add(block); } } finally { if (insertionPosition != null) { insertionPosition.TextContainer.EndChange(); } } }
public static TextEffectTarget[] Resolve(TextPointer startPosition, TextPointer endPosition, System.Windows.Media.TextEffect effect) { Contract.Requires(endPosition != null); Contract.Ensures(Contract.Result<System.Windows.Documents.TextEffectTarget[]>() != null); return default(TextEffectTarget[]); }
// Helper for GetPositionAtWordBoundary. // Returns true when passed TextPointer is next to a wordBreak in requested direction. private static bool IsPositionNextToWordBreak(TextPointer position, LogicalDirection wordBreakDirection) { bool isAtWordBoundary = false; // Skip over any formatting. if (position.GetPointerContext(wordBreakDirection) != TextPointerContext.Text) { position = position.GetInsertionPosition(wordBreakDirection); } if (position.GetPointerContext(wordBreakDirection) == TextPointerContext.Text) { LogicalDirection oppositeDirection = (wordBreakDirection == LogicalDirection.Forward) ? LogicalDirection.Backward : LogicalDirection.Forward; char[] runBuffer = new char[1]; char[] oppositeRunBuffer = new char[1]; position.GetTextInRun(wordBreakDirection, runBuffer, /*startIndex*/0, /*count*/1); position.GetTextInRun(oppositeDirection, oppositeRunBuffer, /*startIndex*/0, /*count*/1); if (runBuffer[0] == ' ' && !(oppositeRunBuffer[0] == ' ')) { isAtWordBoundary = true; } } else { // If we're not adjacent to text then we always want to consider this position a "word break". // In practice, we're most likely next to an embedded object or a block boundary. isAtWordBoundary = true; } return isAtWordBoundary; }
//------------------------------------------------------ // // Protected Methods // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal methods. /// <summary> /// Reads the document from the reader into the specified position. /// </summary> internal void Read(XmlReader reader, TextPointer position) { System.Diagnostics.Debug.Assert(reader != null); System.Diagnostics.Debug.Assert(position != null); ReadDocument(reader, position); }
internal static TextPointer SplitFormattingElement(TextPointer splitPosition, bool keepEmptyFormatting) { Invariant.Assert(splitPosition.Parent != null && TextSchema.IsMergeableInline(splitPosition.Parent.GetType())); Inline inline = (Inline)splitPosition.Parent; // Create a movable copy of a splitPosition if (splitPosition.IsFrozen) { splitPosition = new TextPointer(splitPosition); } if (!keepEmptyFormatting && splitPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { // The first part of element is empty. We are allowed to remove empty formatting elements, // so we can simply move splitPotision outside of the element and we are done splitPosition.MoveToPosition(inline.ElementStart); } else if (!keepEmptyFormatting && splitPosition.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd) { // The second part of element is empty. We are allowed to remove empty formatting elements, // so we can simply move splitPotision outside of the element and we are done. splitPosition.MoveToPosition(inline.ElementEnd); } else { splitPosition = SplitElement(splitPosition); } return splitPosition; }
// Helper that returns a word preceeding the passed position in its paragraph, // wordStartPosition points to the start position of word. private static string GetPreceedingWordInParagraph(TextPointer position, out TextPointer wordStartPosition) { wordStartPosition = null; string word = String.Empty; Paragraph paragraph = position.Paragraph; if (paragraph != null) { TextPointer navigator = position; while (navigator.CompareTo(paragraph.ContentStart) > 0) { string runText = navigator.GetTextInRun(LogicalDirection.Backward); if (runText.Contains(" ")) // Any globalized application would need more sophisticated word break testing. { int index = runText.LastIndexOf(" "); word = runText.Substring(index + 1, runText.Length - index - 1) + word; wordStartPosition = navigator.GetPositionAtOffset(-1 * (runText.Length - index - 1)); break; } else { wordStartPosition = navigator; word = runText + word; } navigator = navigator.GetNextContextPosition(LogicalDirection.Backward); } } return word; }
/// <summary> /// Creates a new Span instance. /// </summary> /// <param name="childInline"> /// Optional child Inline for the new Span. May be null. /// </param> /// <param name="insertionPosition"> /// Optional position at which to insert the new Span. May be null. /// </param> public Span(Inline childInline, TextPointer insertionPosition) { if (insertionPosition != null) { insertionPosition.TextContainer.BeginChange(); } try { if (insertionPosition != null) { // This will throw InvalidOperationException if schema validity is violated. insertionPosition.InsertInline(this); } if (childInline != null) { this.Inlines.Add(childInline); } } finally { if (insertionPosition != null) { insertionPosition.TextContainer.EndChange(); } } }
/// <summary> /// 1. When wordBreakDirection = Forward, returns a position at the end of the word, /// i.e. a position with a wordBreak character (space) following it. /// 2. When wordBreakDirection = Backward, returns a position at the start of the word, /// i.e. a position with a wordBreak character (space) preceeding it. /// 3. Returns null when there is no workbreak in the requested direction. /// </summary> private static TextPointer GetPositionAtWordBoundary(TextPointer position, LogicalDirection wordBreakDirection) { if (!position.IsAtInsertionPosition) { position = position.GetInsertionPosition(wordBreakDirection); } TextPointer navigator = position; while (navigator != null && !IsPositionNextToWordBreak(navigator, wordBreakDirection)) { navigator = navigator.GetNextInsertionPosition(wordBreakDirection); } return navigator; }
public int CompareTo (TextPointer position) { if (position == null) throw new ArgumentNullException ("position"); return NativeMethods.text_pointer_compare_to (native, position.native); }
private void OnKeyDown(object sender, KeyEventArgs e) { if (e.Key != Key.Back && e.Key != Key.Space && e.Key != Key.Return) { return; } if (!Selection.IsEmpty) { Selection.Text = string.Empty; } if (e.Key == Key.Space || e.Key == Key.Return) { myWordsAdded = true; mySelectionStartPosition = Selection.Start; mySelectionEndPosition = Selection.End.GetPositionAtOffset(0, LogicalDirection.Forward); // Hyperlink detection will be done in OnTextChanged() } else // Key.Back { var newCaretPosition = DocumentFacade.RemoveHyperlink(Selection.Start); if (newCaretPosition != null) { // Update selection, since we deleted Hyperlink element and caretPosition was at that Hyperlink's end boundary. Selection.Select(newCaretPosition, newCaretPosition); } } }
/// <summary> /// Perform the appropriate action for this unit. If this is a parent undo unit, the /// parent must create an appropriate parent undo unit to contain the redo units. /// </summary> public override void Do() { UndoManager undoManager; IParentUndoUnit redo; TextPointer textPointerTable; Table table; undoManager = TopContainer as UndoManager; redo = null; textPointerTable = new TextPointer(_textContainer.Start, _cpTable, LogicalDirection.Forward); table = (Table) textPointerTable.Parent; _columnWidths[_columnIndex] -= _resizeAmount; if(_columnIndex < table.ColumnCount - 1) { _columnWidths[_columnIndex + 1] += _resizeAmount; } if(undoManager != null && undoManager.IsEnabled) { redo = new ColumnResizeUndoUnit(textPointerTable, _columnIndex, _columnWidths, -_resizeAmount); undoManager.Open(redo); } TextRangeEditTables.EnsureTableColumnsAreFixedSize(table, _columnWidths); if(redo != null) { undoManager.Close(redo, UndoCloseAction.Commit); } }
//------------------------------------------------------ // // Public Methods // //------------------------------------------------------ #region Public Methods // Called by the undo manager. Restores tree state to its condition // when the unit was created. Assumes the tree state matches conditions // just after the unit was created. public override void DoCore() { TextPointer start; TextPointer end; TextElement element; VerifyTreeContentHashCode(); start = new TextPointer(this.TextContainer, this.SymbolOffset, LogicalDirection.Forward); end = new TextPointer(this.TextContainer, this.SymbolOffset + _symbolCount - 2, LogicalDirection.Forward); // Insert a new element. element = (TextElement)Activator.CreateInstance(_type); element.Reposition(start, end); // Restore local resources element.Resources = _resources; // Move end into the scope of the new element. end.MoveToNextContextPosition(LogicalDirection.Backward); // Then restore local property values. // this.TextContainer.SetValues(end, ArrayToLocalValueEnumerator(_localValues)); if (element is Table) { TextTreeDeleteContentUndoUnit.RestoreColumns((Table)element, _columns); } }
//------------------------------------------------------ // // Public Methods // //------------------------------------------------------ #region Public Methods // Called by the undo manager. Restores tree state to its condition // when the unit was created. Assumes the tree state matches conditions // just after the unit was created. public override void DoCore() { TextPointer start; TextPointer end; TextElement element; VerifyTreeContentHashCode(); start = new TextPointer(this.TextContainer, this.SymbolOffset, LogicalDirection.Forward); Invariant.Assert(start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextTree undo unit out of [....] with TextTree."); element = start.GetAdjacentElementFromOuterPosition(LogicalDirection.Forward); if (_deep) { // Extract the element and its content. end = new TextPointer(this.TextContainer, element.TextElementNode, ElementEdge.AfterEnd); this.TextContainer.DeleteContentInternal(start, end); } else { // Just extract the element, not its content. this.TextContainer.ExtractElementInternal(element); } }
public bool CanMerge(RichTextBox edit, TextPointer insertPosition) { if (edit.Document.ContentStart.GetOffsetToPosition(insertPosition) == __OffsetEnd && insertPosition.IsAtInsertionPosition) return true; return false; }
public int CompareTo(TextPointer position) { Contract.Requires(position != null); Contract.Ensures(-1 <= Contract.Result<int>()); Contract.Ensures(Contract.Result<int>() <= 1); return default(int); }
// Helper that returns true if passed caretPosition and backspacePosition cross a hyperlink end boundary // (under the assumption that caretPosition and backSpacePosition are adjacent insertion positions). private static bool IsHyperlinkBoundaryCrossed(TextPointer caretPosition, TextPointer backspacePosition, out Hyperlink backspacePositionHyperlink) { Hyperlink caretPositionHyperlink = GetHyperlinkAncestor(caretPosition); backspacePositionHyperlink = GetHyperlinkAncestor(backspacePosition); return (caretPositionHyperlink == null && backspacePositionHyperlink != null) || (caretPositionHyperlink != null && backspacePositionHyperlink != null && caretPositionHyperlink != backspacePositionHyperlink); }
internal static TextPointer SafePositionAtOffset(FlowDocument document, TextPointer textPointer, int offsetStart) { var pointer = textPointer.GetPositionAtOffset(offsetStart); if (pointer == null) return document.ContentEnd; return pointer; }
private void OnPasted(object sender, DataObjectPastingEventArgs e) { myWordsAdded = true; mySelectionStartPosition = Selection.Start; mySelectionEndPosition = Selection.IsEmpty ? Selection.End.GetPositionAtOffset(0, LogicalDirection.Forward) : Selection.End; // Hyperlink detection will be done in OnTextChanged() }
//------------------------------------------------------ // // Public Methods // //------------------------------------------------------ //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //------------------------------------------------------ // // Protected Methods // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal methods. /// <summary> /// Writes the container into the specified XmlWriter. /// </summary> internal void Write(TextPointer start, TextPointer end, XmlWriter writer) { System.Diagnostics.Debug.Assert(start != null); System.Diagnostics.Debug.Assert(end != null); System.Diagnostics.Debug.Assert(start.CompareTo(end) <= 0); System.Diagnostics.Debug.Assert(writer != null); WriteContainer(start, end, writer); }
internal ColumnResizeUndoUnit(TextPointer textPointerTable, int columnIndex, double[] columnWidths, double resizeAmount) : base("ColumnResize") { _textContainer = textPointerTable.TextContainer; _cpTable = _textContainer.Start.GetOffsetToPosition(textPointerTable); _columnWidths = columnWidths; _columnIndex = columnIndex; _resizeAmount = resizeAmount; }
public void Select (TextPointer anchorPosition, TextPointer movingPosition) { if (anchorPosition == null) throw new ArgumentNullException ("anchorPosition"); if (movingPosition == null) throw new ArgumentNullException ("movingPosition"); NativeMethods.text_selection_select (native, anchorPosition.native, movingPosition.native); }
public FindAndReplaceManager(FlowDocument inputDocument) { if (inputDocument == null) { throw new ArgumentNullException("需要给构造函数传入一个有效的FlowDocument对象"); } this.inputDocument = inputDocument; this.currentPosition = inputDocument.ContentStart; }
//--------------------------- // public static methods //--------------------------- /// <summary> /// resolves text effect on a text range to a list of text effect targets. /// The method will walk the text and perform the following task: /// 1) For each continous block of text, create a text effect targeting the scoping element /// 2) For the text effect created, calculate the starting cp index and cp count for the effect /// /// The method will create freezable copy of the TextEffect passed in and fill in /// CharacterIndex and Count for the range. /// </summary> /// <param name="startPosition">starting text pointer</param> /// <param name="endPosition">end text pointer</param> /// <param name="effect">effect that is apply on the text</param> public static TextEffectTarget[] Resolve( TextPointer startPosition, TextPointer endPosition, TextEffect effect ) { if (effect == null) throw new ArgumentNullException("effect"); ValidationHelper.VerifyPositionPair(startPosition, endPosition); TextPointer effectStart = new TextPointer(startPosition); // move to the first character symbol at or after Start position MoveToFirstCharacterSymbol(effectStart); TextEffect effectCopy; List<TextEffectTarget> list = new List<TextEffectTarget>(); // we will now traverse the TOM and resolve text effects to the immediate parent // of the characters. We are effectively applying the text effect onto // block of continous text. while (effectStart.CompareTo(endPosition) < 0) { // create a copy of the text effect // so that we can set the CharacterIndex and Count effectCopy = effect.Clone(); // create a position TextPointer continuousTextEnd = new TextPointer(effectStart); // move the position to the end of the continuous text block MoveToFirstNonCharacterSymbol(continuousTextEnd, endPosition); // make sure we are not out of the range continuousTextEnd = (TextPointer)TextPointerBase.Min(continuousTextEnd, endPosition); // set the character index to be the distance from the Start // of this text block to the Start of the text container effectCopy.PositionStart = effectStart.TextContainer.Start.GetOffsetToPosition(effectStart); // count is the distance from the text block start to end effectCopy.PositionCount = effectStart.GetOffsetToPosition(continuousTextEnd); list.Add( new TextEffectTarget( effectStart.Parent, effectCopy ) ); // move the effectStart to the beginning of the next text block. effectStart = continuousTextEnd; MoveToFirstCharacterSymbol(effectStart); } return list.ToArray(); }
void SetDecorations(swd.TextRange range, sw.TextDecorationCollection decorations, bool value) { using (Control.DeclareChangeBlock()) { // set the property to each element in the range so it keeps all other decorations foreach (var element in range.GetInlineElements()) { var existingDecorations = element.GetValue(swd.Inline.TextDecorationsProperty) as sw.TextDecorationCollection; // need to keep the range before changing otherwise the range changes var elementRange = new swd.TextRange(element.ElementStart, element.ElementEnd); sw.TextDecorationCollection newDecorations = null; // remove decorations from the element element.SetValue(swd.Inline.TextDecorationsProperty, null); if (existingDecorations != null && existingDecorations.Count > 0) { // merge desired decorations with existing decorations. if (value) { newDecorations = new sw.TextDecorationCollection(existingDecorations.Union(decorations)); } else { newDecorations = new sw.TextDecorationCollection(existingDecorations.Except(decorations)); } // split up existing decorations to the parts of the element that don't fall within the range existingDecorations = new sw.TextDecorationCollection(existingDecorations); // copy so we don't update existing elements if (elementRange.Start.CompareTo(range.Start) < 0) { new swd.TextRange(elementRange.Start, range.Start).ApplyPropertyValue(swd.Inline.TextDecorationsProperty, existingDecorations); } if (elementRange.End.CompareTo(range.End) > 0) { new swd.TextRange(range.End, elementRange.End).ApplyPropertyValue(swd.Inline.TextDecorationsProperty, existingDecorations); } } else { // no existing decorations, just set the new value newDecorations = value ? decorations : null; } if (newDecorations != null && newDecorations.Count > 0) { // apply new decorations to the desired range, which may be a combination of existing decorations swd.TextPointer start = elementRange.Start.CompareTo(range.Start) < 0 ? range.Start : elementRange.Start; swd.TextPointer end = elementRange.End.CompareTo(range.End) > 0 ? range.End : elementRange.End; new swd.TextRange(start, end).ApplyPropertyValue(swd.Inline.TextDecorationsProperty, newDecorations); } } } }
// Helper that returns a hyperlink ancestor of passed position. private static Hyperlink GetHyperlinkAncestor(TextPointer position) { Inline parent = position.Parent as Inline; while (parent != null && !(parent is Hyperlink)) { parent = parent.Parent as Inline; } return parent as Hyperlink; }
public static TextPointer RemoveHyperlink(TextPointer start) { var backspacePosition = start.GetNextInsertionPosition(LogicalDirection.Backward); Hyperlink hyperlink; if (backspacePosition == null || !IsHyperlinkBoundaryCrossed(start, backspacePosition, out hyperlink)) { return null; } // Remember caretPosition with forward gravity. This is necessary since we are going to delete // the hyperlink element preceeding caretPosition and after deletion current caretPosition // (with backward gravity) will follow content preceeding the hyperlink. // We want to remember content following the hyperlink to set new caret position at. var newCaretPosition = start.GetPositionAtOffset(0, LogicalDirection.Forward); // Deleting the hyperlink is done using logic below. // 1. Copy its children Inline to a temporary array. var hyperlinkChildren = hyperlink.Inlines; var inlines = new Inline[hyperlinkChildren.Count]; hyperlinkChildren.CopyTo(inlines, 0); // 2. Remove each child from parent hyperlink element and insert it after the hyperlink. for (int i = inlines.Length - 1; i >= 0; i--) { hyperlinkChildren.Remove(inlines[i]); hyperlink.SiblingInlines.InsertAfter(hyperlink, inlines[i]); } // 3. Apply hyperlink's local formatting properties to inlines (which are now outside hyperlink scope). var localProperties = hyperlink.GetLocalValueEnumerator(); var inlineRange = new TextRange(inlines[0].ContentStart, inlines[inlines.Length - 1].ContentEnd); while (localProperties.MoveNext()) { var property = localProperties.Current; var dp = property.Property; object value = property.Value; if (!dp.ReadOnly && dp != Inline.TextDecorationsProperty && // Ignore hyperlink defaults. dp != TextElement.ForegroundProperty && dp != BaseUriHelper.BaseUriProperty && !IsHyperlinkProperty(dp)) { inlineRange.ApplyPropertyValue(dp, value); } } // 4. Delete the (empty) hyperlink element. hyperlink.SiblingInlines.Remove(hyperlink); return newCaretPosition; }
// ------------------------------------------------------------------- // // Internal Methods // // ------------------------------------------------------------------- #region Internal Methods internal static TextElement InsertElementClone(TextPointer start, TextPointer end, TextElement element) { TextElement newElement = (TextElement)Activator.CreateInstance(element.GetType()); // Copy properties to the newElement newElement.TextContainer.SetValues(newElement.ContentStart, element.GetLocalValueEnumerator()); newElement.Reposition(start, end); return newElement; }
// По указателю в тексте получает индекс символа в тексте, связанного с этим указателем. // Причем текст считается относительно начала параграфа, в котором находится этот указатель public static int GetTextIndexInParagraphFromPointer(TextPointer pointer) { if (pointer != null) { // Такой вот извращенный способ узнать индекс символа в строке TextRange textRange = new TextRange(pointer.Paragraph.ContentStart, pointer); return textRange.Text.Length; } return -1; }
//------------------------------------------------------ // // Public Methods // //------------------------------------------------------ #region Public Methods // Called by the undo manager. Restores tree state to its condition // when the unit was created. Assumes the tree state matches conditions // just after the unit was created. public override void DoCore() { TextPointer start; TextPointer end; VerifyTreeContentHashCode(); start = new TextPointer(this.TextContainer, this.SymbolOffset, LogicalDirection.Forward); end = new TextPointer(this.TextContainer, this.SymbolOffset + _symbolCount, LogicalDirection.Forward); this.TextContainer.DeleteContentInternal(start, end); }
public static int GetTextOffset(this swd.TextPointer position) { var offset = 0; while (position != null) { if (position.GetPointerContext(swd.LogicalDirection.Backward) == swd.TextPointerContext.Text) { offset += position.GetTextRunLength(swd.LogicalDirection.Backward); } var nextContextPosition = position.GetNextContextPosition(swd.LogicalDirection.Backward); if (nextContextPosition == null) { return(offset); } position = nextContextPosition; } return(offset); }
// Callback for FrameworkElement.ContextMenuOpeningEvent. // If the control is using the default ContextMenu, we initialize it // here. internal static void OnContextMenuOpening(object sender, ContextMenuEventArgs e) { TextEditor This = TextEditor._GetTextEditor(sender); const double KeyboardInvokedSentinel = -1.0; // e.CursorLeft has this value when the menu is invoked with the keyboard. if (This == null || This.TextView == null) { return; } // Get the mouse position that base on RenderScope which we will set // the caret on the RenderScope. Point renderScopeMouseDownPoint = Mouse.GetPosition(This.TextView.RenderScope); ContextMenu contextMenu = null; bool startPositionCustomElementMenu = false; if (This.IsReadOnly) { // If the TextEditor is ReadOnly, only take action if // 1. The selection is non-empty AND // 2. The user clicked inside the selection. if ((e.CursorLeft != KeyboardInvokedSentinel && !This.Selection.Contains(renderScopeMouseDownPoint)) || (e.CursorLeft == KeyboardInvokedSentinel && This.Selection.IsEmpty)) { return; } } else if ((This.Selection.IsEmpty || e.TargetElement is TextElement) && e.TargetElement != null) { // Targeted element has its own ContextMenu, don't override it. contextMenu = (ContextMenu)e.TargetElement.GetValue(FrameworkElement.ContextMenuProperty); } else if (e.CursorLeft == KeyboardInvokedSentinel) { // If the menu was invoked from the keyboard, walk up the tree // from the selection.Start looking for a custom menu. TextPointer start = GetContentPosition(This.Selection.Start) as TextPointer; if (start != null) { TextElement element = start.Parent as TextElement; while (element != null) { contextMenu = (ContextMenu)element.GetValue(FrameworkElement.ContextMenuProperty); if (contextMenu != null) { startPositionCustomElementMenu = true; break; } element = element.Parent as TextElement; } } } // Update the selection caret. // // A negative offset for e.CursorLeft means the user invoked // the menu with a hotkey (shift-F10). Don't mess with the caret // unless the user right-clicked. if (e.CursorLeft != KeyboardInvokedSentinel) { if (!TextEditorMouse.IsPointWithinInteractiveArea(This, Mouse.GetPosition(This.UiScope))) { // Don't bring up a context menu if the user clicked on non-editable space. return; } // Don't update the selection caret if we're bringing up a custom UIElement // ContextMenu. if (contextMenu == null || !(e.TargetElement is UIElement)) { using (This.Selection.DeclareChangeBlock()) // NB: This raises a PUBLIC EVENT. { // If we're not over the selection, move the caret. if (!This.Selection.Contains(renderScopeMouseDownPoint)) { TextEditorMouse.SetCaretPositionOnMouseEvent(This, renderScopeMouseDownPoint, MouseButton.Right, 1 /* clickCount */); } } } } if (contextMenu == null) { // If someone explicitly set it null -- don't mess with it. if (This.UiScope.ReadLocalValue(FrameworkElement.ContextMenuProperty) == null) { return; } // Grab whatever's set to the UiScope's ContextMenu property. contextMenu = This.UiScope.ContextMenu; } // If we are here, it means that either a custom context menu or our default context menu will be opened. // Setting this flag ensures that we dont loose selection highlight while the context menu is open. This.IsContextMenuOpen = true; // If it's not null, someone's overriding our default -- don't mess with it. if (contextMenu != null && !startPositionCustomElementMenu) { // If the user previously raised the ContextMenu with the keyboard, // we've left h/v offsets non-zero, and they need to be cleared now // for mouse placement to work. contextMenu.HorizontalOffset = 0; contextMenu.VerticalOffset = 0; // Since ContextMenuService doesn't open the menu, it won't fire a ContextMenuClosing event. // We need to listen to the Closed event of the ContextMenu itself so we can clear the // IsContextMenuOpen flag. We also do this for the default menu later in this method. contextMenu.Closed += new RoutedEventHandler(OnContextMenuClosed); return; } // Complete the composition before creating the editor context menu. This.CompleteComposition(); if (contextMenu == null) { // It's a default null, so spin up a temporary ContextMenu now. contextMenu = new EditorContextMenu(); ((EditorContextMenu)contextMenu).AddMenuItems(This); } contextMenu.Placement = PlacementMode.RelativePoint; contextMenu.PlacementTarget = This.UiScope; ITextPointer position = null; LogicalDirection direction; // Position the ContextMenu. SpellingError spellingError = (contextMenu is EditorContextMenu) ? This.GetSpellingErrorAtSelection() : null; if (spellingError != null) { // If we have a matching speller error at the selection // start, position relative to the end of the error. position = spellingError.End; direction = LogicalDirection.Backward; } else if (e.CursorLeft == KeyboardInvokedSentinel) { // A negative offset for e.CursorLeft means the user invoked // the menu with a hotkey (shift-F10). Place the menu // relative to Selection.Start. position = This.Selection.Start; direction = LogicalDirection.Forward; } else { direction = LogicalDirection.Forward; } // Calculate coordinats for the ContextMenu. // They must be set relative to UIScope - as EditorContextMenu constructor assumes. if (position != null && position.CreatePointer(direction).HasValidLayout) { double horizontalOffset; double verticalOffset; GetClippedPositionOffsets(This, position, direction, out horizontalOffset, out verticalOffset); contextMenu.HorizontalOffset = horizontalOffset; contextMenu.VerticalOffset = verticalOffset; } else { Point uiScopeMouseDownPoint = Mouse.GetPosition(This.UiScope); contextMenu.HorizontalOffset = uiScopeMouseDownPoint.X; contextMenu.VerticalOffset = uiScopeMouseDownPoint.Y; } // Since ContextMenuService doesn't open the menu, it won't fire a ContextMenuClosing event. // We need to listen to the Closed event of the ContextMenu itself so we can clear the // IsContextMenuOpen flag. contextMenu.Closed += new RoutedEventHandler(OnContextMenuClosed); // This line raises a public event. contextMenu.IsOpen = true; e.Handled = true; }
// Inserts the content held by this container at a specified position. // Navigator is positioned just past the new content on return. // Navigator is expected to have forward gravity. internal abstract void Do(TextPointer navigator);
/// <summary> /// Creates a new Span instance. /// </summary> /// <param name="childInline"> /// Optional child Inline for the new Span. May be null. /// </param> /// <param name="insertionPosition"> /// Optional position at which to insert the new Span. May be null. /// </param> public Hyperlink(Inline childInline, TextPointer insertionPosition) : base(childInline, insertionPosition) { }
public bool Contains(TextPointer textPointer) { return(default(bool)); }
internal static bool IsValidChild(TextPointer position, Type childType) { return(ValidateChild(position, childType, false /* throwIfIllegalChild */, false /* throwIfIllegalHyperlinkDescendent */)); }
public TextRange(TextPointer position1, TextPointer position2) { }
public System.Windows.Documents.TextPointer GetNextSpellingErrorPosition(System.Windows.Documents.TextPointer position, System.Windows.Documents.LogicalDirection direction) { return(default(System.Windows.Documents.TextPointer)); }
// Token: 0x06003AA5 RID: 15013 RVA: 0x00109F45 File Offset: 0x00108145 internal TextRange(TextPointer position1, TextPointer position2, bool useRestrictiveXamlXmlReader) : this(position1, position2) { this._useRestrictiveXamlXmlReader = useRestrictiveXamlXmlReader; }
/// <summary>Updates the current selection, taking two <see cref="T:System.Windows.Documents.TextPointer" /> positions to indicate the updated selection.</summary> /// <param name="position1">A fixed anchor position that marks one end of the updated selection.</param> /// <param name="position2">A movable position that marks the other end of the updated selection.</param> /// <exception cref="T:System.ArgumentException">Occurs when <paramref name="position1" /> and <paramref name="position2" /> are not positioned within the same document.</exception> /// <exception cref="T:System.ArgumentNullException">Occurs when <paramref name="position1" /> or <paramref name="position2" /> is <see langword="null" />.</exception> // Token: 0x06003AD2 RID: 15058 RVA: 0x0010A137 File Offset: 0x00108337 public void Select(TextPointer position1, TextPointer position2) { ((ITextRange)this).Select(position1, position2); }
// Token: 0x06003AD3 RID: 15059 RVA: 0x0010A141 File Offset: 0x00108341 internal void SelectWord(TextPointer textPointer) { ((ITextRange)this).SelectWord(textPointer); }
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.Documents.Floater" /> class with the specified <see cref="T:System.Windows.Documents.Block" /> object as its initial content, and a <see cref="T:System.Windows.Documents.TextPointer" /> that specifies an insertion position for the new <see cref="T:System.Windows.Documents.Floater" />.</summary> /// <param name="childBlock">The initial content of the new <see cref="T:System.Windows.Documents.Floater" />. This parameter can be <see langword="null" />, in which case no <see cref="T:System.Windows.Documents.Block" /> is inserted.</param> /// <param name="insertionPosition">The position at which to insert the <see cref="T:System.Windows.Documents.Floater" /> element after it is created.</param> // Token: 0x06002F05 RID: 12037 RVA: 0x000C94AF File Offset: 0x000C76AF public Floater(Block childBlock, TextPointer insertionPosition) : base(childBlock, insertionPosition) { }
//------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods /// <summary> /// Changed handler for the Text property. /// </summary> /// <param name="d">The source of the event.</param> /// <param name="e">A PropertyChangedEventArgs that contains the event data.</param> /// <remarks> /// We can't assume the value is a string here -- it may be a DeferredRunTextReference. /// </remarks> private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Run run = (Run)d; // Return if this update was caused by a TextContainer change or a reentrant change. if (run._changeEventNestingCount > 0) { return; } Invariant.Assert(!e.NewEntry.IsDeferredReference); // CoerceText will have already converted null -> String.Empty, but our default // CoerceValueCallback could be overridden by a derived class. So check again here. string newText = (string)e.NewValue; if (newText == null) { newText = String.Empty; } // Run.TextProperty has changed. Update the backing store. run._changeEventNestingCount++; try { TextContainer textContainer = run.TextContainer; textContainer.BeginChange(); try { TextPointer contentStart = run.ContentStart; if (!run.IsEmpty) { textContainer.DeleteContentInternal(contentStart, run.ContentEnd); } contentStart.InsertTextInRun(newText); } finally { textContainer.EndChange(); } } finally { run._changeEventNestingCount--; } // We need to clear undo stack if we are in a RichTextBox and the value comes from // data binding or some other expression. FlowDocument document = run.TextContainer.Parent as FlowDocument; if (document != null) { RichTextBox rtb = document.Parent as RichTextBox; if (rtb != null && run.HasExpression(run.LookupEntry(Run.TextProperty.GlobalIndex), Run.TextProperty)) { UndoManager undoManager = rtb.TextEditor._GetUndoManager(); if (undoManager != null && undoManager.IsEnabled) { undoManager.Clear(); } } } }
/// <summary>Checks whether a position (specified by a <see cref="T:System.Windows.Documents.TextPointer" />) is located within the current selection.</summary> /// <param name="textPointer">A position to test for inclusion in the current selection.</param> /// <returns> /// <see langword="true" /> if the specified position is located within the current selection; otherwise, <see langword="false" />.</returns> /// <exception cref="T:System.ArgumentException">Occurs when textPointer is not in the same document as the current selection.</exception> // Token: 0x06003AD1 RID: 15057 RVA: 0x0010A12E File Offset: 0x0010832E public bool Contains(TextPointer textPointer) { return(((ITextRange)this).Contains(textPointer)); }
public System.Windows.Documents.TextRange GetSpellingErrorRange(System.Windows.Documents.TextPointer position) { Contract.Requires(position != null); return(default(System.Windows.Documents.TextRange)); }
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.Documents.TextRange" /> class, taking two specified <see cref="T:System.Windows.Documents.TextPointer" /> positions as the beginning and end positions for the new range.</summary> /// <param name="position1">A fixed anchor position that marks one end of the selection used to form the new <see cref="T:System.Windows.Documents.TextRange" />.</param> /// <param name="position2">A movable position that marks the other end of the selection used to form the new <see cref="T:System.Windows.Documents.TextRange" />.</param> /// <exception cref="T:System.ArgumentException">Occurs when <paramref name="position1" /> and <paramref name="position2" /> are not positioned within the same document.</exception> /// <exception cref="T:System.ArgumentNullException">Occurs when <paramref name="position1" /> or <paramref name="position2" /> is <see langword="null" />.</exception> // Token: 0x06003AA2 RID: 15010 RVA: 0x00109ECC File Offset: 0x001080CC public TextRange(TextPointer position1, TextPointer position2) : this(position1, position2) { }
public int GetOffsetToPosition(TextPointer position) { Contract.Requires(position != null); return(default(int)); }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors // Creates a new instance. // start/end span the content to copy into the new undo unit -- they // should always share the same scoping TextElement. internal TextTreeDeleteContentUndoUnit(TextContainer tree, TextPointer start, TextPointer end) : base(tree, start.GetSymbolOffset()) { TextTreeNode node; TextTreeNode haltNode; start.DebugAssertGeneration(); end.DebugAssertGeneration(); Invariant.Assert(start.GetScopingNode() == end.GetScopingNode(), "start/end have different scope!"); node = start.GetAdjacentNode(LogicalDirection.Forward); haltNode = end.GetAdjacentNode(LogicalDirection.Forward); // Walk the content, copying runs as we go. _content = CopyContent(node, haltNode); }
public bool IsInSameDocument(TextPointer textPosition) { return(default(bool)); }
// Inserts the content held by this container at a specified position. // Navigator is positioned just past the new content on return. // Navigator is expected to have forward gravity. internal override void Do(TextPointer navigator) { navigator.TextContainer.InsertTextInternal(navigator, _text); }
// Adds a DeleteContentUndoUnit to the open parent undo unit, if any. // Called by TextContainer.DeleteContent. internal static TextTreeDeleteContentUndoUnit CreateDeleteContentUndoUnit(TextContainer tree, TextPointer start, TextPointer end) { UndoManager undoManager; TextTreeDeleteContentUndoUnit undoUnit; if (start.CompareTo(end) == 0) { return(null); } undoManager = GetOrClearUndoManager(tree); if (undoManager == null) { return(null); } undoUnit = new TextTreeDeleteContentUndoUnit(tree, start, end); undoManager.Add(undoUnit); return(undoUnit); }
public void Select(TextPointer position1, TextPointer position2) { }