/// <summary>
        /// Removes an item from a collection and from a tree.
        /// The element removed can be re-inserted later in another collection of a tree.
        /// </summary>
        /// <param name="item"></param>
        /// <returns>
        /// True if removal was successful.
        /// </returns>
        public bool Remove(TextElementType item)
        {
            if (item == null)
            {
                return(false);
            }

            if (item.Parent != this.Parent)
            {
                return(false);
            }

            // Note: We need to remember the textcontainer for any delete operations in this collection.
            // This is important for the case when the owner of the collection is a sibling member.
            // In a scenario where you remove the owner itself from the collection,
            // the owner belongs to another tree after the reposition.

            TextContainer textContainer = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                item.RepositionWithContent(null);
            }
            finally
            {
                textContainer.EndChange();
            }

            return(true);
        }
Beispiel #2
0
        // Token: 0x06003525 RID: 13605 RVA: 0x000F0C7C File Offset: 0x000EEE7C
        private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Run run = (Run)d;

            if (run._changeEventNestingCount > 0)
            {
                return;
            }
            Invariant.Assert(!e.NewEntry.IsDeferredReference);
            string text = (string)e.NewValue;

            if (text == null)
            {
                text = string.Empty;
            }
            run._changeEventNestingCount++;
            try
            {
                TextContainer textContainer = run.TextContainer;
                textContainer.BeginChange();
                try
                {
                    TextPointer contentStart = run.ContentStart;
                    if (!run.IsEmpty)
                    {
                        textContainer.DeleteContentInternal(contentStart, run.ContentEnd);
                    }
                    contentStart.InsertTextInRun(text);
                }
                finally
                {
                    textContainer.EndChange();
                }
            }
            finally
            {
                run._changeEventNestingCount--;
            }
            FlowDocument flowDocument = run.TextContainer.Parent as FlowDocument;

            if (flowDocument != null)
            {
                RichTextBox richTextBox = flowDocument.Parent as RichTextBox;
                if (richTextBox != null && run.HasExpression(run.LookupEntry(Run.TextProperty.GlobalIndex), Run.TextProperty))
                {
                    UndoManager undoManager = richTextBox.TextEditor._GetUndoManager();
                    if (undoManager != null && undoManager.IsEnabled)
                    {
                        undoManager.Clear();
                    }
                }
            }
        }
        //-------------------------------------------------------------------
        //
        //  Private Methods
        //
        //-------------------------------------------------------------------

        #region Private Methods

        // Worker for IList.RemoveAt and IList.set_Item.
        // Returns the element following the element removed.
        private TextElementType RemoveAtInternal(int index)
        {
            if (index < 0)
            {
                throw new IndexOutOfRangeException(SR.Get(SRID.TextElementCollection_IndexOutOfRange));
            }

            TextElementType element = GetElementAtIndex(index);

            if (element == null)
            {
                throw new IndexOutOfRangeException(SR.Get(SRID.TextElementCollection_IndexOutOfRange));
            }

            TextElementType nextElement = (TextElementType)element.NextElement;

            // Note: We need to remember the textcontainer for any delete operations in this collection.
            // This is important for the case when the owner of the collection is a sibling member.
            // In a scenario where you remove the owner itself from the collection,
            // the owner belongs to another tree after the reposition.

            TextContainer textContainer = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                // Prepare to reset the cache.
                // We're about to remove the current cache, so we need to find a neighbor.
                TextElementType newElementCache = nextElement;
                if (newElementCache == null)
                {
                    newElementCache = (TextElementType)element.PreviousElement;
                    index--;
                }

                // Remove the element.
                element.RepositionWithContent(null);

                // Reset the cache.
                if (newElementCache != null)
                {
                    SetCache(index, newElementCache);
                }
            }
            finally
            {
                textContainer.EndChange();
            }

            return(nextElement);
        }
        /// <summary>Clears all items from the collection.</summary>
        // Token: 0x06003979 RID: 14713 RVA: 0x001048F8 File Offset: 0x00102AF8
        public void Clear()
        {
            TextContainer textContainer = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                textContainer.DeleteContentInternal(this.ContentStart, this.ContentEnd);
            }
            finally
            {
                textContainer.EndChange();
            }
        }
        /// <summary>
        /// </summary>
        public void Clear()
        {
            // Note: We need to remember the textcontainer for any delete operations in this collection.
            // This is important for the case when the owner of the collection is a sibling member.
            // In a scenario where you remove the owner itself from the collection,
            // the owner belongs to another tree after the reposition.

            TextContainer textContainer = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                textContainer.DeleteContentInternal(this.ContentStart, this.ContentEnd);
            }
            finally
            {
                textContainer.EndChange();
            }
        }
        // Token: 0x060031BA RID: 12730 RVA: 0x000DBC04 File Offset: 0x000D9E04
        internal void Apply(Block firstBlock, Block lastBlock)
        {
            Invariant.Assert(base.Parent == null, "Cannot Apply List Because It Is Inserted In The Tree Already.");
            Invariant.Assert(base.IsEmpty, "Cannot Apply List Because It Is Not Empty.");
            Invariant.Assert(firstBlock.Parent == lastBlock.Parent, "Cannot Apply List Because Block Are Not Siblings.");
            TextContainer textContainer = base.TextContainer;

            textContainer.BeginChange();
            try
            {
                base.Reposition(firstBlock.ElementStart, lastBlock.ElementEnd);
                ListItem listItem;
                for (Block block = firstBlock; block != null; block = ((block == lastBlock) ? null : ((Block)listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward))))
                {
                    if (block is List)
                    {
                        listItem = (block.ElementStart.GetAdjacentElement(LogicalDirection.Backward) as ListItem);
                        if (listItem != null)
                        {
                            listItem.Reposition(listItem.ContentStart, block.ElementEnd);
                        }
                        else
                        {
                            listItem = new ListItem();
                            listItem.Reposition(block.ElementStart, block.ElementEnd);
                        }
                    }
                    else
                    {
                        listItem = new ListItem();
                        listItem.Reposition(block.ElementStart, block.ElementEnd);
                        block.ClearValue(Block.MarginProperty);
                        block.ClearValue(Block.PaddingProperty);
                        block.ClearValue(Paragraph.TextIndentProperty);
                    }
                }
                TextRangeEdit.SetParagraphProperty(base.ElementStart, base.ElementEnd, Block.FlowDirectionProperty, firstBlock.GetValue(Block.FlowDirectionProperty));
            }
            finally
            {
                textContainer.EndChange();
            }
        }
