// Existing GetPropertyValue for the TextDecorationCollection will return the first collection, even if it is empty. // this skips empty collections so we can get the actual value. // slightly modified code from https://social.msdn.microsoft.com/Forums/vstudio/en-US/3ac626cf-60aa-427f-80e9-794f3775a70e/how-to-tell-if-richtextbox-selection-is-underlined?forum=wpf public static object GetRealPropertyValue(this swd.TextRange textRange, sw.DependencyProperty formattingProperty, out swd.TextRange fullRange) { object value = null; fullRange = null; var pointer = textRange.Start as swd.TextPointer; if (pointer != null) { var needsContinue = true; swd.TextElement text = null; sw.DependencyObject element = pointer.Parent as swd.TextElement; while (needsContinue && (element is swd.Inline || element is swd.Paragraph || element is swc.TextBlock)) { value = element.GetValue(formattingProperty); text = element as swd.TextElement; var seq = value as IEnumerable; needsContinue = (seq == null) ? value == null : seq.Cast <object>().Count() == 0; element = element is swd.TextElement ? ((swd.TextElement)element).Parent : null; } if (text != null) { fullRange = new swd.TextRange(text.ElementStart, text.ElementEnd); } } return(value); }
public void Insert (TextElement element) { if (element == null) throw new ArgumentNullException ("element"); NativeMethods.text_selection_insert (native, element.native); }
public Component CreateComponent(TextElement textElement) { var elementType = textElement.GetType(); var title = elementType.Name; if (elementType == typeof(Paragraph)) { return new ParagraphComponent(title, textElement as Paragraph); } if (elementType == typeof(Volume)) { return new VolumeComponent(title, textElement as Volume); } if (elementType == typeof(Section)) { return new SectionComponent(title, textElement as Section); } if (elementType == typeof(Run)) { return new RunComponent(title, textElement as Run); } throw new NotSupportedException(string.Format("Not supported type {0}.", elementType)); }
public static void ApplyFont(this System.Windows.Documents.TextElement self, Font font) { if (font.UseNamedSize) { switch (font.NamedSize) { case NamedSize.Micro: self.FontSize = (double)System.Windows.Application.Current.Resources["PhoneFontSizeSmall"] - 3; break; case NamedSize.Small: self.FontSize = (double)System.Windows.Application.Current.Resources["PhoneFontSizeSmall"]; break; case NamedSize.Medium: self.FontSize = (double)System.Windows.Application.Current.Resources["PhoneFontSizeNormal"]; // use normal instead of medium as this is the default break; case NamedSize.Large: self.FontSize = (double)System.Windows.Application.Current.Resources["PhoneFontSizeLarge"]; break; default: throw new ArgumentOutOfRangeException(); } } else { self.FontSize = font.FontSize; } if (!string.IsNullOrEmpty(font.FontFamily)) { self.FontFamily = new FontFamily(font.FontFamily); } else { self.FontFamily = (FontFamily)System.Windows.Application.Current.Resources["PhoneFontFamilyNormal"]; } if (font.FontAttributes.HasFlag(FontAttributes.Italic)) { self.FontStyle = FontStyles.Italic; } else { self.FontStyle = FontStyles.Normal; } if (font.FontAttributes.HasFlag(FontAttributes.Bold)) { self.FontWeight = FontWeights.Bold; } else { self.FontWeight = FontWeights.Normal; } }
public void ApplyFormatToTextElement(TextElement e) { e.FontFamily = FontFamily; e.FontSize = FontSize; e.FontStyle = FontStyle; e.FontWeight = FontWeight; e.FontStretch = FontStretch; if (ForegroundColor!=Colors.Black) e.Foreground = new SolidColorBrush(ForegroundColor); if (BackgroundColor!=Colors.White) e.Background = new SolidColorBrush(BackgroundColor); }
private static void AddItem(TreeViewItem item, TextElement textElement) { TreeViewItem childItem; if (textElement is InlineUIContainer) { childItem = new TreeViewItem { Header = ((InlineUIContainer) textElement).Child.GetType().Name, IsExpanded = true }; item.Items.Add(childItem); } else if (textElement is BlockUIContainer) { childItem = new TreeViewItem { Header = ((BlockUIContainer) textElement).Child.GetType().Name, IsExpanded = true }; item.Items.Add(childItem); } else if (textElement is Span) { AddCollection(item, ((Span) textElement).Inlines); } else if (textElement is Paragraph) { AddCollection(item, ((Paragraph) textElement).Inlines); } else if (textElement is List) { AddCollection(item, ((List) textElement).ListItems); } else if (textElement is ListItem) { AddCollection(item, ((ListItem) textElement).Blocks); } else if (textElement is Table) { TableTreeView(item, textElement as Table); } else if (textElement is AnchoredBlock) { var floater = textElement as Floater; AddCollection(item, ((AnchoredBlock) textElement).Blocks); } //The element should be an inline (Run); try to display the text. else if (textElement is Inline) { var range = new TextRange(((Inline) textElement).ContentEnd, ((Inline) textElement).ContentStart); item.Header = item.Header + " - [" + range.Text + "]"; } }
// ------------------------------------------------------------------- // // 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; }
private TreeViewItem AddNodeToTreeview(ItemsControl parent, SysDoc.TextElement header) { var item = new TreeViewItem() { Header = header }; parent.Items.Add(item); item.IsExpanded = true; return(item); }
public void Apply(swd.TextElement control, Action <sw.TextDecorationCollection> setDecorations) { control.FontFamily = WpfFamily; control.FontStyle = WpfFontStyle; control.FontWeight = WpfFontWeight; control.FontSize = PixelSize; if (setDecorations != null && WpfTextDecorations != null) { setDecorations(WpfTextDecorations); } }
private static void FormatText(TextElement text, TokenType tokenType) { if (tokenType == TokenType.WordForm) { FlowDocumentStyles.FormatWordForm(text); } else if (tokenType == TokenType.Example) { FlowDocumentStyles.FormatExample(text); } else { FlowDocumentStyles.FormatTranslation(text); } }
// Adds a TextTreePropertyUndoUnit to the open parent undo unit, if any. // Called by TextElement's property change listener. internal static void CreatePropertyUndoUnit(TextElement element, DependencyPropertyChangedEventArgs e) { UndoManager undoManager; PropertyRecord record; TextContainer textContainer = element.TextContainer; undoManager = GetOrClearUndoManager(textContainer); if (undoManager == null) return; record = new PropertyRecord(); record.Property = e.Property; record.Value = e.OldValueSource == BaseValueSourceInternal.Local ? e.OldValue : DependencyProperty.UnsetValue; undoManager.Add(new TextTreePropertyUndoUnit(textContainer, element.TextElementNode.GetSymbolOffset(textContainer.Generation) + 1, record)); }
public static void LoadSettingsFor(System.Windows.Documents.TextElement element, MessageSetting setting) { element.FontFamily = setting.Fontfamily; element.FontWeight = setting.Bold; element.FontStyle = setting.Italic; element.FontSize = setting.Size; element.FontWeight = setting.Bold; if (element is Inline) { Inline inline = (Inline)element; inline.TextDecorations = setting.Textdecorations; } else if (element is Paragraph) { Paragraph p = (Paragraph)element; p.TextDecorations = setting.Textdecorations; } }
public TextFormat(TextElement e) { FontFamily = e.FontFamily; FontSize = e.FontSize; FontStyle = e.FontStyle; FontWeight = e.FontWeight; FontStretch = e.FontStretch; if (e.Foreground is SolidColorBrush) { ForegroundColor = ((SolidColorBrush)e.Foreground).Color; } else { ForegroundColor = SystemColors.WindowTextColor; } if (e.Background is SolidColorBrush) { BackgroundColor = ((SolidColorBrush)e.Background).Color; } else { BackgroundColor = SystemColors.WindowColor; } }
//------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods /// <summary> /// Given a ContentElement within FlowDocument searches for associated IContentHost. /// </summary> /// <param name="contentElement">Content element</param> /// <param name="flowDocument">FlowDocument hosting ContentElement.</param> /// <returns>Associated IContentHost with ContentElement.</returns> private static IContentHost GetICHFromFlowDocument(TextElement contentElement, FlowDocument flowDocument) { IContentHost ich = null; List<DocumentPageView> pageViews; ITextView textView = flowDocument.StructuralCache.TextContainer.TextView; if (textView != null) { // If FlowDocument is hosted by FlowDocumentScrollViewer, the RenderScope // is FlowDocumentView object which hosts PageVisual representing the content. // This PageVisual is also IContentHost for the entire content of DocumentPage. if (textView.RenderScope is FlowDocumentView) // FlowDocumentScrollViewer { if (VisualTreeHelper.GetChildrenCount(textView.RenderScope) > 0) { ich = VisualTreeHelper.GetChild(textView.RenderScope, 0) as IContentHost; } } // Our best guess is that FlowDocument is hosted by DocumentViewerBase. // In this case search the style for all DocumentPageViews. // Having collection of DocumentPageViews, find for the one which hosts TextElement. else if (textView.RenderScope is FrameworkElement) { pageViews = new List<DocumentPageView>(); FindDocumentPageViews(textView.RenderScope, pageViews); for (int i = 0; i < pageViews.Count; i++) { if (pageViews[i].DocumentPage is FlowDocumentPage) { textView = (ITextView)((IServiceProvider)pageViews[i].DocumentPage).GetService(typeof(ITextView)); if (textView != null && textView.IsValid) { // Check if the page contains ContentElement. Check Start and End // position, which will give desired results in most of the cases. // Having hyperlink spanning more than 2 pages is not very common, // and this code will not work with it correctly. if (textView.Contains(contentElement.ContentStart) || textView.Contains(contentElement.ContentEnd)) { ich = pageViews[i].DocumentPage.Visual as IContentHost; } } } } } } return ich; }
// Helper function used to set default value for an indicator requesting to merge last paragraph. private static void AdjustFragmentForTargetRange(TextElement fragment, TextRange range) { if (fragment is Section && ((Section)fragment).HasTrailingParagraphBreakOnPaste) { // Explicit indicator is missing, we need to set it by default. // In a case of TextRange.Xml property assignment we assume that // user expects to insert as many paragraphs new paragraphs as her pasted xaml contains. // The expection must be done to the case when the target range is // extended beyond the last paragraph - then we must merge last paragraph // to avoid extra paragraph creation at the end (one additional paragraph // will be created in this case by Pasting code before pasting). // The other case for exception is when target TextContainer is empty - // in this case we as well want to merge last paragraph with the following // one (which will be created as part of paragraph enforcement in pasting operation). // The both desired conditions - IsAfterLastParagraph and "in empty container" // can be identified by the following simple test - range.End is not at end-of-doc. ((Section)fragment).HasTrailingParagraphBreakOnPaste = range.End.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None; } }
// Helper for PasteTextFragment private static void PasteMergeableTextFragment(TextElement fragment, TextRange range, TextPointer insertionPosition) { TextPointer fragmentStart; TextPointer fragmentEnd; if (fragment is Span) { // Split structure at insertion point in target insertionPosition = TextRangeEdit.SplitFormattingElements(insertionPosition, /*keepEmptyFormatting:*/false); Invariant.Assert(insertionPosition.Parent is Paragraph, "insertionPosition must be in a scope of a Paragraph after splitting formatting elements"); // Move the whole Span into the insertion point fragment.RepositionWithContent(insertionPosition); // Store edge positions of inserted content fragmentStart = fragment.ElementStart; fragmentEnd = fragment.ElementEnd; // Remove wrapper from a tree fragment.Reposition(null, null); ValidateMergingPositions(typeof(Inline), fragmentStart, fragmentEnd); // Transfer inheritable contextual properties ApplyContextualProperties(fragmentStart, fragmentEnd, fragment); } else { // Correct leading nested List elements in the fragment CorrectLeadingNestedLists((Section)fragment); // Split a paragraph at insertion position bool needFirstParagraphMerging = SplitParagraphForPasting(ref insertionPosition); // Move the whole Section into the insertion point fragment.RepositionWithContent(insertionPosition); // Store edge positions of inserted content fragmentStart = fragment.ElementStart; fragmentEnd = fragment.ElementEnd.GetPositionAtOffset(0, LogicalDirection.Forward); // need forward orientation to stick with the following content during merge at fragmentStart position // And unwrap the root Section fragment.Reposition(null, null); ValidateMergingPositions(typeof(Block), fragmentStart, fragmentEnd); // Transfer inheritable contextual properties ApplyContextualProperties(fragmentStart, fragmentEnd, fragment); // Merge paragraphs on fragment boundaries if (needFirstParagraphMerging) { MergeParagraphsAtPosition(fragmentStart, /*mergingOnFragmentStart:*/true); } // Get an indication that we need to merge last paragraph if (!((Section)fragment).HasTrailingParagraphBreakOnPaste) { MergeParagraphsAtPosition(fragmentEnd, /*mergingOnFragmentStart:*/false); } } // // For paragraph pasting move range end to the following paragraph, because // it must include an ending paragraph break (in case of no-merging) if (fragment is Section && ((Section)fragment).HasTrailingParagraphBreakOnPaste) { fragmentEnd = fragmentEnd.GetInsertionPosition(LogicalDirection.Forward); } // Select pasted content range.Select(fragmentStart, fragmentEnd); }
private static void PasteTextFragment(TextElement fragment, TextRange range) { Invariant.Assert(range.IsEmpty, "range must be empty at this point - emptied by a caller"); Invariant.Assert(fragment is Section || fragment is Span, "The wrapper element must be a Section or Span"); // Define insertion position. TextPointer insertionPosition = TextRangeEditTables.EnsureInsertionPosition(range.End); // Check if our insertion position has a non-splittable Inline ancestor such as Hyperlink element. // Since we cannot split such Inline, we must switch to Text mode for pasting. // Note that this also has the side effect of converting paragraph breaks to space characters. if (insertionPosition.HasNonMergeableInlineAncestor) { PasteNonMergeableTextFragment(fragment, range); } else { PasteMergeableTextFragment(fragment, range, insertionPosition); } }
private static void SetForeBrushBinding(TextElement inline, object property) { var binding = new Binding { RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(TextBlock), 1), Path = new PropertyPath(property) }; inline.SetBinding(TextElement.ForegroundProperty, binding); }
private void FixParagraphColors(TextElement elem) { var par = elem as Paragraph; if (par!=null) { if (par.Inlines.Count>0) { bool sameFore = true; bool sameBack = true; var firstFmt = new TextFormat(par.Inlines.FirstInline); foreach (var i in par.Inlines) { var fmt = new TextFormat(i); if (fmt.ForegroundColor != firstFmt.ForegroundColor) sameFore = false; if (fmt.BackgroundColor != firstFmt.BackgroundColor) sameBack = false; } var parFmt = new TextFormat(par); if (parFmt.ForegroundColor == Colors.Black && sameFore) par.Foreground = new SolidColorBrush(firstFmt.ForegroundColor); if (parFmt.BackgroundColor == Colors.White && sameBack) par.Background = new SolidColorBrush(firstFmt.BackgroundColor); } } else { foreach (var e in LogicalTreeHelper.GetChildren(elem).OfType<TextElement>()) FixParagraphColors(e); } }
public static void FormatTranslation(TextElement text) { text.Foreground = Brushes.Black; text.FontStyle = FontStyles.Normal; text.FontWeight = FontWeights.Normal; }
// Token: 0x06003B7E RID: 15230 RVA: 0x0010EB84 File Offset: 0x0010CD84 internal static bool MergeParagraphs(Block firstParagraphOrBlockUIContainer, Block secondParagraphOrBlockUIContainer) { if (!TextRangeEditLists.ParagraphsAreMergeable(firstParagraphOrBlockUIContainer, secondParagraphOrBlockUIContainer)) { return(false); } ListItem listItem = (secondParagraphOrBlockUIContainer.PreviousBlock == null) ? (secondParagraphOrBlockUIContainer.Parent as ListItem) : null; if (listItem != null && listItem.PreviousListItem == null && secondParagraphOrBlockUIContainer.NextBlock is List) { List list = (List)secondParagraphOrBlockUIContainer.NextBlock; if (list.ElementEnd.CompareTo(listItem.ContentEnd) == 0) { listItem.Reposition(null, null); } else { listItem.Reposition(list.ElementEnd, listItem.ContentEnd); } list.Reposition(null, null); } while (secondParagraphOrBlockUIContainer.ElementStart.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { TextElement textElement = (TextElement)secondParagraphOrBlockUIContainer.Parent; Invariant.Assert(textElement != null); Invariant.Assert(TextSchema.AllowsParagraphMerging(textElement.GetType())); if (secondParagraphOrBlockUIContainer.ElementEnd.CompareTo(textElement.ContentEnd) == 0) { textElement.Reposition(null, null); } else { textElement.Reposition(secondParagraphOrBlockUIContainer.ElementEnd, textElement.ContentEnd); } } TextPointer frozenPointer = secondParagraphOrBlockUIContainer.ElementEnd.GetFrozenPointer(LogicalDirection.Forward); for (;;) { TextElement textElement2 = secondParagraphOrBlockUIContainer.ElementStart.GetAdjacentElement(LogicalDirection.Backward) as TextElement; Invariant.Assert(textElement2 != null); if (textElement2 is Paragraph || textElement2 is BlockUIContainer) { break; } Invariant.Assert(TextSchema.AllowsParagraphMerging(textElement2.GetType())); textElement2.Reposition(textElement2.ContentStart, secondParagraphOrBlockUIContainer.ElementEnd); } if (secondParagraphOrBlockUIContainer.TextRange.IsEmpty) { secondParagraphOrBlockUIContainer.RepositionWithContent(null); } else if (firstParagraphOrBlockUIContainer.TextRange.IsEmpty) { firstParagraphOrBlockUIContainer.RepositionWithContent(null); } else if (firstParagraphOrBlockUIContainer is Paragraph && secondParagraphOrBlockUIContainer is Paragraph) { Invariant.Assert(firstParagraphOrBlockUIContainer.ElementEnd.CompareTo(secondParagraphOrBlockUIContainer.ElementStart) == 0); firstParagraphOrBlockUIContainer.Reposition(firstParagraphOrBlockUIContainer.ContentStart, secondParagraphOrBlockUIContainer.ElementEnd); TextPointer elementStart = secondParagraphOrBlockUIContainer.ElementStart; secondParagraphOrBlockUIContainer.Reposition(null, null); TextRangeEdit.MergeFormattingInlines(elementStart); } ListItem listItem2 = (frozenPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) ? (frozenPointer.GetAdjacentElement(LogicalDirection.Forward) as ListItem) : null; if (listItem2 != null && listItem2 == listItem) { ListItem listItem3 = frozenPointer.GetAdjacentElement(LogicalDirection.Backward) as ListItem; if (listItem3 != null) { Invariant.Assert(frozenPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart); Invariant.Assert(frozenPointer.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementEnd); listItem3.Reposition(listItem3.ContentStart, listItem2.ElementEnd); listItem2.Reposition(null, null); } } TextRangeEditLists.MergeLists(frozenPointer); 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); }
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); }
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, e.UserInitiated); } 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; }
// Token: 0x06003BE4 RID: 15332 RVA: 0x00114145 File Offset: 0x00112345 internal static bool IsValidChild(TextElement parent, Type childType) { return(TextSchema.ValidateChild(parent, childType, false, false)); }
internal static bool IsValidChild(TextElement parent, TextElement child) { return(ValidateChild(parent, child, false /* throwIfIllegalChild */, false /* throwIfIllegalHyperlinkDescendent */)); }
public static void FormatExample(TextElement text) { text.Foreground = Brushes.Black; text.FontStyle = FontStyles.Italic; text.FontWeight = FontWeights.Normal; }
public bool HasUnmappedFormat(TextElement block) { return !mFormatMarkupMapping.ContainsKey(new TextFormat(block)); }
// 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); }
public static int CountNumberOfFormatInstances(TextElement element, TextFormat format) { if (format.Equals(new TextFormat(element))) return 1; return LogicalTreeHelper.GetChildren(element).OfType<TextElement>().Sum(o => CountNumberOfFormatInstances(o, format)); }
// Tests whether this element is a Run inserted at potential run position. // It is used in decidint whether the empty element can be removed // or not. The Run that is at potential run position should not // be removed as it would cause a loss of formatting data at this // position. internal static bool IsAtPotentialRunPosition(TextElement run) { return run is Run && run.IsEmpty && IsAtPotentialRunPosition(run.ElementStart, run.ElementEnd); }
// ............................................................. // // Pasting // // ............................................................. // Handles a special case for pasting a single embedded element - // needs to choose between BlockUIContainer and InlineUIContainer. private static bool PasteSingleEmbeddedElement(TextRange range, TextElement fragment) { if (fragment.ContentStart.GetOffsetToPosition(fragment.ContentEnd) == 3) { TextElement uiContainer = fragment.ContentStart.GetAdjacentElement(LogicalDirection.Forward) as TextElement; FrameworkElement embeddedElement = null; if (uiContainer is BlockUIContainer) { embeddedElement = ((BlockUIContainer)uiContainer).Child as FrameworkElement; if (embeddedElement != null) { ((BlockUIContainer)uiContainer).Child = null; } } else if (uiContainer is InlineUIContainer) { embeddedElement = ((InlineUIContainer)uiContainer).Child as FrameworkElement; if (embeddedElement != null) { ((InlineUIContainer)uiContainer).Child = null; } } if (embeddedElement != null) { range.InsertEmbeddedUIElement(embeddedElement); return true; } } return false; }
private bool TryMatch(TextElement element) { if (myAction(element)) { myResults.Add(element); if (!ContinueAfterMatch) { return false; } } return true; }
// Helper for PasteTextFragment private static void PasteNonMergeableTextFragment(TextElement fragment, TextRange range) { // We cannot split Hyperlink or other non-splittable inline ancestor. // Paste text content of fragment in such case. // Get text content to be pasted. string fragmentText = TextRangeBase.GetTextInternal(fragment.ElementStart, fragment.ElementEnd); // Paste text into our empty target range. // range.Text = fragmentText; // Select pasted content range.Select(range.Start, range.End); }
//...................................................... // // Range Serialization // //...................................................... // Worker for Xml property setter; enables extensibility for TextSelection internal virtual void SetXmlVirtual(TextElement fragment) { if (!this.IsTableCellRange) { TextRangeSerialization.PasteXml(this, fragment); } }
/// <summary> /// Reads a well-formed xml representing a serialized text range. /// It expects a root element xaml:FlowDocument and two range markers /// The result of reading is pasting this text into End position /// of text range. /// </summary> /// <param name="range"> /// TextRange designating the target position for pasting. /// The existing content of a range will be deleted and new content /// will be inserted at the end. /// Resulting locations of Start/End positions depend on their gravities. /// Normally (when gravity=Backward/Forward respectively) the resulting /// range will embrace the inserted content. /// </param> /// <param name="fragment"> /// Represents a portion of xml to insert into the range. /// </param> /// <remarks> /// We are expecting to be called with xmlReader on opening tag /// of root text range element - xaml:FlowDocument. /// Some insignificant stuff may occur before the root though. /// Otherwise exception will be thrown. /// </remarks> internal static void PasteXml(TextRange range, TextElement fragment) { Invariant.Assert(fragment != null); // Check a special case for pasing a single embedded element if (PasteSingleEmbeddedElement(range, fragment)) { // All done. Return successfully. return; } // Set default value for an indicator of whether we need to merge last paragraph or not. // It depends on a state of a range, so do it before emptying the range. AdjustFragmentForTargetRange(fragment, range); // Delete current content of a range if (!range.IsEmpty) { range.Text = String.Empty; } Invariant.Assert(range.IsEmpty, "range must be empty in the beginning of pasting"); // Chek special case of empty pasted fragment if (((ITextPointer)fragment.ContentStart).CompareTo(fragment.ContentEnd) == 0) { // Pasted fragment is empty. Nothing to insert. return; } // Transfer the content from reader to writer and merge elements on both ends PasteTextFragment(fragment, range); }
// Paste flow content into the current text selection // Returns false if pasting was not successful - assuming that the caller will choose another format for pasting private static bool PasteTextElement(TextEditor This, TextElement sectionOrSpan) { bool success = false; This.Selection.BeginChange(); try { ((TextRange)This.Selection).SetXmlVirtual(sectionOrSpan); // Merge new Lists with surrounding Lists. TextRangeEditLists.MergeListsAroundNormalizedPosition((TextPointer)This.Selection.Start); TextRangeEditLists.MergeListsAroundNormalizedPosition((TextPointer)This.Selection.End); // Merge flow direction of the new content if it matches its surroundings. TextRangeEdit.MergeFlowDirection((TextPointer)This.Selection.Start); TextRangeEdit.MergeFlowDirection((TextPointer)This.Selection.End); success = true; } finally { This.Selection.EndChange(); } return success; }
// Applies a whole property bag to a range from start to end to simulate inheritance of this property from source conntext private static void ApplyContextualProperties(TextPointer start, TextPointer end, TextElement propertyBag) { Invariant.Assert(propertyBag.IsEmpty && propertyBag.Parent == null, "propertyBag is supposed to be an empty element outside any tree"); LocalValueEnumerator contextualProperties = propertyBag.GetLocalValueEnumerator(); while (start.CompareTo(end) < 0 && contextualProperties.MoveNext()) { // Note: we repeatedly check for IsEmpty because the selection // may become empty as a result of normalization after formatting // (thai character sequence). LocalValueEntry propertyEntry = contextualProperties.Current; DependencyProperty property = propertyEntry.Property; if (TextSchema.IsCharacterProperty(property) && TextSchema.IsParagraphProperty(property)) { // In case a property is both an Inline and Paragraph property, // propertyBag element type (section or span) decides how it should be applied. if (TextSchema.IsBlock(propertyBag.GetType())) { ApplyContextualProperty(typeof(Block), start, end, property, propertyEntry.Value); } else { ApplyContextualProperty(typeof(Inline), start, end, property, propertyEntry.Value); } } else if (TextSchema.IsCharacterProperty(property)) { ApplyContextualProperty(typeof(Inline), start, end, property, propertyEntry.Value); } else if (TextSchema.IsParagraphProperty(property)) { ApplyContextualProperty(typeof(Block), start, end, property, propertyEntry.Value); } } // Merge formatting elements at end position TextRangeEdit.MergeFormattingInlines(start); TextRangeEdit.MergeFormattingInlines(end); }
//...................................................... // // Range Serialization // //...................................................... // Worker for Xml property setter; enables extensibility for TextSelection internal override void SetXmlVirtual(TextElement fragment) { TextRangeBase.BeginChange(this); try { base.SetXmlVirtual(fragment); this.ClearSpringloadFormatting(); } finally { TextRangeBase.EndChange(this); } }
/// <summary> /// Constructor. /// </summary> /// <param name="block">Block for which MBP properties are retrieved.</param> private MbpInfo(TextElement block) { _margin = (Thickness)block.GetValue(Block.MarginProperty); _border = (Thickness)block.GetValue(Block.BorderThicknessProperty); _padding = (Thickness)block.GetValue(Block.PaddingProperty); _borderBrush = (Brush)block.GetValue(Block.BorderBrushProperty); }
public void ApplyFormatTags(TextElement elem) { var format = new TextFormat(elem); if (mFormatMarkupMapping.ContainsKey(format)) { elem.Tag = mFormatMarkupMapping[format]; } else { foreach (var e in LogicalTreeHelper.GetChildren(elem).OfType<TextElement>()) ApplyFormatTags(e); } }
/// <summary> /// The set style. /// </summary> /// <param name="run"> /// The run. /// </param> /// <param name="s"> /// The s. /// </param> private static void SetStyle(TextElement run, ParagraphStyle s) { run.FontFamily = new FontFamily(s.FontFamily); run.FontSize = s.FontSize; run.FontWeight = s.Bold ? FontWeights.Bold : FontWeights.Normal; FontStyle fontStyle = FontStyles.Normal; if (s.Italic) { fontStyle = FontStyles.Italic; } run.FontStyle = fontStyle; }
/// <summary> /// Paste the content data(Text, Unicode, Xaml and Rtf) to the current text selection /// </summary> /// <param name="This"></param> /// <param name="dataObject"> /// data object containing data to paste /// </param> /// <param name="dataObjectToApply"> /// </param> /// <param name="formatToApply"> /// </param> /// <returns> /// true if successful, false otherwise /// </returns> private static bool PasteContentData(TextEditor This, IDataObject dataObject, IDataObject dataObjectToApply, string formatToApply) { // CF_BITMAP - pasting a single image. if (formatToApply == DataFormats.Bitmap && dataObjectToApply is DataObject) { // This demand is present to explicitly disable RTF independant of any // asserts in the confines of partial trust // We check unmanaged code instead of all clipboard because in paste // there is a high level assert for all clipboard in commandmanager.cs if (This.AcceptsRichContent && This.Selection is TextSelection && SecurityHelper.CheckUnmanagedCodePermission()) { System.Windows.Media.Imaging.BitmapSource bitmapSource = GetPasteData(dataObjectToApply, DataFormats.Bitmap) as System.Windows.Media.Imaging.BitmapSource; if (bitmapSource != null) { // Pack the image into a WPF container MemoryStream packagedImage = WpfPayload.SaveImage(bitmapSource, WpfPayload.ImageBmpContentType); // Place it onto a data object dataObjectToApply = new DataObject(); formatToApply = DataFormats.XamlPackage; dataObjectToApply.SetData(DataFormats.XamlPackage, packagedImage); } } } if (formatToApply == DataFormats.XamlPackage) { // This demand is present to explicitly disable RTF independant of any // asserts in the confines of partial trust // We check unmanaged code instead of all clipboard because in paste // there is a high level assert for all clipboard in commandmanager.cs if (This.AcceptsRichContent && This.Selection is TextSelection && SecurityHelper.CheckUnmanagedCodePermission()) { object pastedData = GetPasteData(dataObjectToApply, DataFormats.XamlPackage); MemoryStream pastedMemoryStream = pastedData as MemoryStream; if (pastedMemoryStream != null) { object element = WpfPayload.LoadElement(pastedMemoryStream); if ((element is Section || element is Span) && PasteTextElement(This, (TextElement)element)) { return(true); } else if (element is FrameworkElement) { ((TextSelection)This.Selection).InsertEmbeddedUIElement((FrameworkElement)element); return(true); } } } // Fall to Xaml: dataObjectToApply = dataObject; // go back to source data object if (dataObjectToApply.GetDataPresent(DataFormats.Xaml)) { formatToApply = DataFormats.Xaml; } else if (SecurityHelper.CheckUnmanagedCodePermission() && dataObjectToApply.GetDataPresent(DataFormats.Rtf)) { formatToApply = DataFormats.Rtf; } else if (dataObjectToApply.GetDataPresent(DataFormats.UnicodeText)) { formatToApply = DataFormats.UnicodeText; } else if (dataObjectToApply.GetDataPresent(DataFormats.Text)) { formatToApply = DataFormats.Text; } } if (formatToApply == DataFormats.Xaml) { if (This.AcceptsRichContent && This.Selection is TextSelection) { object pastedData = GetPasteData(dataObjectToApply, DataFormats.Xaml); if (pastedData != null && PasteXaml(This, pastedData.ToString())) { return(true); } } // Fall to Rtf: dataObjectToApply = dataObject; // go back to source data object if (SecurityHelper.CheckUnmanagedCodePermission() && dataObjectToApply.GetDataPresent(DataFormats.Rtf)) { formatToApply = DataFormats.Rtf; } else if (dataObjectToApply.GetDataPresent(DataFormats.UnicodeText)) { formatToApply = DataFormats.UnicodeText; } else if (dataObjectToApply.GetDataPresent(DataFormats.Text)) { formatToApply = DataFormats.Text; } } if (formatToApply == DataFormats.Rtf) { // This demand is present to explicitly disable RTF independant of any // asserts in the confines of partial trust // We check unmanaged code instead of all clipboard because in paste // there is a high level assert for all clipboard in commandmanager.cs if (This.AcceptsRichContent && SecurityHelper.CheckUnmanagedCodePermission()) { object pastedData = GetPasteData(dataObjectToApply, DataFormats.Rtf); // Convert rtf to xaml text to paste rtf data into the target. if (pastedData != null) { MemoryStream memoryStream = ConvertRtfToXaml(pastedData.ToString()); if (memoryStream != null) { TextElement textElement = WpfPayload.LoadElement(memoryStream) as TextElement; if ((textElement is Section || textElement is Span) && PasteTextElement(This, textElement)) { return(true); } } } } // Fall to plain text: dataObjectToApply = dataObject; // go back to source data object if (dataObjectToApply.GetDataPresent(DataFormats.UnicodeText)) { formatToApply = DataFormats.UnicodeText; } else if (dataObjectToApply.GetDataPresent(DataFormats.Text)) { formatToApply = DataFormats.Text; } } if (formatToApply == DataFormats.UnicodeText) { object pastedData = GetPasteData(dataObjectToApply, DataFormats.UnicodeText); if (pastedData == null) { if (dataObjectToApply.GetDataPresent(DataFormats.Text)) { formatToApply = DataFormats.Text; // fall to plain text dataObjectToApply = dataObject; // go back to source data object } } else { // Dont attempt to recover if pasting Unicode text fails because our only fallback is mbcs text, // which will either evaluate identically (at best) or // produce a string with unexpected text (worse!) from WideCharToMultiByte conversion. return(PastePlainText(This, pastedData.ToString())); } } if (formatToApply == DataFormats.Text) { object pastedData = GetPasteData(dataObjectToApply, DataFormats.Text); if (pastedData != null && PastePlainText(This, pastedData.ToString())) { return(true); } } return(false); }