Наследование: System.Windows.FrameworkContentElement, System.Windows.Markup.IAddChild
Пример #1
0
        // 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);
        }
Пример #2
0
		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));
        }
Пример #4
0
        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;
            }
        }
Пример #5
0
 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);
 }
Пример #6
0
        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 + "]";
            }
        }
Пример #7
0
        // ------------------------------------------------------------------- 
        // 
        // 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;
        } 
Пример #8
0
        private TreeViewItem AddNodeToTreeview(ItemsControl parent, SysDoc.TextElement header)
        {
            var item = new TreeViewItem()
            {
                Header = header
            };

            parent.Items.Add(item);
            item.IsExpanded = true;
            return(item);
        }
Пример #9
0
 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);
     }
 }
Пример #10
0
 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);
     }
 }
Пример #11
0
        // 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));
        }
Пример #12
0
 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;
     }
 }
Пример #13
0
 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);
            }
        }
Пример #18
0
 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);
            }
        }
Пример #20
0
 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);
        }
Пример #22
0
        // --------------------------------------------------------------------
        //
        // 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);
        }
Пример #23
0
        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);
        }
Пример #24
0
        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));
 }
Пример #26
0
 internal static bool IsValidChild(TextElement parent, TextElement child)
 {
     return(ValidateChild(parent, child, false /* throwIfIllegalChild */, false /* throwIfIllegalHyperlinkDescendent */));
 }
Пример #27
0
 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;
        }
Пример #33
0
        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);
        }
Пример #35
0
        //......................................................
        //
        //  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);
        }
Пример #39
0
        //......................................................
        //
        //  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);
            }
        }
Пример #40
0
 /// <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;
        }
Пример #43
0
        /// <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);
        }