Beispiel #7
0
        private void UpdateText(string text)
        {
            if (text == null)
            {
                text = string.Empty;
            }

            _accessKeyLocated = false;
            _accessKey        = null;
            TextContainer.BeginChange();
            try
            {
                TextContainer.DeleteContentInternal((TextPointer)TextContainer.Start, TextContainer.End);
                Run run = Inline.CreateImplicitRun(this);
                ((TextPointer)TextContainer.End).InsertTextElement(run);
                run.Text = text;
            }
            finally
            {
                TextContainer.EndChange();
            }
        }
        /// <summary>Removes a specified item from the collection.</summary>
        /// <param name="item">An item to be removed fro the collection.</param>
        /// <returns>
        ///     true if the specified item was found and removed; otherwise, false.</returns>
        // Token: 0x0600397E RID: 14718 RVA: 0x001049F4 File Offset: 0x00102BF4
        public bool Remove(TextElementType item)
        {
            if (item == null)
            {
                return(false);
            }
            if (item.Parent != this.Parent)
            {
                return(false);
            }
            TextContainer textContainer = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                item.RepositionWithContent(null);
            }
            finally
            {
                textContainer.EndChange();
            }
            return(true);
        }
        // Token: 0x06003999 RID: 14745 RVA: 0x001052EC File Offset: 0x001034EC
        private TextElementType RemoveAtInternal(int index)
        {
            if (index < 0)
            {
                throw new IndexOutOfRangeException(SR.Get("TextElementCollection_IndexOutOfRange"));
            }
            TextElementType elementAtIndex = this.GetElementAtIndex(index);

            if (elementAtIndex == null)
            {
                throw new IndexOutOfRangeException(SR.Get("TextElementCollection_IndexOutOfRange"));
            }
            TextElementType textElementType = (TextElementType)((object)elementAtIndex.NextElement);
            TextContainer   textContainer   = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                TextElementType textElementType2 = textElementType;
                if (textElementType2 == null)
                {
                    textElementType2 = (TextElementType)((object)elementAtIndex.PreviousElement);
                    index--;
                }
                elementAtIndex.RepositionWithContent(null);
                if (textElementType2 != null)
                {
                    this.SetCache(index, textElementType2);
                }
            }
            finally
            {
                textContainer.EndChange();
            }
            return(textElementType);
        }
