/// <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); } }
// Token: 0x06003AFD RID: 15101 RVA: 0x0010A660 File Offset: 0x00108860 internal virtual void InsertEmbeddedUIElementVirtual(FrameworkElement embeddedElement) { Invariant.Assert(this.HasConcreteTextContainer, "Can't insert embedded object to non-TextContainer range!"); Invariant.Assert(embeddedElement != null); TextRangeBase.BeginChange(this); try { this.Text = string.Empty; TextPointer textPointer = TextRangeEditTables.EnsureInsertionPosition(this.Start); Paragraph paragraph = textPointer.Paragraph; if (paragraph != null) { if (Paragraph.HasNoTextContent(paragraph)) { BlockUIContainer blockUIContainer = new BlockUIContainer(embeddedElement); blockUIContainer.TextAlignment = TextRangeEdit.GetTextAlignmentFromHorizontalAlignment(embeddedElement.HorizontalAlignment); paragraph.SiblingBlocks.InsertAfter(paragraph, blockUIContainer); paragraph.SiblingBlocks.Remove(paragraph); this.Select(blockUIContainer.ContentStart, blockUIContainer.ContentEnd); } else { InlineUIContainer inlineUIContainer = new InlineUIContainer(embeddedElement); TextPointer textPointer2 = TextRangeEdit.SplitFormattingElements(this.Start, false); textPointer2.InsertTextElement(inlineUIContainer); this.Select(inlineUIContainer.ElementStart, inlineUIContainer.ElementEnd); } } } finally { TextRangeBase.EndChange(this); } }
// Token: 0x06003888 RID: 14472 RVA: 0x000FDA94 File Offset: 0x000FBC94 private static void UpdateCursor(TextEditor This, Point mouseMovePoint) { Invariant.Assert(This.TextView != null && This.TextView.IsValid); Cursor cursor = Cursors.IBeam; if (TextEditor.IsTableEditingEnabled && TextRangeEditTables.TableBorderHitTest(This.TextView, mouseMovePoint)) { cursor = Cursors.SizeWE; } else if (This.Selection != null && !This.UiScope.IsMouseCaptured) { if (This.Selection.IsEmpty) { UIElement uielementWhenMouseOver = TextEditorMouse.GetUIElementWhenMouseOver(This, mouseMovePoint); if (uielementWhenMouseOver != null && uielementWhenMouseOver.IsEnabled) { cursor = Cursors.Arrow; } } else if (This.UiScope.IsFocused && This.Selection.Contains(mouseMovePoint)) { cursor = Cursors.Arrow; } } if (cursor != This._cursor) { This._cursor = cursor; Mouse.UpdateCursor(); } }
// Assumes that a range contains a sequence of same-level ListItems. // Converts all these ListItems into Paragraphs and // either adds them to preceding ListItem (as non-bulleted continuation) // or pulls them out of a List if they start in the beginning of a List internal static void ConvertListItemsToParagraphs(TextRange range) { ListItem firstListItem = TextPointerBase.GetListItem(range.Start); ListItem lastListItem = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); // The range must be in a sequence of ListItems belonging to one List wrapper if (firstListItem == null || lastListItem == null || firstListItem.Parent != lastListItem.Parent || !(firstListItem.Parent is List)) { return; } List listToRemove = null; ListItem leadingListItem = firstListItem.PreviousListItem; if (leadingListItem != null) { // We have a leading ListItem, so pull selected items into it leadingListItem.Reposition(leadingListItem.ContentStart, lastListItem.ElementEnd); } else { // We do not have a leading ListItem. So pull selected items out of a list // Cut wrapping list after endListItem if (lastListItem.NextListItem != null) { TextRangeEdit.SplitElement(lastListItem.ElementEnd); } // Set list to remove listToRemove = firstListItem.List; } // Remove ListItems from all selected blocks ListItem listItem = firstListItem; while (listItem != null) { ListItem nextListItem = listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem; // If this is an empty <ListItem></ListItem>, insert an explicit paragraph in it before deleting the list item. if (listItem.ContentStart.CompareTo(listItem.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem.ContentStart); } listItem.Reposition(null, null); listItem = listItem == lastListItem ? null : nextListItem; } // If we have a list to remove, remove it and set its FlowDirection to its children if (listToRemove != null) { FlowDirection flowDirection = (FlowDirection)listToRemove.GetValue(Paragraph.FlowDirectionProperty); listToRemove.Reposition(null, null); TextRangeEdit.SetParagraphProperty(range.Start, range.End, Paragraph.FlowDirectionProperty, flowDirection); } }
// Token: 0x06003879 RID: 14457 RVA: 0x000FD0D4 File Offset: 0x000FB2D4 private static void CreateImplicitParagraphIfNeededAndUpdateSelection(TextSelection thisSelection) { TextPointer textPointer = thisSelection.Start; if (TextPointerBase.IsAtPotentialParagraphPosition(textPointer)) { textPointer = TextRangeEditTables.EnsureInsertionPosition(textPointer); thisSelection.Select(textPointer, textPointer); } }
private static void CreateImplicitParagraphIfNeededAndUpdateSelection(TextSelection thisSelection) { // Create implicit paragraph if we are at a potential paragraph position, such as empty FlowDocument, TableCell. TextPointer position = thisSelection.Start; if (TextPointerBase.IsAtPotentialParagraphPosition(position)) { position = TextRangeEditTables.EnsureInsertionPosition(position); thisSelection.Select(position, position); } }
// Token: 0x06003B04 RID: 15108 RVA: 0x0010A9FC File Offset: 0x00108BFC internal virtual bool DeleteColumnsVirtual() { TextRangeBase.BeginChange(this); bool result; try { result = TextRangeEditTables.DeleteColumns(this); } finally { TextRangeBase.EndChange(this); } return(result); }
// Token: 0x06003B03 RID: 15107 RVA: 0x0010A9C4 File Offset: 0x00108BC4 internal virtual TextRange InsertColumnsVirtual(int columnCount) { TextRangeBase.BeginChange(this); TextRange result; try { result = TextRangeEditTables.InsertColumns(this, columnCount); } finally { TextRangeBase.EndChange(this); } return(result); }
// Token: 0x06003B00 RID: 15104 RVA: 0x0010A91C File Offset: 0x00108B1C internal virtual Table InsertTableVirtual(int rowCount, int columnCount) { TextRangeBase.BeginChange(this); Table result; try { result = TextRangeEditTables.InsertTable(this.End, rowCount, columnCount); } finally { TextRangeBase.EndChange(this); } return(result); }
// Token: 0x06003B06 RID: 15110 RVA: 0x0010AA64 File Offset: 0x00108C64 internal virtual TextRange SplitCellVirtual(int splitCountHorizontal, int splitCountVertical) { TextRangeBase.BeginChange(this); TextRange result; try { result = TextRangeEditTables.SplitCell(this, splitCountHorizontal, splitCountVertical); } finally { TextRangeBase.EndChange(this); } return(result); }
// Token: 0x06003B05 RID: 15109 RVA: 0x0010AA30 File Offset: 0x00108C30 internal virtual TextRange MergeCellsVirtual() { TextRangeBase.BeginChange(this); TextRange result; try { result = TextRangeEditTables.MergeCells(this); } finally { TextRangeBase.EndChange(this); } return(result); }
// Token: 0x06003865 RID: 14437 RVA: 0x000FC618 File Offset: 0x000FA818 private static bool PastePlainText(TextEditor This, string pastedText) { pastedText = This._FilterText(pastedText, This.Selection); if (pastedText.Length > 0) { if (This.AcceptsRichContent && This.Selection.Start is TextPointer) { This.Selection.Text = string.Empty; TextPointer textPointer = TextRangeEditTables.EnsureInsertionPosition((TextPointer)This.Selection.Start); textPointer = textPointer.GetPositionAtOffset(0, LogicalDirection.Backward); TextPointer textPointer2 = textPointer.GetPositionAtOffset(0, LogicalDirection.Forward); int num = 0; for (int i = 0; i < pastedText.Length; i++) { if (pastedText[i] == '\r' || pastedText[i] == '\n') { textPointer2.InsertTextInRun(pastedText.Substring(num, i - num)); if (!This.AcceptsReturn) { return(true); } if (textPointer2.HasNonMergeableInlineAncestor) { textPointer2.InsertTextInRun(" "); } else { textPointer2 = textPointer2.InsertParagraphBreak(); } if (pastedText[i] == '\r' && i + 1 < pastedText.Length && pastedText[i + 1] == '\n') { i++; } num = i + 1; } } textPointer2.InsertTextInRun(pastedText.Substring(num, pastedText.Length - num)); This.Selection.Select(textPointer, textPointer2); } else { This.Selection.Text = pastedText; } return(true); } return(false); }
// Token: 0x06003B82 RID: 15234 RVA: 0x0010EF28 File Offset: 0x0010D128 internal static bool ConvertParagraphsToListItems(TextRange range, TextMarkerStyle markerStyle) { if (range.IsEmpty && TextPointerBase.IsAtPotentialParagraphPosition(range.Start)) { TextPointer textPointer = TextRangeEditTables.EnsureInsertionPosition(range.Start); ((ITextRange)range).Select(textPointer, textPointer); } Block paragraphOrBlockUIContainer = range.Start.ParagraphOrBlockUIContainer; TextPointer textPointer2 = (TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End); Block paragraphOrBlockUIContainer2 = textPointer2.ParagraphOrBlockUIContainer; if (paragraphOrBlockUIContainer == null || paragraphOrBlockUIContainer2 == null || paragraphOrBlockUIContainer.Parent != paragraphOrBlockUIContainer2.Parent || (paragraphOrBlockUIContainer.Parent is ListItem && paragraphOrBlockUIContainer.PreviousBlock == null)) { return(false); } Block block = paragraphOrBlockUIContainer; while (block != paragraphOrBlockUIContainer2 && block != null) { if (block is Table || block is Section) { return(false); } block = block.NextBlock; } ListItem listItem = paragraphOrBlockUIContainer.Parent as ListItem; if (listItem != null) { Block block3; for (Block block2 = paragraphOrBlockUIContainer; block2 != null; block2 = block3) { block3 = ((block2 == paragraphOrBlockUIContainer2) ? null : (block2.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as Block)); Invariant.Assert(block2.Parent is ListItem); TextRangeEdit.SplitElement(block2.ElementStart); } } else { new List { MarkerStyle = markerStyle }.Apply(paragraphOrBlockUIContainer, paragraphOrBlockUIContainer2); } return(true); }
// Token: 0x06003B89 RID: 15241 RVA: 0x0010F754 File Offset: 0x0010D954 private static TextPointer GetPositionAfterList(List list) { Invariant.Assert(list != null, "list cannot be null"); TextPointer textPointer = list.ElementEnd.GetInsertionPosition(LogicalDirection.Backward); if (textPointer != null) { textPointer = textPointer.GetNextInsertionPosition(LogicalDirection.Forward); } if (textPointer == null) { textPointer = list.ElementEnd.TextContainer.End; } if (TextRangeEditTables.IsTableStructureCrossed(list.ElementEnd, textPointer)) { textPointer = list.ContentEnd; } return(textPointer); }
// Token: 0x06003B83 RID: 15235 RVA: 0x0010F058 File Offset: 0x0010D258 internal static void ConvertListItemsToParagraphs(TextRange range) { ListItem listItem = TextPointerBase.GetListItem(range.Start); ListItem listItem2 = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); if (listItem == null || listItem2 == null || listItem.Parent != listItem2.Parent || !(listItem.Parent is List)) { return; } List list = null; ListItem previousListItem = listItem.PreviousListItem; if (previousListItem != null) { previousListItem.Reposition(previousListItem.ContentStart, listItem2.ElementEnd); } else { if (listItem2.NextListItem != null) { TextRangeEdit.SplitElement(listItem2.ElementEnd); } list = listItem.List; } ListItem listItem4; for (ListItem listItem3 = listItem; listItem3 != null; listItem3 = ((listItem3 == listItem2) ? null : listItem4)) { listItem4 = (listItem3.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem); if (listItem3.ContentStart.CompareTo(listItem3.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem3.ContentStart); } listItem3.Reposition(null, null); } if (list != null) { FlowDirection flowDirection = (FlowDirection)list.GetValue(Block.FlowDirectionProperty); list.Reposition(null, null); TextRangeEdit.SetParagraphProperty(range.Start, range.End, Block.FlowDirectionProperty, flowDirection); } }
// Check the cursor position against the text selection and see if we need to // change which cursor is displayed. If the cursor is over the selection, show // the normal cursor. Otherwise, show the EditCursors. private static void UpdateCursor(TextEditor This, Point mouseMovePoint) { Invariant.Assert(This.TextView != null && This.TextView.IsValid); // Default cursor is editing IBeam Cursor cursor = Cursors.IBeam; // Check special conditions to setup special cursor shape if (TextEditor.IsTableEditingEnabled && TextRangeEditTables.TableBorderHitTest(This.TextView, mouseMovePoint)) { // Mmouse is over a tablecell border. Cursor must indicate potential column resize cursor = Cursors.SizeWE; } else { // Check if this position belongs to selected area or is over an embedded UIElement if (This.Selection != null && !This.UiScope.IsMouseCaptured) { if (This.Selection.IsEmpty) { UIElement uiElement = GetUIElementWhenMouseOver(This, mouseMovePoint); if (uiElement != null && uiElement.IsEnabled) { // Mouse is over an embedded UIElement which is enabled (UiScope may or may not have focus) cursor = Cursors.Arrow; } } else if (This.UiScope.IsFocused && This.Selection.Contains(mouseMovePoint)) { // The mouse is over a non-empty selection and we're not dragging cursor = Cursors.Arrow; } } } if (cursor != This._cursor) { This._cursor = cursor; Mouse.UpdateCursor(); } }
// Token: 0x06002B4B RID: 11083 RVA: 0x000C592C File Offset: 0x000C3B2C public override void Do() { UndoManager undoManager = base.TopContainer as UndoManager; IParentUndoUnit parentUndoUnit = null; TextPointer textPointer = new TextPointer(this._textContainer.Start, this._cpTable, LogicalDirection.Forward); Table table = (Table)textPointer.Parent; this._columnWidths[this._columnIndex] -= this._resizeAmount; if (this._columnIndex < table.ColumnCount - 1) { this._columnWidths[this._columnIndex + 1] += this._resizeAmount; } if (undoManager != null && undoManager.IsEnabled) { parentUndoUnit = new ColumnResizeUndoUnit(textPointer, this._columnIndex, this._columnWidths, -this._resizeAmount); undoManager.Open(parentUndoUnit); } TextRangeEditTables.EnsureTableColumnsAreFixedSize(table, this._columnWidths); if (parentUndoUnit != null) { undoManager.Close(parentUndoUnit, UndoCloseAction.Commit); } }
// Helper for plain text filtering when pasted into rich or plain destination private static bool PastePlainText(TextEditor This, string pastedText) { pastedText = This._FilterText(pastedText, This.Selection); if (pastedText.Length > 0) { if (This.AcceptsRichContent && This.Selection.Start is TextPointer) { // Clear selection content This.Selection.Text = String.Empty; // Ensure that text is insertable at current selection TextPointer start = TextRangeEditTables.EnsureInsertionPosition((TextPointer)This.Selection.Start); // Store boundaries of inserted text start = start.GetPositionAtOffset(0, LogicalDirection.Backward); TextPointer end = start.GetPositionAtOffset(0, LogicalDirection.Forward); // For rich text we need to remove control characters and // replace linebreaks by paragraphs int currentLineStart = 0; for (int i = 0; i < pastedText.Length; i++) { if (pastedText[i] == '\r' || pastedText[i] == '\n') { end.InsertTextInRun(pastedText.Substring(currentLineStart, i - currentLineStart)); if (!This.AcceptsReturn) { return(true); // All lined except for the first one are ignored when TextBox does not accept Return key } if (end.HasNonMergeableInlineAncestor) { // We cannot split a Hyperlink or other non-mergeable Inline element, // so insert a space character instead (similar to embedded object). // Note that this means, Paste operation would loose // paragraph break information in this case. end.InsertTextInRun(" "); } else { end = end.InsertParagraphBreak(); } if (pastedText[i] == '\r' && i + 1 < pastedText.Length && pastedText[i + 1] == '\n') { i++; } currentLineStart = i + 1; } } end.InsertTextInRun(pastedText.Substring(currentLineStart, pastedText.Length - currentLineStart)); // Select all pasted content This.Selection.Select(start, end); } else { // For plain text we insert the content as is (including control characters) This.Selection.Text = pastedText; } return(true); } return(false); }
// Token: 0x0600387F RID: 14463 RVA: 0x000FD304 File Offset: 0x000FB504 internal static void OnMouseDown(object sender, MouseButtonEventArgs e) { TextEditor textEditor = TextEditor._GetTextEditor(sender); if (textEditor == null) { return; } textEditor.CloseToolTip(); if (!textEditor._IsEnabled) { return; } if (!textEditor.UiScope.Focusable) { return; } if (e.ButtonState == MouseButtonState.Released) { return; } e.Handled = true; TextEditorMouse.MoveFocusToUiScope(textEditor); if (textEditor.UiScope != Keyboard.FocusedElement) { return; } if (e.ChangedButton != MouseButton.Left) { return; } if (textEditor.TextView == null) { return; } textEditor.CompleteComposition(); if (!textEditor.TextView.IsValid) { textEditor.TextView.RenderScope.UpdateLayout(); if (textEditor.TextView == null || !textEditor.TextView.IsValid) { return; } } if (!TextEditorMouse.IsPointWithinInteractiveArea(textEditor, e.GetPosition(textEditor.UiScope))) { return; } textEditor.TextView.ThrottleBackgroundTasksForUserInput(); Point position = e.GetPosition(textEditor.TextView.RenderScope); if (TextEditor.IsTableEditingEnabled && TextRangeEditTables.TableBorderHitTest(textEditor.TextView, position)) { textEditor._tableColResizeInfo = TextRangeEditTables.StartColumnResize(textEditor.TextView, position); Invariant.Assert(textEditor._tableColResizeInfo != null); textEditor._mouseCapturingInProgress = true; try { textEditor.UiScope.CaptureMouse(); return; } finally { textEditor._mouseCapturingInProgress = false; } } textEditor.Selection.BeginChange(); try { TextEditorMouse.SetCaretPositionOnMouseEvent(textEditor, position, e.ChangedButton, e.ClickCount); textEditor._mouseCapturingInProgress = true; textEditor.UiScope.CaptureMouse(); } finally { textEditor._mouseCapturingInProgress = false; textEditor.Selection.EndChange(); } }
// Token: 0x06003B85 RID: 15237 RVA: 0x0010F26C File Offset: 0x0010D46C internal static bool UnindentListItems(TextRange range) { if (!TextRangeEditLists.IsRangeWithinSingleList(range)) { return(false); } ListItem listItem = TextPointerBase.GetListItem(range.Start); ListItem listItem2 = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); for (TextElement textElement = (TextElement)listItem2.Parent; textElement != listItem.Parent; textElement = (TextElement)textElement.Parent) { listItem2 = (textElement as ListItem); } if (listItem2 == null) { return(false); } if (listItem.PreviousListItem != null) { TextRangeEdit.SplitElement(listItem.ElementStart); } if (listItem2.NextListItem != null) { TextRangeEdit.SplitElement(listItem2.ElementEnd); } List list = (List)listItem.Parent; ListItem listItem3 = list.Parent as ListItem; if (listItem3 != null) { list.Reposition(null, null); TextPointer contentEnd = listItem3.ContentEnd; if (listItem3.ContentStart.CompareTo(listItem.ElementStart) == 0) { listItem3.Reposition(null, null); } else { listItem3.Reposition(listItem3.ContentStart, listItem.ElementStart); } if (contentEnd.CompareTo(listItem2.ElementEnd) != 0) { TextPointer contentEnd2 = listItem2.ContentEnd; listItem2.Reposition(listItem2.ContentStart, contentEnd); TextRangeEditLists.MergeLists(contentEnd2); } } else { TextPointer elementStart = list.ElementStart; TextPointer elementEnd = list.ElementEnd; object value = list.GetValue(Block.FlowDirectionProperty); list.Reposition(null, null); ListItem listItem5; for (ListItem listItem4 = listItem; listItem4 != null; listItem4 = ((listItem4 == listItem2) ? null : listItem5)) { listItem5 = (listItem4.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem); if (listItem4.ContentStart.CompareTo(listItem4.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem4.ContentStart); } listItem4.Reposition(null, null); } TextRangeEdit.SetParagraphProperty(elementStart, elementEnd, Block.FlowDirectionProperty, value); TextRangeEditLists.MergeLists(elementStart); TextRangeEditLists.MergeLists(elementEnd); } return(true); }
/// <summary> /// Creates a new Span instance covering existing content. /// </summary> /// <param name="start"> /// Start position of the new Span. /// </param> /// <param name="end"> /// End position of the new Span. /// </param> /// <remarks> /// start and end must both be parented by the same Paragraph, otherwise /// the method will raise an ArgumentException. /// </remarks> public Span(TextPointer start, TextPointer end) { if (start == null) { throw new ArgumentNullException("start"); } if (end == null) { throw new ArgumentNullException("start"); } if (start.TextContainer != end.TextContainer) { throw new ArgumentException(SR.Get(SRID.InDifferentTextContainers, "start", "end")); } if (start.CompareTo(end) > 0) { throw new ArgumentException(SR.Get(SRID.BadTextPositionOrder, "start", "end")); } start.TextContainer.BeginChange(); try { start = TextRangeEditTables.EnsureInsertionPosition(start); Invariant.Assert(start.Parent is Run); end = TextRangeEditTables.EnsureInsertionPosition(end); Invariant.Assert(end.Parent is Run); if (start.Paragraph != end.Paragraph) { throw new ArgumentException(SR.Get(SRID.InDifferentParagraphs, "start", "end")); } // If start or end positions have a Hyperlink ancestor, we cannot split them. Inline nonMergeableAncestor; if ((nonMergeableAncestor = start.GetNonMergeableInlineAncestor()) != null) { throw new InvalidOperationException(SR.Get(SRID.TextSchema_CannotSplitElement, nonMergeableAncestor.GetType().Name)); } if ((nonMergeableAncestor = end.GetNonMergeableInlineAncestor()) != null) { throw new InvalidOperationException(SR.Get(SRID.TextSchema_CannotSplitElement, nonMergeableAncestor.GetType().Name)); } TextElement commonAncestor = TextElement.GetCommonAncestor((TextElement)start.Parent, (TextElement)end.Parent); while (start.Parent != commonAncestor) { start = SplitElement(start); } while (end.Parent != commonAncestor) { end = SplitElement(end); } if (start.Parent is Run) { start = SplitElement(start); } if (end.Parent is Run) { end = SplitElement(end); } Invariant.Assert(start.Parent == end.Parent); Invariant.Assert(TextSchema.IsValidChild(/*position*/ start, /*childType*/ typeof(Span))); this.Reposition(start, end); } finally { start.TextContainer.EndChange(); } }
// MouseDownEvent handler - used both for Left and Right mouse buttons internal static void OnMouseDown(object sender, MouseButtonEventArgs e) { TextEditor This = TextEditor._GetTextEditor(sender); if (This == null) { return; } // If UiScope has a ToolTip and it is open, any keyboard/mouse activity should close the tooltip. This.CloseToolTip(); // Ignore the event if the editor has been detached from its scope if (!This._IsEnabled) { return; } // Ignore the event if the attached scope is not focusable content. if (!This.UiScope.Focusable) { return; } // MITIGATION: NESTED_MESSAGE_PUMPS_INTERFERE_WITH_INPUT // This is a very specific fix for a case where someone displayed a dialog // box in response to mouse down. In general, this entire routine needs // to be written to handle that fact that any state can change whenever // you call out. See ButtonBase.OnMouseLeftButtonDown for an example. if (e.ButtonState == MouseButtonState.Released) { return; } e.Handled = true; // Start with moving the focus into this control. MoveFocusToUiScope(This); if (This.UiScope != Keyboard.FocusedElement) { return; } // If this is a right-click, we're done after setting // the focus. Caret is position is only updated when a // context menu opens. if (e.ChangedButton != MouseButton.Left) { return; } if (This.TextView == null) { return; } // Finalize any active IME compositions. // We have to do this async because it will potentially // invalidate layout. This.CompleteComposition(); if (!This.TextView.IsValid) { // This.TextView.RenderScope.UpdateLayout(); if (This.TextView == null || !This.TextView.IsValid) { return; } } if (!IsPointWithinInteractiveArea(This, e.GetPosition(This.UiScope))) { // Mouse down happened over padding area or chrome instead of RenderScope; just set focus return; } // Scale back any background layout in progress. This.TextView.ThrottleBackgroundTasksForUserInput(); // Get the mouse down position. Point mouseDownPoint = e.GetPosition(This.TextView.RenderScope); // Check if we're at a position where we need to begin a resize operation for table column if (TextEditor.IsTableEditingEnabled && TextRangeEditTables.TableBorderHitTest(This.TextView, mouseDownPoint)) { // Set up resize information, and create adorner This._tableColResizeInfo = TextRangeEditTables.StartColumnResize(This.TextView, mouseDownPoint); Invariant.Assert(This._tableColResizeInfo != null); This._mouseCapturingInProgress = true; try { This.UiScope.CaptureMouse(); } finally { This._mouseCapturingInProgress = false; } } else { This.Selection.BeginChange(); try { SetCaretPositionOnMouseEvent(This, mouseDownPoint, e.ChangedButton, e.ClickCount); This._mouseCapturingInProgress = true; This.UiScope.CaptureMouse(); } finally { This._mouseCapturingInProgress = false; This.Selection.EndChange(); } } }
internal static bool UnindentListItems(TextRange range) { // If listitems in this range cross a list boundary, we cannot unindent them. if (!IsRangeWithinSingleList(range)) { return(false); } ListItem firstListItem = TextPointerBase.GetListItem(range.Start); ListItem lastListItem = TextPointerBase.GetListItem((TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End)); // At this point it is possible that lastListItem is a child of // firstListItem. // // This is due to a special case in IsRangeWithinSingleList // which allows the input TextRange to cross List boundaries only // in the case where the TextRange ends adjacent to an insertion // position at the same level as the start, e.g.: // // - parent item // - start item (range starts here) // - child item (range ends here) // <start item must not have any siblings> // // Here we check for that special case and ensure that // lastListItem is at the same level as firstListItem. TextElement parent = (TextElement)lastListItem.Parent; while (parent != firstListItem.Parent) { lastListItem = parent as ListItem; parent = (TextElement)parent.Parent; } if (lastListItem == null) { // This can happen if the input is a fragment, a collection // of ListItems not parented by an outer List. return(false); } // Cut wrapping list before startListItem if (firstListItem.PreviousListItem != null) { TextRangeEdit.SplitElement(firstListItem.ElementStart); } // Cut wrapping list after endListItem if (lastListItem.NextListItem != null) { TextRangeEdit.SplitElement(lastListItem.ElementEnd); } // Remove List wrapper from selected items List unindentedList = (List)firstListItem.Parent; // Check whether we have outer ListItem ListItem outerListItem = unindentedList.Parent as ListItem; if (outerListItem != null) { // Selected items belong to a nested list. // So we need to pull them to the level of enclosing ListItem, i.e. cut this ListItem. // In this case we also need to include trailing list into the last of selected items // Remove a wrapping List from selected items unindentedList.Reposition(null, null); // Remember end position of outerListItem to pull any trailing list or other blocks into the last of selected listitems TextPointer outerListItemEnd = outerListItem.ContentEnd; if (outerListItem.ContentStart.CompareTo(firstListItem.ElementStart) == 0) { // There is nothing before first list item; so outer list item would be empty - just delete it outerListItem.Reposition(null, null); } else { // Wrap all stuff preceding firstListItem in outerListItem outerListItem.Reposition(outerListItem.ContentStart, firstListItem.ElementStart); } if (outerListItemEnd.CompareTo(lastListItem.ElementEnd) == 0) { // There are no following siblings to pull into last selected item; do nothing. } else { // Pull trailing items (following siblings to the selected ones) into the last selected item // Remember a position to merge any trailing list after lastListItem TextPointer mergePosition = lastListItem.ContentEnd; // Reposition last selectd ListItem so that it includes trailing list (or other block) as its children lastListItem.Reposition(lastListItem.ContentStart, outerListItemEnd); // Merge any trailing list with a sublist outdented with our listitem MergeLists(mergePosition); } } else { // Selected items are not in nested list. // We need to simply unwrap them and convert to paragraphs TextPointer start = unindentedList.ElementStart; TextPointer end = unindentedList.ElementEnd; // Save the list's FlowDirection value, to apply later to its children. object listFlowDirectionValue = unindentedList.GetValue(Paragraph.FlowDirectionProperty); // Remove a wrapping List from selected items unindentedList.Reposition(null, null); // Remove ListItems from all selected items ListItem listItem = firstListItem; while (listItem != null) { ListItem nextListItem = listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as ListItem; // If this is an empty <ListItem></ListItem>, insert an explicit paragraph in it before deleting the list item. if (listItem.ContentStart.CompareTo(listItem.ContentEnd) == 0) { TextRangeEditTables.EnsureInsertionPosition(listItem.ContentStart); } listItem.Reposition(null, null); listItem = listItem == lastListItem ? null : nextListItem; } // Apply FlowDirection of the list just deleted to all its children. TextRangeEdit.SetParagraphProperty(start, end, Paragraph.FlowDirectionProperty, listFlowDirectionValue); // Merge lists on boundaries MergeLists(start); MergeLists(end); } return(true); }
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.Documents.Span" /> class, taking two <see cref="T:System.Windows.Documents.TextPointer" /> objects that indicate the beginning and end of a selection of content that the new <see cref="T:System.Windows.Documents.Span" /> will contain.</summary> /// <param name="start">A <see cref="T:System.Windows.Documents.TextPointer" /> that indicates the beginning of a selection of content that the new <see cref="T:System.Windows.Documents.Span" /> will contain.</param> /// <param name="end">A <see cref="T:System.Windows.Documents.TextPointer" /> that indicates the end of a selection of content that the new <see cref="T:System.Windows.Documents.Span" /> will contain.</param> /// <exception cref="T:System.ArgumentNullException">Raised when <paramref name="start" /> or <paramref name="end" /> is null.</exception> /// <exception cref="T:System.ArgumentException">Raised when <paramref name="start" /> and <paramref name="end" /> do not resolve to a range of content suitable for enclosure by a <see cref="T:System.Windows.Documents.Span" /> element; for example, if <paramref name="start" /> and <paramref name="end" /> indicate positions in different paragraphs.</exception> // Token: 0x06003543 RID: 13635 RVA: 0x000F1218 File Offset: 0x000EF418 public Span(TextPointer start, TextPointer end) { if (start == null) { throw new ArgumentNullException("start"); } if (end == null) { throw new ArgumentNullException("start"); } if (start.TextContainer != end.TextContainer) { throw new ArgumentException(SR.Get("InDifferentTextContainers", new object[] { "start", "end" })); } if (start.CompareTo(end) > 0) { throw new ArgumentException(SR.Get("BadTextPositionOrder", new object[] { "start", "end" })); } start.TextContainer.BeginChange(); try { start = TextRangeEditTables.EnsureInsertionPosition(start); Invariant.Assert(start.Parent is Run); end = TextRangeEditTables.EnsureInsertionPosition(end); Invariant.Assert(end.Parent is Run); if (start.Paragraph != end.Paragraph) { throw new ArgumentException(SR.Get("InDifferentParagraphs", new object[] { "start", "end" })); } Inline nonMergeableInlineAncestor; if ((nonMergeableInlineAncestor = start.GetNonMergeableInlineAncestor()) != null) { throw new InvalidOperationException(SR.Get("TextSchema_CannotSplitElement", new object[] { nonMergeableInlineAncestor.GetType().Name })); } if ((nonMergeableInlineAncestor = end.GetNonMergeableInlineAncestor()) != null) { throw new InvalidOperationException(SR.Get("TextSchema_CannotSplitElement", new object[] { nonMergeableInlineAncestor.GetType().Name })); } TextElement commonAncestor = TextElement.GetCommonAncestor((TextElement)start.Parent, (TextElement)end.Parent); while (start.Parent != commonAncestor) { start = this.SplitElement(start); } while (end.Parent != commonAncestor) { end = this.SplitElement(end); } if (start.Parent is Run) { start = this.SplitElement(start); } if (end.Parent is Run) { end = this.SplitElement(end); } Invariant.Assert(start.Parent == end.Parent); Invariant.Assert(TextSchema.IsValidChild(start, typeof(Span))); base.Reposition(start, end); } finally { start.TextContainer.EndChange(); } }
internal static bool ConvertParagraphsToListItems(TextRange range, TextMarkerStyle markerStyle) { if (range.IsEmpty && TextPointerBase.IsAtPotentialParagraphPosition(range.Start)) { TextPointer insertionPosition = TextRangeEditTables.EnsureInsertionPosition(range.Start); ((ITextRange)range).Select(insertionPosition, insertionPosition); } Block firstBlock = range.Start.ParagraphOrBlockUIContainer; TextPointer end = (TextPointer)TextRangeEdit.GetAdjustedRangeEnd(range.Start, range.End); Block lastBlock = end.ParagraphOrBlockUIContainer; // We assume that a range contains a sequence of one-level paragraphs. // Otherwise the operation is disabled. if (firstBlock == null || lastBlock == null || firstBlock.Parent != lastBlock.Parent || firstBlock.Parent is ListItem && firstBlock.PreviousBlock == null) { // Either the paragraphs belong to different scopes or first of them has a bullet already. // We cannot convert them into bulleted lists. return(false); } // Check that all top-level elements of selection are Paragraphs. // We do not apply the command to Tables or Sections. for (Block block = firstBlock; block != lastBlock && block != null; block = block.NextBlock) { if (block is Table || block is Section) { return(false); } } ListItem parentListItem = firstBlock.Parent as ListItem; if (parentListItem != null) { // Paragraphs are inside of ListItem already. // Split a current ListItem before each of selected blocks Block block = firstBlock; while (block != null) { Block nextBlock = block == lastBlock ? null : block.ElementEnd.GetAdjacentElement(LogicalDirection.Forward) as Block; Invariant.Assert(block.Parent is ListItem); TextRangeEdit.SplitElement(block.ElementStart); block = nextBlock; } } else { // Create a list around all paragraphs List list = new List(); list.MarkerStyle = markerStyle; list.Apply(firstBlock, lastBlock); // Merge with neighboring lists //MergeLists(list.ElementEnd); // start with End to not loose an instance of "list" during merging with the following list //MergeLists(list.ElementStart); } return(true); }