Highlights.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Documents / Highlights.cs / 1305600 / Highlights.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: Text highlights associated with a TextContainer. 
//
// History: 
//  7/1/2004 : [....] - Created.
//
//---------------------------------------------------------------------------
 
using System.Collections;
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using MS.Internal;
 
namespace System.Windows.Documents
{
    /// 
    /// Text highlights associated with a TextContainer. 
    /// 
    internal class Highlights 
    { 
        //-----------------------------------------------------
        // 
        //  Constructors
        //
        //-----------------------------------------------------
 
        #region Constructors
 
        // Constructor. 
        internal Highlights(ITextContainer textContainer)
        { 
            _textContainer = textContainer;
        }

        #endregion Constructors 

        //------------------------------------------------------ 
        // 
        //  Internal Methods
        // 
        //-----------------------------------------------------

        #region Internal Methods
 
        /// 
        /// Returns the value of a property stored on scoping highlight, if any. 
        ///  
        /// 
        /// Position to query. 
        /// 
        /// 
        /// Direction of content to query.
        ///  
        /// 
        /// Type of the matching highlight layer owner. 
        ///  
        /// 
        /// The highlight value if set on any scoping highlight.  If no property 
        /// value is set, returns DependencyProperty.UnsetValue.
        /// 
        internal virtual object GetHighlightValue(StaticTextPointer textPosition, LogicalDirection direction, Type highlightLayerOwnerType)
        { 
            int layerIndex;
            object value; 
            HighlightLayer layer; 

            value = DependencyProperty.UnsetValue; 

            // Take the value on the closest layer.  "Closest" == added first.
            for (layerIndex = 0; layerIndex < this.LayerCount; layerIndex++)
            { 
                layer = GetLayer(layerIndex);
 
                if (layer.OwnerType == highlightLayerOwnerType) 
                {
                    value = layer.GetHighlightValue(textPosition, direction); 
                    if (value != DependencyProperty.UnsetValue)
                        break;
                }
            } 

            return value; 
        } 

        ///  
        /// Returns true iff the indicated content has scoping highlights.
        /// 
        /// 
        /// Position to query. 
        /// 
        ///  
        /// Direction of content to query. 
        /// 
        internal virtual bool IsContentHighlighted(StaticTextPointer textPosition, LogicalDirection direction) 
        {
            int i;

            for (i = 0; i < this.LayerCount; i++) 
            {
                if (GetLayer(i).IsContentHighlighted(textPosition, direction)) 
                { 
                    break;
                } 
            }

            return (i < this.LayerCount);
        } 

        ///  
        /// Returns the position of the next highlight start or end in an 
        /// indicated direction, or null if there is no such position.
        ///  
        /// 
        /// Position to query.
        /// 
        ///  
        /// Direction of content to query.
        ///  
        internal virtual StaticTextPointer GetNextHighlightChangePosition(StaticTextPointer textPosition, LogicalDirection direction) 
        {
            StaticTextPointer changePosition; 
            StaticTextPointer closestChangePosition;
            int i;

            closestChangePosition = StaticTextPointer.Null; 

            // Calculate the min of the layers' transitions. 
            for (i = 0; i < this.LayerCount; i++) 
            {
                changePosition = GetLayer(i).GetNextChangePosition(textPosition, direction); 

                if (!changePosition.IsNull)
                {
                    if (closestChangePosition.IsNull) 
                    {
                        closestChangePosition = changePosition; 
                    } 
                    else if (direction == LogicalDirection.Forward)
                    { 
                        closestChangePosition = StaticTextPointer.Min(closestChangePosition, changePosition);
                    }
                    else
                    { 
                        closestChangePosition = StaticTextPointer.Max(closestChangePosition, changePosition);
                    } 
                } 
            }
 
            return closestChangePosition;
        }