Beispiel #10
0
        //-------------------------------------------------------------------
        //
        // Private Methods
        //
        //-------------------------------------------------------------------

        #region Private Methods

        /// <summary>
        /// Changed handler for the Text property.
        /// </summary>
        /// <param name="d">The source of the event.</param>
        /// <param name="e">A PropertyChangedEventArgs that contains the event data.</param>
        /// <remarks>
        /// We can't assume the value is a string here -- it may be a DeferredRunTextReference.
        /// </remarks>
        private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Run run = (Run)d;

            // Return if this update was caused by a TextContainer change or a reentrant change.
            if (run._changeEventNestingCount > 0)
            {
                return;
            }

            Invariant.Assert(!e.NewEntry.IsDeferredReference);

            // CoerceText will have already converted null -> String.Empty, but our default
            // CoerceValueCallback could be overridden by a derived class.  So check again here.
            string newText = (string)e.NewValue;

            if (newText == null)
            {
                newText = String.Empty;
            }

            // Run.TextProperty has changed. Update the backing store.
            run._changeEventNestingCount++;
            try
            {
                TextContainer textContainer = run.TextContainer;
                textContainer.BeginChange();

                try
                {
                    TextPointer contentStart = run.ContentStart;
                    if (!run.IsEmpty)
                    {
                        textContainer.DeleteContentInternal(contentStart, run.ContentEnd);
                    }
                    contentStart.InsertTextInRun(newText);
                }
                finally
                {
                    textContainer.EndChange();
                }
            }
            finally
            {
                run._changeEventNestingCount--;
            }

            // We need to clear undo stack if we are in a RichTextBox and the value comes from
            // data binding or some other expression.
            FlowDocument document = run.TextContainer.Parent as FlowDocument;

            if (document != null)
            {
                RichTextBox rtb = document.Parent as RichTextBox;
                if (rtb != null && run.HasExpression(run.LookupEntry(Run.TextProperty.GlobalIndex), Run.TextProperty))
                {
                    UndoManager undoManager = rtb.TextEditor._GetUndoManager();
                    if (undoManager != null && undoManager.IsEnabled)
                    {
                        undoManager.Clear();
                    }
                }
            }
        }
        /// <summary>
        /// Inserts a List around a sequence of Blocks
        /// starting from firstBlock ending with lastBlock.
        /// the List must be empty and not inserted in a tree
        /// before the operation
        /// </summary>
        /// <param name="firstBlock"></param>
        /// <param name="lastBlock"></param>
        internal void Apply(Block firstBlock, Block lastBlock)
        {
            Invariant.Assert(this.Parent == null, "Cannot Apply List Because It Is Inserted In The Tree Already.");
            Invariant.Assert(this.IsEmpty, "Cannot Apply List Because It Is Not Empty.");
            Invariant.Assert(firstBlock.Parent == lastBlock.Parent, "Cannot Apply List Because Block Are Not Siblings.");

            TextContainer textContainer = this.TextContainer;

            textContainer.BeginChange();
            try
            {
                // Wrap all block items into this List element
                this.Reposition(firstBlock.ElementStart, lastBlock.ElementEnd);

                // Add ListItem elements
                Block block = firstBlock;
                while (block != null)
                {
                    ListItem listItem;
                    if (block is List)
                    {
                        // To wrap List into list item we pull it into previous ListItem (if any) as sublist
                        listItem = block.ElementStart.GetAdjacentElement(LogicalDirection.Backward) as ListItem;
                        if (listItem != null)
                        {
                            // Wrap the List into preceding ListItem
                            listItem.Reposition(listItem.ContentStart, block.ElementEnd);
                        }
                        else
                        {
                            // No preceding ListItem. Create new one
                            listItem = new ListItem();
                            listItem.Reposition(block.ElementStart, block.ElementEnd);
                        }
                    }
                    else
                    {
                        // To wrap paragraph into list item we need to create a new one
                        //
                        listItem = new ListItem();
                        listItem.Reposition(block.ElementStart, block.ElementEnd);

                        // MS Word-like heuristic: clear margin from a paragraph before wrapping it into a list item
                        // Note: using TextContainer to make sure that undo unit is created.
                        block.ClearValue(Block.MarginProperty);
                        block.ClearValue(Block.PaddingProperty);
                        block.ClearValue(Paragraph.TextIndentProperty);
                    }

                    // Stop when the last paragraph is covered
                    block = block == lastBlock ? null : (Block)listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward);
                }

                // We need to set appropriate FlowDirection property on the new List and its paragraph children.
                // We take the FlowDirection value from the first paragraph's FlowDirection value.

                TextRangeEdit.SetParagraphProperty(this.ElementStart, this.ElementEnd,
                                                   Paragraph.FlowDirectionProperty, firstBlock.GetValue(Paragraph.FlowDirectionProperty));
            }
            finally
            {
                textContainer.EndChange();
            }
        }
