internal static bool ValidateChild(TextElement parent, Type childType, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent) { // Disallow nested hyperlink elements. if (TextSchema.HasHyperlinkAncestor(parent)) { if (typeof(Hyperlink).IsAssignableFrom(childType) || typeof(AnchoredBlock).IsAssignableFrom(childType)) { if (throwIfIllegalHyperlinkDescendent) { throw new InvalidOperationException(SR.Get(SRID.TextSchema_IllegalHyperlinkChild, childType)); } return(false); } } bool isValidChild = IsValidChild(parent.GetType(), childType); if (!isValidChild && throwIfIllegalChild) { throw new InvalidOperationException(SR.Get(SRID.TextSchema_ChildTypeIsInvalid, parent.GetType().Name, childType.Name)); } return(isValidChild); }
// Token: 0x060038DB RID: 14555 RVA: 0x00100F94 File Offset: 0x000FF194 private static ITextPointer GetNextTextPosition(ITextPointer position, ITextPointer limit, LogicalDirection direction, out char character) { bool flag = false; character = '\0'; while (position != null && !flag && (limit == null || position.CompareTo(limit) < 0)) { switch (position.GetPointerContext(direction)) { case TextPointerContext.Text: { char[] array = new char[1]; position.GetTextInRun(direction, array, 0, 1); character = array[0]; flag = true; continue; } case TextPointerContext.ElementStart: case TextPointerContext.ElementEnd: if (TextSchema.IsFormattingType(position.GetElementType(direction))) { position = position.CreatePointer(1); continue; } position = null; continue; } position = null; } return(position); }
internal static void _OnApplyProperty(TextEditor This, DependencyProperty formattingProperty, object propertyValue, bool applyToParagraphs, PropertyValueAction propertyValueAction) { if (This == null || !This._IsEnabled || This.IsReadOnly || !This.AcceptsRichContent || !(This.Selection is TextSelection)) { return; } // Check whether the property is known if (!TextSchema.IsParagraphProperty(formattingProperty) && !TextSchema.IsCharacterProperty(formattingProperty)) { Invariant.Assert(false, "The property '" + formattingProperty.Name + "' is unknown to TextEditor"); return; } TextSelection selection = (TextSelection)This.Selection; if (TextSchema.IsStructuralCharacterProperty(formattingProperty) && !TextRangeEdit.CanApplyStructuralInlineProperty(selection.Start, selection.End)) { // Ignore structural commands fires in inappropriate context. return; } TextEditorTyping._FlushPendingInputItems(This); // Forget previously suggested horizontal position TextEditorSelection._ClearSuggestedX(This); // Break merged typing sequence TextEditorTyping._BreakTypingSequence(This); // Apply property selection.ApplyPropertyValue(formattingProperty, propertyValue, applyToParagraphs, propertyValueAction); }
// Token: 0x060039C1 RID: 14785 RVA: 0x001064C0 File Offset: 0x001046C0 private static bool IsAdjacentToFormatElement(ITextPointer pointer, LogicalDirection direction) { bool result = false; if (direction == LogicalDirection.Forward) { TextPointerContext pointerContext = pointer.GetPointerContext(LogicalDirection.Forward); if (pointerContext == TextPointerContext.ElementStart && TextSchema.IsFormattingType(pointer.GetElementType(LogicalDirection.Forward))) { result = true; } else if (pointerContext == TextPointerContext.ElementEnd && TextSchema.IsFormattingType(pointer.ParentType)) { result = true; } } else { TextPointerContext pointerContext = pointer.GetPointerContext(LogicalDirection.Backward); if (pointerContext == TextPointerContext.ElementEnd && TextSchema.IsFormattingType(pointer.GetElementType(LogicalDirection.Backward))) { result = true; } else if (pointerContext == TextPointerContext.ElementStart && TextSchema.IsFormattingType(pointer.ParentType)) { result = true; } } return(result); }
// Token: 0x06003BE7 RID: 15335 RVA: 0x001141F8 File Offset: 0x001123F8 internal static bool ValidateChild(TextPointer position, Type childType, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent) { DependencyObject parent = position.Parent; if (parent == null) { TextElement adjacentElementFromOuterPosition = position.GetAdjacentElementFromOuterPosition(LogicalDirection.Backward); TextElement adjacentElementFromOuterPosition2 = position.GetAdjacentElementFromOuterPosition(LogicalDirection.Forward); return((adjacentElementFromOuterPosition == null || TextSchema.IsValidSibling(adjacentElementFromOuterPosition.GetType(), childType)) && (adjacentElementFromOuterPosition2 == null || TextSchema.IsValidSibling(adjacentElementFromOuterPosition2.GetType(), childType))); } if (parent is TextElement) { return(TextSchema.ValidateChild((TextElement)parent, childType, throwIfIllegalChild, throwIfIllegalHyperlinkDescendent)); } bool flag = TextSchema.IsValidChild(parent.GetType(), childType); if (!flag && throwIfIllegalChild) { throw new InvalidOperationException(SR.Get("TextSchema_ChildTypeIsInvalid", new object[] { parent.GetType().Name, childType.Name })); } return(flag); }
// Token: 0x06003B87 RID: 15239 RVA: 0x0010F4AC File Offset: 0x0010D6AC internal static bool ParagraphsAreMergeable(Block firstParagraphOrBlockUIContainer, Block secondParagraphOrBlockUIContainer) { if (firstParagraphOrBlockUIContainer == null || secondParagraphOrBlockUIContainer == null || firstParagraphOrBlockUIContainer == secondParagraphOrBlockUIContainer) { return(false); } TextPointer textPointer = firstParagraphOrBlockUIContainer.ElementEnd; TextPointer elementStart = secondParagraphOrBlockUIContainer.ElementStart; while (textPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd) { if (!TextSchema.AllowsParagraphMerging(textPointer.Parent.GetType())) { return(false); } textPointer = textPointer.GetNextContextPosition(LogicalDirection.Forward); } while (textPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) { if (textPointer.CompareTo(elementStart) == 0) { return(true); } textPointer = textPointer.GetNextContextPosition(LogicalDirection.Forward); if (!TextSchema.AllowsParagraphMerging(textPointer.Parent.GetType())) { return(false); } } return(false); }
// ............................................................... // // TextSchema Validation // // ............................................................... // Checks whether it is valid to insert the child object at passed position. internal static void ValidateChild(TextPointer position, object child, string paramName) { Invariant.Assert(position != null); if (child == null) { throw new ArgumentNullException(paramName); } if (!TextSchema.IsValidChild(/*position:*/ position, /*childType:*/ child.GetType())) { throw new ArgumentException(SR.Get(SRID.TextSchema_ChildTypeIsInvalid, position.Parent.GetType().Name, child.GetType().Name)); } // The new child should not be currently in other text tree if (child is TextElement) { if (((TextElement)child).Parent != null) { throw new ArgumentException(SR.Get(SRID.TextSchema_TheChildElementBelongsToAnotherTreeAlready, child.GetType().Name)); } } else { Invariant.Assert(child is UIElement); // Cannot call UIElement.Parent across assembly boundary. So skip this part of validation. This condition will be checked elsewhere anyway. //if (((UIElement)child).Parent != null) //{ // throw new ArgumentException(SR.Get(SRID.TextSchema_TheChildElementBelongsToAnotherTreeAlready, child.GetType().Name)); //} } }
// Token: 0x06003EF1 RID: 16113 RVA: 0x0011F3C8 File Offset: 0x0011D5C8 internal static void ValidateChild(TextPointer position, object child, string paramName) { Invariant.Assert(position != null); if (child == null) { throw new ArgumentNullException(paramName); } if (!TextSchema.IsValidChild(position, child.GetType())) { throw new ArgumentException(SR.Get("TextSchema_ChildTypeIsInvalid", new object[] { position.Parent.GetType().Name, child.GetType().Name })); } if (child is TextElement) { if (((TextElement)child).Parent != null) { throw new ArgumentException(SR.Get("TextSchema_TheChildElementBelongsToAnotherTreeAlready", new object[] { child.GetType().Name })); } } else { Invariant.Assert(child is UIElement); } }
// Token: 0x06003BE5 RID: 15333 RVA: 0x00114150 File Offset: 0x00112350 internal static bool ValidateChild(TextElement parent, Type childType, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent) { if (TextSchema.HasHyperlinkAncestor(parent) && (typeof(Hyperlink).IsAssignableFrom(childType) || typeof(AnchoredBlock).IsAssignableFrom(childType))) { if (throwIfIllegalHyperlinkDescendent) { throw new InvalidOperationException(SR.Get("TextSchema_IllegalHyperlinkChild", new object[] { childType })); } return(false); } else { bool flag = TextSchema.IsValidChild(parent.GetType(), childType); if (!flag && throwIfIllegalChild) { throw new InvalidOperationException(SR.Get("TextSchema_ChildTypeIsInvalid", new object[] { parent.GetType().Name, childType.Name })); } return(flag); } }
/// <summary> /// ToggleUnderline command event handler. /// </summary> private static void OnToggleUnderline(object target, ExecutedRoutedEventArgs args) { TextEditor This = TextEditor._GetTextEditor(target); if (This == null || !This._IsEnabled || This.IsReadOnly || !This.AcceptsRichContent || !(This.Selection is TextSelection)) { return; } TextEditorTyping._FlushPendingInputItems(This); object propertyValue = ((TextSelection)This.Selection).GetCurrentValue(Inline.TextDecorationsProperty); TextDecorationCollection textDecorations = propertyValue != DependencyProperty.UnsetValue ? (TextDecorationCollection)propertyValue : null; TextDecorationCollection toggledTextDecorations; if (!TextSchema.HasTextDecorations(textDecorations)) { toggledTextDecorations = TextDecorations.Underline; } else if (!textDecorations.TryRemove(TextDecorations.Underline, out toggledTextDecorations)) { // TextDecorations.Underline was not present, so add it toggledTextDecorations.Add(TextDecorations.Underline); } TextEditorCharacters._OnApplyProperty(This, Inline.TextDecorationsProperty, toggledTextDecorations); }
// Token: 0x06002EFA RID: 12026 RVA: 0x000D47DC File Offset: 0x000D29DC private void _SkipFormattingTags(ITextPointer textPointer) { LogicalDirection logicalDirection = textPointer.LogicalDirection; int offset = (logicalDirection == LogicalDirection.Forward) ? 1 : -1; while (TextSchema.IsFormattingType(textPointer.GetElementType(logicalDirection))) { textPointer.MoveByOffset(offset); } }
// Token: 0x06003B88 RID: 15240 RVA: 0x0010F530 File Offset: 0x0010D730 internal static bool SplitListsForFlowDirectionChange(TextPointer start, TextPointer end, object newFlowDirectionValue) { ListItem listAncestor = start.GetListAncestor(); if (listAncestor != null && listAncestor.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listAncestor.List.GetValue(Block.FlowDirectionProperty))) { while (listAncestor != null && listAncestor.List != null && listAncestor.List.Parent is ListItem) { if (!TextRangeEditLists.UnindentListItems(new TextRange(start, TextRangeEditLists.GetPositionAfterList(listAncestor.List)))) { return(false); } listAncestor = start.GetListAncestor(); } } ListItem listItem = end.GetListAncestor(); if (listItem != null && listItem.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listItem.List.GetValue(Block.FlowDirectionProperty))) { if (listAncestor == null || listAncestor.List == null || listItem.List.ElementEnd.CompareTo(listAncestor.List.ElementEnd) >= 0) { while (listItem != null && listItem.List != null && listItem.List.Parent is ListItem) { if (!TextRangeEditLists.UnindentListItems(new TextRange(listItem.List.ContentStart, TextRangeEditLists.GetPositionAfterList(listItem.List)))) { return(false); } listItem = end.GetListAncestor(); } } } if ((listAncestor = start.GetListAncestor()) != null && listAncestor.PreviousListItem != null && listAncestor.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listAncestor.List.GetValue(Block.FlowDirectionProperty))) { Invariant.Assert(!(listAncestor.List.Parent is ListItem), "startListItem's list must not be nested!"); TextRangeEdit.SplitElement(listAncestor.ElementStart); } if ((listItem = end.GetListAncestor()) != null && listItem.List != null && !TextSchema.ValuesAreEqual(newFlowDirectionValue, listItem.List.GetValue(Block.FlowDirectionProperty))) { if (listItem.List.Parent is ListItem) { while (listItem.List != null && listItem.List.Parent is ListItem) { listItem = (ListItem)listItem.List.Parent; } } if (listItem.List != null && listItem.NextListItem != null) { Invariant.Assert(!(listItem.List.Parent is ListItem), "endListItem's list must not be nested!"); TextRangeEdit.SplitElement(listItem.ElementEnd); } } return(true); }
private void _SkipFormattingTags(ITextPointer textPointer) { Debug.Assert(!textPointer.IsFrozen, "Can't reposition a frozen pointer!"); LogicalDirection dir = textPointer.LogicalDirection; int increment = (dir == LogicalDirection.Forward ? +1 : -1); while (TextSchema.IsFormattingType(textPointer.GetElementType(dir))) { textPointer.MoveByOffset(increment); } }
/// <summary>Returns the effective value of a specified formatting property on the current selection.</summary> /// <param name="formattingProperty">A formatting property to get the value of with respect to the current selection.</param> /// <returns>An object specifying the value of the specified formatting property.</returns> /// <exception cref="T:System.ArgumentException">Occurs when <paramref name="formattingProperty" /> does not specify a valid formatting property, or <paramref name="value" /> specifies an invalid value for <paramref name="formattingProperty" />.</exception> /// <exception cref="T:System.ArgumentNullException">Occurs when <paramref name="formattingProperty" /> is <see langword="null" />.</exception> // Token: 0x06003AD9 RID: 15065 RVA: 0x0010A2EC File Offset: 0x001084EC public object GetPropertyValue(DependencyProperty formattingProperty) { if (formattingProperty == null) { throw new ArgumentNullException("formattingProperty"); } if (!TextSchema.IsCharacterProperty(formattingProperty) && !TextSchema.IsParagraphProperty(formattingProperty)) { throw new ArgumentException(SR.Get("TextEditorPropertyIsNotApplicableForTextFormatting", new object[] { formattingProperty.Name })); } return(((ITextRange)this).GetPropertyValue(formattingProperty)); }
//------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods /// <summary> /// This method performs schema validation for inline collections. /// (1) We want to disallow nested Hyperlink elements. /// (2) Also, a Hyperlink element allows only these child types: Run, InlineUIContainer and Span elements other than Hyperlink. /// </summary> internal override void ValidateChild(Inline child) { base.ValidateChild(child); if (this.Parent is TextElement) { TextSchema.ValidateChild((TextElement)this.Parent, child, true /* throwIfIllegalChild */, true /* throwIfIllegalHyperlinkDescendent */); } else { if (!TextSchema.IsValidChildOfContainer(this.Parent.GetType(), child.GetType())) { throw new InvalidOperationException(SR.Get(SRID.TextSchema_ChildTypeIsInvalid, this.Parent.GetType().Name, child.GetType().Name)); } } }
// Token: 0x0600309E RID: 12446 RVA: 0x000DB2F4 File Offset: 0x000D94F4 internal override void ValidateChild(Inline child) { base.ValidateChild(child); if (base.Parent is TextElement) { TextSchema.ValidateChild((TextElement)base.Parent, child, true, true); return; } if (!TextSchema.IsValidChildOfContainer(base.Parent.GetType(), child.GetType())) { throw new InvalidOperationException(SR.Get("TextSchema_ChildTypeIsInvalid", new object[] { base.Parent.GetType().Name, child.GetType().Name })); } }
// Token: 0x06003BE3 RID: 15331 RVA: 0x001140D8 File Offset: 0x001122D8 internal static bool ValidateChild(TextElement parent, TextElement child, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent) { if (TextSchema.HasHyperlinkAncestor(parent) && TextSchema.HasIllegalHyperlinkDescendant(child, throwIfIllegalHyperlinkDescendent)) { return(false); } bool flag = TextSchema.IsValidChild(parent.GetType(), child.GetType()); if (!flag && throwIfIllegalChild) { throw new InvalidOperationException(SR.Get("TextSchema_ChildTypeIsInvalid", new object[] { parent.GetType().Name, child.GetType().Name })); } return(flag); }
internal static bool ValidateChild(TextElement parent, TextElement child, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent) { // Disallow nested hyperlink elements. if (TextSchema.HasHyperlinkAncestor(parent) && TextSchema.HasIllegalHyperlinkDescendant(child, throwIfIllegalHyperlinkDescendent)) { return(false); } bool isValidChild = IsValidChild(parent.GetType(), child.GetType()); if (!isValidChild && throwIfIllegalChild) { throw new InvalidOperationException(SR.Get(SRID.TextSchema_ChildTypeIsInvalid, parent.GetType().Name, child.GetType().Name)); } return(isValidChild); }
// Checks whether two paragraphs are meargeable. // To be meargeable they need to be separated by s sequence of closing, then opening // tags only. // And all tags must be Sections/Lists/ListItems only. internal static bool ParagraphsAreMergeable(Block firstParagraphOrBlockUIContainer, Block secondParagraphOrBlockUIContainer) { if (firstParagraphOrBlockUIContainer == null || secondParagraphOrBlockUIContainer == null || firstParagraphOrBlockUIContainer == secondParagraphOrBlockUIContainer) { return(false); // nothing to merge } TextPointer position = firstParagraphOrBlockUIContainer.ElementEnd; TextPointer startOfSecondParagraph = secondParagraphOrBlockUIContainer.ElementStart; // Skip and check all closing tags (if any) while (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd) { if (!TextSchema.AllowsParagraphMerging(position.Parent.GetType())) { return(false); // Crossing hard-structured element. Paragraphs are not meargeable. } position = position.GetNextContextPosition(LogicalDirection.Forward); } // Skip and check all opening tags (if any) while (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) { if (position.CompareTo(startOfSecondParagraph) == 0) { // Successfully skipped all tags, and reached the seconfParagraph. // The paragraphs are meargeable. return(true); } position = position.GetNextContextPosition(LogicalDirection.Forward); if (!TextSchema.AllowsParagraphMerging(position.Parent.GetType())) { return(false); // Crossing hardd-structured element. Paragraphs are not meargeable. } } // Non-tag run found. Paragraphs are not meargeable. return(false); }
// Returns the position preceeding the next text character in a specified // direction, or null if no such position exists. // The scan will halt if limit is encounted; limit may be null. private static ITextPointer GetNextTextPosition(ITextPointer position, ITextPointer limit, LogicalDirection direction, out char character) { bool foundText = false; character = (char)0; while (position != null && !foundText && (limit == null || position.CompareTo(limit) < 0)) { switch (position.GetPointerContext(direction)) { case TextPointerContext.Text: char[] buffer = new char[1]; position.GetTextInRun(direction, buffer, 0, 1); character = buffer[0]; foundText = true; break; case TextPointerContext.ElementStart: case TextPointerContext.ElementEnd: if (TextSchema.IsFormattingType(position.GetElementType(direction))) { position = position.CreatePointer(+1); } else { position = null; } break; case TextPointerContext.EmbeddedElement: case TextPointerContext.None: default: position = null; break; } } return(position); }
// Token: 0x06003AD7 RID: 15063 RVA: 0x0010A16C File Offset: 0x0010836C internal void ApplyPropertyValue(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction) { Invariant.Assert(this.HasConcreteTextContainer, "Can't apply property to non-TextContainer range!"); if (formattingProperty == null) { throw new ArgumentNullException("formattingProperty"); } if (!TextSchema.IsCharacterProperty(formattingProperty) && !TextSchema.IsParagraphProperty(formattingProperty)) { throw new ArgumentException(SR.Get("TextEditorPropertyIsNotApplicableForTextFormatting", new object[] { formattingProperty.Name })); } if (value is string && formattingProperty.PropertyType != typeof(string)) { TypeConverter converter = TypeDescriptor.GetConverter(formattingProperty.PropertyType); Invariant.Assert(converter != null); value = converter.ConvertFromString((string)value); } if (!formattingProperty.IsValidValue(value) && (!(formattingProperty.PropertyType == typeof(Thickness)) || !(value is Thickness))) { throw new ArgumentException(SR.Get("TextEditorTypeOfParameterIsNotAppropriateForFormattingProperty", new object[] { (value == null) ? "null" : value.GetType().Name, formattingProperty.Name }), "value"); } if (propertyValueAction != PropertyValueAction.SetValue && propertyValueAction != PropertyValueAction.IncreaseByAbsoluteValue && propertyValueAction != PropertyValueAction.DecreaseByAbsoluteValue && propertyValueAction != PropertyValueAction.IncreaseByPercentageValue && propertyValueAction != PropertyValueAction.DecreaseByPercentageValue) { throw new ArgumentException(SR.Get("TextRange_InvalidParameterValue"), "propertyValueAction"); } if (propertyValueAction != PropertyValueAction.SetValue && !TextSchema.IsPropertyIncremental(formattingProperty)) { throw new ArgumentException(SR.Get("TextRange_PropertyCannotBeIncrementedOrDecremented", new object[] { formattingProperty.Name }), "propertyValueAction"); } this.ApplyPropertyToTextVirtual(formattingProperty, value, applyToParagraphs, propertyValueAction); }
// Token: 0x06003835 RID: 14389 RVA: 0x000FA980 File Offset: 0x000F8B80 internal static void _OnApplyProperty(TextEditor This, DependencyProperty formattingProperty, object propertyValue, bool applyToParagraphs, PropertyValueAction propertyValueAction) { if (This == null || !This._IsEnabled || This.IsReadOnly || !This.AcceptsRichContent || !(This.Selection is TextSelection)) { return; } if (!TextSchema.IsParagraphProperty(formattingProperty) && !TextSchema.IsCharacterProperty(formattingProperty)) { Invariant.Assert(false, "The property '" + formattingProperty.Name + "' is unknown to TextEditor"); return; } TextSelection textSelection = (TextSelection)This.Selection; if (TextSchema.IsStructuralCharacterProperty(formattingProperty) && !TextRangeEdit.CanApplyStructuralInlineProperty(textSelection.Start, textSelection.End)) { return; } TextEditorTyping._FlushPendingInputItems(This); TextEditorSelection._ClearSuggestedX(This); TextEditorTyping._BreakTypingSequence(This); textSelection.ApplyPropertyValue(formattingProperty, propertyValue, applyToParagraphs, propertyValueAction); }
// Token: 0x06003AFE RID: 15102 RVA: 0x0010A744 File Offset: 0x00108944 internal virtual void ApplyPropertyToTextVirtual(DependencyProperty formattingProperty, object value, bool applyToParagraphs, PropertyValueAction propertyValueAction) { TextRangeBase.BeginChange(this); try { for (int i = 0; i < this._textSegments.Count; i++) { TextSegment textSegment = this._textSegments[i]; if (formattingProperty == FrameworkElement.FlowDirectionProperty) { if (applyToParagraphs || this.IsEmpty || TextRangeBase.IsParagraphBoundaryCrossed(this)) { TextRangeEdit.SetParagraphProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction); } else { TextRangeEdit.SetInlineProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction); } } else if (TextSchema.IsCharacterProperty(formattingProperty)) { TextRangeEdit.SetInlineProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction); } else if (TextSchema.IsParagraphProperty(formattingProperty)) { if (formattingProperty.PropertyType == typeof(Thickness) && (FlowDirection)textSegment.Start.GetValue(Block.FlowDirectionProperty) == FlowDirection.RightToLeft) { value = new Thickness(((Thickness)value).Right, ((Thickness)value).Top, ((Thickness)value).Left, ((Thickness)value).Bottom); } TextRangeEdit.SetParagraphProperty((TextPointer)textSegment.Start, (TextPointer)textSegment.End, formattingProperty, value, propertyValueAction); } } } finally { TextRangeBase.EndChange(this); } }
// Token: 0x06003839 RID: 14393 RVA: 0x000FAC48 File Offset: 0x000F8E48 private static void OnToggleUnderline(object target, ExecutedRoutedEventArgs args) { TextEditor textEditor = TextEditor._GetTextEditor(target); if (textEditor == null || !textEditor._IsEnabled || textEditor.IsReadOnly || !textEditor.AcceptsRichContent || !(textEditor.Selection is TextSelection)) { return; } TextEditorTyping._FlushPendingInputItems(textEditor); object currentValue = ((TextSelection)textEditor.Selection).GetCurrentValue(Inline.TextDecorationsProperty); TextDecorationCollection textDecorationCollection = (currentValue != DependencyProperty.UnsetValue) ? ((TextDecorationCollection)currentValue) : null; TextDecorationCollection underline; if (!TextSchema.HasTextDecorations(textDecorationCollection)) { underline = TextDecorations.Underline; } else if (!textDecorationCollection.TryRemove(TextDecorations.Underline, out underline)) { underline.Add(TextDecorations.Underline); } TextEditorCharacters._OnApplyProperty(textEditor, Inline.TextDecorationsProperty, underline); }
/// <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(); } }
// Token: 0x06003BE2 RID: 15330 RVA: 0x001140C3 File Offset: 0x001122C3 internal static bool IsInTextContent(ITextPointer position) { return(TextSchema.IsValidChild(position, typeof(string))); }
/// <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(); } }
// Checks if start and end positions are parented by a List. // If so, unindents list items between (start - start's list end) or (end's list start - end) // until they are parented by a top level list. // Then, if needed, splits the list(s) at start and/or end positions. // Returns false if splitting is not successful due to a failing unindent operation on any nested lists. internal static bool SplitListsForFlowDirectionChange(TextPointer start, TextPointer end, object newFlowDirectionValue) { ListItem startListItem = start.GetListAncestor(); // Unindent startListItem's list to prepare for a split, if the List's FlowDirection value is different. if (startListItem != null && startListItem.List != null && // Check for unparented list items !TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ startListItem.List.GetValue(Paragraph.FlowDirectionProperty))) { while (startListItem != null && startListItem.List != null && startListItem.List.Parent is ListItem) { // startListItem is within a nested List. if (!UnindentListItems(new TextRange(start, GetPositionAfterList(startListItem.List)))) { return(false); } startListItem = start.GetListAncestor(); } } ListItem endListItem = end.GetListAncestor(); // Unindent endListItem's list to prepare for a split, if the List's FlowDirection value is different. if (endListItem != null && endListItem.List != null && !TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ endListItem.List.GetValue(Paragraph.FlowDirectionProperty))) { if (startListItem != null && startListItem.List != null && endListItem.List.ElementEnd.CompareTo(startListItem.List.ElementEnd) < 0) { // endListItem's List is contained within startListItem's List. // No need to unindent endListItem. } else { while (endListItem != null && endListItem.List != null && endListItem.List.Parent is ListItem) { // endListItem is within a nested List. if (!UnindentListItems(new TextRange(endListItem.List.ContentStart, GetPositionAfterList(endListItem.List)))) { return(false); } endListItem = end.GetListAncestor(); } } } // Split list(s) at boundary position(s) if // 1. startListItem is not the first list item within its list (or endListItem is not the last one) // and // 2. start/end's parent List's flow direction value is different than the new value being set if ((startListItem = start.GetListAncestor()) != null && startListItem.PreviousListItem != null && startListItem.List != null && // Check for unparented list items (!TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ startListItem.List.GetValue(Paragraph.FlowDirectionProperty)))) { Invariant.Assert(!(startListItem.List.Parent is ListItem), "startListItem's list must not be nested!"); TextRangeEdit.SplitElement(startListItem.ElementStart); } if ((endListItem = end.GetListAncestor()) != null && endListItem.List != null && // Check for unparented list items (!TextSchema.ValuesAreEqual(/*newValue*/ newFlowDirectionValue, /*currentValue*/ endListItem.List.GetValue(Paragraph.FlowDirectionProperty)))) { // Walk up from endListItem to find the topmost listitem that contains it. if (endListItem.List.Parent is ListItem) { while (endListItem.List != null && endListItem.List.Parent is ListItem) { endListItem = (ListItem)endListItem.List.Parent; } } if (endListItem.List != null && endListItem.NextListItem != null) { Invariant.Assert(!(endListItem.List.Parent is ListItem), "endListItem's list must not be nested!"); TextRangeEdit.SplitElement(endListItem.ElementEnd); } } return(true); }
// -------------------------------------------------------------------- // // Internal Methods // // -------------------------------------------------------------------- #region Internal Methods /// <summary> /// Merges two paragraphs followinng one another. /// The content of a second paragraph is moved into the end /// of the first one. /// </summary> /// <param name="firstParagraphOrBlockUIContainer"> /// First of two merged paragraphs or BlockUIContainer. /// </param> /// <param name="secondParagraphOrBlockUIContainer"> /// Second of two mered paragraphs or BlockUIContainer. /// </param> /// <returns> /// true if paragraphs have been merged; false if no actions where made. /// </returns> internal static bool MergeParagraphs(Block firstParagraphOrBlockUIContainer, Block secondParagraphOrBlockUIContainer) { if (!ParagraphsAreMergeable(firstParagraphOrBlockUIContainer, secondParagraphOrBlockUIContainer)) { return(false); // Cannot mearge these paragraphs. } // Store parent list item of a second paragraph - // to correct its structure after the merge ListItem secondListItem = secondParagraphOrBlockUIContainer.PreviousBlock == null ? secondParagraphOrBlockUIContainer.Parent as ListItem : null; if (secondListItem != null && secondListItem.PreviousListItem == null && secondParagraphOrBlockUIContainer.NextBlock is List) { // The second paragraph is a first list item in some list. // It has a sublists in it, so this sublist must be unindented // to avoid double bulleted line. List sublistOfSecondParagraph = (List)secondParagraphOrBlockUIContainer.NextBlock; if (sublistOfSecondParagraph.ElementEnd.CompareTo(secondListItem.ContentEnd) == 0) { secondListItem.Reposition(null, null); } else { secondListItem.Reposition(sublistOfSecondParagraph.ElementEnd, secondListItem.ContentEnd); } // At this point the schema is temporaty broken: the secondParagraph and the sublistOfSecondParagraph have List as a parent sublistOfSecondParagraph.Reposition(null, null); // The schema is repared as to sublistOfSecondParagraph concern, but still broken for secondParagraph - must be corrected in the following code } // Move the second paragraph out of its wrappers separating from the first paragraph (if any). // We can not use RepositionWithContent because it would destroy // all pointers and ranges within a moved paragraph. // Instead we reposition elements around the two paragraphs. while (secondParagraphOrBlockUIContainer.ElementStart.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { TextElement parentBlock = (TextElement)secondParagraphOrBlockUIContainer.Parent; Invariant.Assert(parentBlock != null); Invariant.Assert(TextSchema.AllowsParagraphMerging(parentBlock.GetType())); if (secondParagraphOrBlockUIContainer.ElementEnd.CompareTo(parentBlock.ContentEnd) == 0) { // Remove ancestor block if it becomes empty parentBlock.Reposition(null, null); } else { // Move ancestor's Start after the end of our paragraph parentBlock.Reposition(secondParagraphOrBlockUIContainer.ElementEnd, parentBlock.ContentEnd); } } // Store a position after the second paragraph where list merging may be needed TextPointer positionAfterSecondParagraph = secondParagraphOrBlockUIContainer.ElementEnd.GetFrozenPointer(LogicalDirection.Forward); // Move the second paragraph to become an immediate following sibling of the first paragraph while (true) { TextElement previousBlock = secondParagraphOrBlockUIContainer.ElementStart.GetAdjacentElement(LogicalDirection.Backward) as TextElement; // Note: We cannot use Block.NextSibling property, because the structure is invalid during this process Invariant.Assert(previousBlock != null); if (previousBlock is Paragraph || previousBlock is BlockUIContainer) { break; } Invariant.Assert(TextSchema.AllowsParagraphMerging(previousBlock.GetType())); previousBlock.Reposition(previousBlock.ContentStart, secondParagraphOrBlockUIContainer.ElementEnd); } // Now that paragraphs are next to each other merge them. // If one of paragraphs is empty we will apply special logic - to preserve a formatting from a non-empty one if (secondParagraphOrBlockUIContainer.TextRange.IsEmpty) { secondParagraphOrBlockUIContainer.RepositionWithContent(null); } else if (firstParagraphOrBlockUIContainer.TextRange.IsEmpty) { firstParagraphOrBlockUIContainer.RepositionWithContent(null); } else if (firstParagraphOrBlockUIContainer is Paragraph && secondParagraphOrBlockUIContainer is Paragraph) { // Do reposition magic for merging paragraph content // without destroying any pointers positioned in them. // Pull the second paragraph into the first one Invariant.Assert(firstParagraphOrBlockUIContainer.ElementEnd.CompareTo(secondParagraphOrBlockUIContainer.ElementStart) == 0); firstParagraphOrBlockUIContainer.Reposition(firstParagraphOrBlockUIContainer.ContentStart, secondParagraphOrBlockUIContainer.ElementEnd); // Store inline merging position TextPointer inlineMergingPosition = secondParagraphOrBlockUIContainer.ElementStart; // Now we can delete the second paragraph secondParagraphOrBlockUIContainer.Reposition(null, null); // Merge formatting elements at the point of paragraphs merging TextRangeEdit.MergeFormattingInlines(inlineMergingPosition); } // Merge ListItems wrapping first and second paragraphs. ListItem followingListItem = positionAfterSecondParagraph.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart ? positionAfterSecondParagraph.GetAdjacentElement(LogicalDirection.Forward) as ListItem : null; if (followingListItem != null && followingListItem == secondListItem) { ListItem precedingListItem = positionAfterSecondParagraph.GetAdjacentElement(LogicalDirection.Backward) as ListItem; if (precedingListItem != null) { // Merge the second list item with the preceding one Invariant.Assert(positionAfterSecondParagraph.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart); Invariant.Assert(positionAfterSecondParagraph.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementEnd); precedingListItem.Reposition(precedingListItem.ContentStart, followingListItem.ElementEnd); followingListItem.Reposition(null, null); } } // Merge lists at merge position MergeLists(positionAfterSecondParagraph); return(true); }
// Token: 0x06003BE4 RID: 15332 RVA: 0x00114145 File Offset: 0x00112345 internal static bool IsValidChild(TextElement parent, Type childType) { return(TextSchema.ValidateChild(parent, childType, false, false)); }