        ///  
        /// Returns the closest neighboring TextPointer in an indicated
        /// direction where a property value calculated from an embedded 
        /// object, scoping text element, or scoping highlight could 
        /// change.
        ///  
        /// 
        /// Position to query.
        /// 
        ///  
        /// Direction of content to query.
        ///  
        ///  
        /// If the following symbol is TextPointerContext.EmbeddedElement,
        /// TextPointerContext.ElementBegin, or TextPointerContext.ElementEnd, returns 
        /// a TextPointer exactly one symbol distant.
        ///
        /// If the following symbol is TextPointerContext.Text, the distance
        /// of the returned TextPointer is the minimum of the value returned 
        /// by textPosition.GetTextLength and the distance to any highlight
        /// start or end edge. 
        /// 
        /// If the following symbol is TextPointerContext.None, returns null.
        ///  
        internal virtual StaticTextPointer GetNextPropertyChangePosition(StaticTextPointer textPosition, LogicalDirection direction)
        {
            StaticTextPointer changePosition;
            StaticTextPointer characterRunEndPosition; 

            switch (textPosition.GetPointerContext(direction)) 
            { 
                case TextPointerContext.None:
                    changePosition = StaticTextPointer.Null; 
                    break;

                case TextPointerContext.Text:
                    changePosition = GetNextHighlightChangePosition(textPosition, direction); 
                    characterRunEndPosition = textPosition.GetNextContextPosition(LogicalDirection.Forward);
 
                    if (changePosition.IsNull || 
                        characterRunEndPosition.CompareTo(changePosition) < 0)
                    { 
                        changePosition = characterRunEndPosition;
                    }

                    break; 

                case TextPointerContext.EmbeddedElement: 
                case TextPointerContext.ElementStart: 
                case TextPointerContext.ElementEnd:
                default: 
                    changePosition = textPosition.CreatePointer(+1);
                    break;
            }
 
            return changePosition;
        } 
 
        /// 
        /// Adds a HighlightLayer to this collection. 
        /// 
        /// 
        /// HighlightLayer to add.
        ///  
        internal void AddLayer(HighlightLayer highlightLayer)
        { 
            // Delay alloc the layers store. 
            if (_layers == null)
            { 
                _layers = new ArrayList(1);
            }

            Invariant.Assert(!_layers.Contains(highlightLayer)); 

            _layers.Add(highlightLayer); 
 
            highlightLayer.Changed += new HighlightChangedEventHandler(OnLayerChanged);
 
            // Raise initial change event to cover existing content.
            RaiseChangedEventForLayerContent(highlightLayer);
        }
 
        /// 
        /// Removes a HighlightLayer to this collection. 
        ///  
        /// 
        /// HighlightLayer to add. 
        /// 
        internal void RemoveLayer(HighlightLayer highlightLayer)
        {
            Invariant.Assert(_layers != null && _layers.Contains(highlightLayer)); 

            // Raise final change event to cover existing content. 
            RaiseChangedEventForLayerContent(highlightLayer); 

            highlightLayer.Changed -= new HighlightChangedEventHandler(OnLayerChanged); 

            _layers.Remove(highlightLayer);
        }
 

        ///  
        /// Retrieve a HighlightLayer from this collection 
        /// 
        ///  
        /// 
        /// 
        /// The first added HighlightLayer owned by the type.
        /// null if no such HighlightLayer can be found. 
        /// 
        internal HighlightLayer GetLayer(Type highlightLayerType) 
        { 
            int i;
 
            for (i = 0; i < this.LayerCount; i++)
            {
                if (highlightLayerType == GetLayer(i).OwnerType)
                { 
                    return GetLayer(i);
                } 
            } 
            return null;
        } 
        #endregion Internal Methods

        //------------------------------------------------------
        // 
        //  Protected Properties
        // 
        //------------------------------------------------------ 

        #region Protected Properties 

        protected ITextContainer TextContainer
        {
            get 
            {
                return _textContainer; 
            } 
        }
 
        #endregion Protected Properties

        //-----------------------------------------------------
        // 
        //  Internal Events
        // 
        //------------------------------------------------------ 

        #region Internal Events 

        /// 
        /// Event raised when a highlight is inserted, removed, moved, or
        /// has a local property value change. 
        /// 
        internal event HighlightChangedEventHandler Changed; 
 