Beispiel #12
0
        /// <summary>
        /// UpdateAccessKey - Scans forward in the tree looking for the access key marker, replacing it with access key element. We only support one find.
        /// </summary>
        private void UpdateAccessKey()
        {
            TextPointer navigator = new TextPointer(TextContainer.Start);

            while (!_accessKeyLocated && navigator.CompareTo(TextContainer.End) < 0)
            {
                TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);
                switch (symbolType)
                {
                case TextPointerContext.Text:
                    string text  = navigator.GetTextInRun(LogicalDirection.Forward);
                    int    index = FindAccessKeyMarker(text);
                    if (index != -1 && index < text.Length - 1)
                    {
                        string      keyText = StringInfo.GetNextTextElement(text, index + 1);
                        TextPointer keyEnd  = navigator.GetPositionAtOffset(index + 1 + keyText.Length);

                        _accessKey       = new Run(keyText);
                        _accessKey.Style = AccessKeyStyle;

                        RegisterAccessKey();

                        HasCustomSerializationStorage.SetValue(_accessKey, true);
                        _accessKeyLocated = true;

                        UninitializeTextContainerListener();

                        TextContainer.BeginChange();
                        try
                        {
                            TextPointer underlineStart = new TextPointer(navigator, index);
                            TextRangeEdit.DeleteInlineContent(underlineStart, keyEnd);
                            _accessKey.RepositionWithContent(underlineStart);
                        }
                        finally
                        {
                            TextContainer.EndChange();
                            InitializeTextContainerListener();
                        }
                    }

                    break;
                }
                navigator.MoveToNextContextPosition(LogicalDirection.Forward);
            }

            // Convert double _ to single _
            navigator = new TextPointer(TextContainer.Start);
            string accessKeyMarker       = AccessKeyMarker.ToString();
            string doubleAccessKeyMarker = accessKeyMarker + accessKeyMarker;

            while (navigator.CompareTo(TextContainer.End) < 0)
            {
                TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);
                switch (symbolType)
                {
                case TextPointerContext.Text:
                    string text    = navigator.GetTextInRun(LogicalDirection.Forward);
                    string nexText = text.Replace(doubleAccessKeyMarker, accessKeyMarker);
                    if (text != nexText)
                    {
                        TextPointer keyStart = new TextPointer(navigator, 0);
                        TextPointer keyEnd   = new TextPointer(navigator, text.Length);

                        UninitializeTextContainerListener();
                        TextContainer.BeginChange();
                        try
                        {
                            keyEnd.InsertTextInRun(nexText);
                            TextRangeEdit.DeleteInlineContent(keyStart, keyEnd);
                        }
                        finally
                        {
                            TextContainer.EndChange();
                            InitializeTextContainerListener();
                        }
                    }

                    break;
                }
                navigator.MoveToNextContextPosition(LogicalDirection.Forward);
            }
        }