        #endregion Internal Events
 
        //-----------------------------------------------------
        //
        //  Private Methods
        // 
        //-----------------------------------------------------
 
        #region Private Methods 

        // Returns a contained HighlightLayer. 
        private HighlightLayer GetLayer(int index)
        {
            return (HighlightLayer)_layers[index];
        } 

        // Callback for changes on a single layer. 
        private void OnLayerChanged(object sender, HighlightChangedEventArgs args) 
        {
            // Forward on the event to any listeners. 
            if (this.Changed != null)
            {
                Changed(this, args);
            } 
        }
 
        // Raises initial or final change event for added/removed layers. 
        private void RaiseChangedEventForLayerContent(HighlightLayer highlightLayer)
        { 
            List ranges;
            StaticTextPointer highlightTransitionPosition;
            StaticTextPointer highlightRangeStart;
 
            if (this.Changed != null)
            { 
                // Build a list of all highlights in this layer -- they're all 
                // going to "change" as the layer is added/removed.
 
                ranges = new List();

                highlightTransitionPosition = _textContainer.CreateStaticPointerAtOffset(0);
 
                while (true)
                { 
                    // Move to the next highlight start. 
                    if (!highlightLayer.IsContentHighlighted(highlightTransitionPosition, LogicalDirection.Forward))
                    { 
                        highlightTransitionPosition = highlightLayer.GetNextChangePosition(highlightTransitionPosition, LogicalDirection.Forward);

                        // No more highlights?
                        if (highlightTransitionPosition.IsNull) 
                            break;
                    } 
 
                    highlightRangeStart = highlightTransitionPosition;
                    highlightTransitionPosition = highlightLayer.GetNextChangePosition(highlightTransitionPosition, LogicalDirection.Forward); 
                    Invariant.Assert(!highlightTransitionPosition.IsNull, "Highlight start not followed by highlight end!");

                    ranges.Add(new TextSegment(highlightRangeStart.CreateDynamicTextPointer(LogicalDirection.Forward), highlightTransitionPosition.CreateDynamicTextPointer(LogicalDirection.Forward)));
                } 

                if (ranges.Count > 0) 
                { 
                    Changed(this, new LayerHighlightChangedEventArgs(new ReadOnlyCollection(ranges), highlightLayer.OwnerType));
                } 
            }
        }

        #endregion Private Methods 

        //----------------------------------------------------- 
        // 
        //  Private Properties
        // 
        //------------------------------------------------------

        #region Private Properties
 
        // Count of contained HighlightLayers.
        private int LayerCount 
        { 
            get
            { 
                return (_layers == null) ? 0 : _layers.Count;
            }
        }
 
        #endregion Private Properties
 
        //----------------------------------------------------- 
        //
        //  Private Types 
        //
        //------------------------------------------------------

        #region Private Types 

        // EventArgs for the Changed event. 
        private class LayerHighlightChangedEventArgs : HighlightChangedEventArgs 
        {
            // Constructor. 
            internal LayerHighlightChangedEventArgs(ReadOnlyCollection ranges, Type ownerType)
            {
                _ranges = ranges;
                _ownerType = ownerType; 
            }
 
            // List of changed ranges. 
            internal override IList Ranges
            { 
                get
                {
                    return _ranges;
                } 
            }
 
            // Type identifying the owner of the changed layer. 
            internal override Type OwnerType
            { 
                get
                {
                    return _ownerType;
                } 
            }
 
            // List of changed ranges. 
            private readonly ReadOnlyCollection _ranges;
 
            // Type identifying the owner of the changed layer.
            private readonly Type _ownerType;
        }
 
        #endregion Private Types
 
        //------------------------------------------------------ 
        //
        //  Private Fields 
        //
        //-----------------------------------------------------

        #region Private Fields 

        // Associated TextContainer. 
        private readonly ITextContainer _textContainer; 

        // List of contained HighlightLayers. 
        private ArrayList _layers;

        #endregion Private Fields
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK