documentsequencetextview.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 / documentsequencetextview.cs / 1305600 / documentsequencetextview.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//      DocumentSequenceTextView implements TextView for DocumentSequence
//      to support text editing (e.g Selection). 
//
// History:
//  07/20/2004 : zhenbinx - Created
// 
//---------------------------------------------------------------------------
 
namespace System.Windows.Documents 
{
    using MS.Internal.Documents; 
    using MS.Internal;
    using MS.Utility;
    using System;
    using System.Collections; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Diagnostics; 
    using System.Windows;
    using System.Windows.Media; 
    using System.Windows.Shapes;


    ///  
    /// DocumentSequenceTextView implements TextView for DocumentSequence
    /// to support text editing (e.g Selection). 
    ///  
    internal sealed class DocumentSequenceTextView : TextViewBase
    { 
        //-----------------------------------------------------
        //
        //  Constructors
        // 
        //-----------------------------------------------------
 
        #region Constructors 

        ///  
        /// Constructor.
        /// 
        internal DocumentSequenceTextView(FixedDocumentSequenceDocumentPage docPage)
        { 
            _docPage = docPage;
        } 
 
        #endregion Constructors
 
        //------------------------------------------------------
        //
        //  Internal Methods
        // 
        //-----------------------------------------------------
 
        #region Internal Methods 

        ///  
        /// Retrieves a position matching a point.
        /// 
        /// 
        /// Point in pixel coordinates to test. 
        /// 
        ///  
        /// If true, this method must always return a positioned text position 
        /// (the closest position as calculated by the control's heuristics).
        /// If false, this method should return null position, if the test 
        /// point does not fall within any character bounding box.
        /// 
        /// 
        /// A text position and its orientation matching or closest to the point. 
        /// 
        ///  
        /// Throws InvalidOperationException if IsValid is false. 
        /// If IsValid returns false, Validate method must be called before
        /// calling this method. 
        /// 
        internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText)
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetTextPositionFromPoint {0}-{1}", point, snapToText)); 
            DocumentSequenceTextPointer tp = null;
            LogicalDirection edge = LogicalDirection.Forward; 
 
            if (ChildTextView != null)
            { 
                ITextPointer childOTP = ChildTextView.GetTextPositionFromPoint(point, snapToText);
                if (childOTP != null)
                {
                    tp = new DocumentSequenceTextPointer(ChildBlock, childOTP); 
                    edge = childOTP.LogicalDirection;
                } 
            } 

            // When snapToText is true, ChildTextView.GetTextPositionFromPoint will guranttee to 
            // return a non-null position.
            // In current code, ChildTextView can't be null.
            return tp == null ? null : DocumentSequenceTextPointer.CreatePointer(tp, edge);
        } 

        ///  
        /// Retrieves the height and offset, in pixels, of the edge of 
        /// the object/character represented by position.
        ///  
        /// 
        /// Position of an object/character.
        /// 
        ///  
        /// Transform to be applied to returned rect
        ///  
        ///  
        /// The height, in pixels, of the edge of the object/character
        /// represented by position. 
        /// 
        /// 
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        ///  
        ///  
        /// Rect.Width is always 0.
        /// 
        /// If the document is empty, then this method returns the expected
        /// height of a character, if placed at the specified position.
        /// 
        internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform) 
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetRawRectangleFromTextPosition {0} {1}", position, position.LogicalDirection)); 
            DocumentSequenceTextPointer tp = null; 

            // Initialize transform to identity 
            transform = Transform.Identity;

            if (position != null)
            { 
                 tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
            } 
 
            if (tp != null)
            { 
                if (ChildTextView != null)
                {
                    if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
                    { 
                        return ChildTextView.GetRawRectangleFromTextPosition(tp.ChildPointer.CreatePointer(position.LogicalDirection), out transform);
                    } 
                } 
            }
            return Rect.Empty; 
        }

        /// 
        ///  
        /// 
        internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) 
        { 
            if (startPosition != null && endPosition != null && ChildTextView != null)
            { 
                DocumentSequenceTextPointer startTp = null;
                DocumentSequenceTextPointer endTp = null;

                startTp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(startPosition); 
                endTp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(endPosition);
 
                if (startTp != null && endTp != null) 
                {
                    return ChildTextView.GetTightBoundingGeometryFromTextPositions(startTp.ChildPointer, endTp.ChildPointer); 
                }
            }

            return (new PathGeometry());; 
        }
 
        ///  
        /// Retrieves an oriented text position matching position advanced by
        /// a number of lines from its initial position. 
        /// 
        /// 
        /// Initial text position of an object/character.
        ///  
        /// 
        /// The suggested X offset, in pixels, of text position on the destination 
        /// line. If suggestedX is set to Double.NaN it will be ignored, otherwise 
        /// the method will try to find a position on the destination line closest
        /// to suggestedX. 
        /// 
        /// 
        /// Number of lines to advance. Negative means move backwards.
        ///  
        /// 
        /// newSuggestedX is the offset at the position moved (useful when moving 
        /// between columns or pages). 
        /// 
        ///  
        /// linesMoved indicates the number of lines moved, which may be less
        /// than count if there is no more content.
        /// 
        ///  
        /// A TextPointer and its orientation matching suggestedX on the
        /// destination line. 
        ///  
        /// 
        /// Throws InvalidOperationException if IsValid is false. 
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// 
        internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved) 
        {
            newSuggestedX = suggestedX; 
            linesMoved = count; 

            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetPositionAtNextLine {0} {1} {2} {3} ", position, position.LogicalDirection, suggestedX, count)); 
            DocumentSequenceTextPointer newTp  = null;
            LogicalDirection newEdge = LogicalDirection.Forward;
            DocumentSequenceTextPointer tp = null;
            if (position != null) 
            {
                tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position); 
            } 

            // Note we do not handle cross page navigation 
            if (tp != null)
            {
                if (ChildTextView != null)
                { 
                    if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
                    { 
                        ITextPointer childOTP = ChildTextView.GetPositionAtNextLine(tp.ChildPointer.CreatePointer(position.LogicalDirection), suggestedX, count, out newSuggestedX, out linesMoved); 
                        if (childOTP != null)
                        { 
                            newTp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
                            newEdge = childOTP.LogicalDirection;
                        }
                    } 
                }
            } 
            return DocumentSequenceTextPointer.CreatePointer(newTp, newEdge); 
        }
 
        /// 
        /// Determines if a position is located between two caret units.
        /// 
        ///  
        /// Position to test.
        ///  
        ///  
        /// Returns true if the specified position precedes or follows
        /// the first or last code point of a caret unit, respectively. 
        /// 
        /// 
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        ///  
        ///  
        /// In the context of this method, "caret unit" refers to a group
        /// of one or more Unicode code points that map to a single rendered 
        /// glyph.
        /// 
        internal override bool IsAtCaretUnitBoundary(ITextPointer position)
        { 
            Invariant.Assert(position != null);
            if (position == null) 
            { 
                throw new ArgumentNullException("position");
            } 

            //Verify the position and propagate the call to the child text view
            Invariant.Assert(ChildTextView != null);
            DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position); 

            return this.ChildTextView.IsAtCaretUnitBoundary(ftp.ChildPointer); 
        } 

        ///  
        /// Finds the next position at the edge of a caret unit in
        /// specified direction.
        /// 
        ///  
        /// Initial text position of an object/character.
        ///  
        ///  
        /// If Forward, this method returns the "caret unit" position following
        /// the initial position. 
        /// If Backward, this method returns the caret unit" position preceding
        /// the initial position.
        /// 
        ///  
        /// The next caret unit break position in specified direction.
        ///  
        ///  
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        /// 
        /// 
        /// In the context of this method, "caret unit" refers to a group of one 
        /// or more Unicode code points that map to a single rendered glyph.
        /// 
        /// If position is located between two caret units, this method returns 
        /// a new position located at the opposite edge of the caret unit in
        /// the indicated direction. 
        /// If position is located within a group of Unicode code points that map
        /// to a single caret unit, this method returns a new position at
        /// the indicated edge of the containing caret unit.
        /// If position is located at the beginning of end of content -- there is 
        /// no content in the indicated direction -- then this method returns
        /// a position located at the same location as initial position. 
        ///  
        internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        { 
            Invariant.Assert(position != null);
            if (position == null)
            {
                throw new ArgumentNullException("position"); 
            }
 
            //Verify the position and propagate the call to the child text view 
            Invariant.Assert(ChildTextView != null);
            DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position); 

            return this.ChildTextView.GetNextCaretUnitPosition(ftp.ChildPointer, direction);
        }
 
        /// 
        /// Finds the previous position at the edge of a caret after backspacing. 
        ///  
        /// 
        /// Initial text position of an object/character. 
        /// 
        /// 
        /// The previous caret unit break position after backspacing.
        ///  
        /// 
        /// Throws InvalidOperationException if IsValid is false. 
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        ///  
        internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
        {
            Invariant.Assert(position != null);
            if (position == null) 
            {
                throw new ArgumentNullException("position"); 
            } 

            //Verify the position and propagate the call to the child text view 
            Invariant.Assert(ChildTextView != null);
            DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);

            return this.ChildTextView.GetBackspaceCaretUnitPosition(ftp.ChildPointer); 
        }
 
        ///  
        /// Returns a TextSegment that spans the line on which position is located.
        ///  
        /// 
        /// Any oriented text position on the line.
        /// 
        ///  
        /// TextSegment that spans the line on which position is located.
        ///  
        ///  
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        /// 
        internal override TextSegment GetLineRange(ITextPointer position)
        { 
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetLineRange {0} {1}", position, position.LogicalDirection));
            DocumentSequenceTextPointer tpStart = null; 
            DocumentSequenceTextPointer tpEnd   = null; 
            DocumentSequenceTextPointer tpLine = null;
 
            if (position != null)
            {
                if (ChildTextView != null)
                { 
                    tpLine = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
 
                    if (ChildTextView.TextContainer == tpLine.ChildBlock.ChildContainer) 
                    {
                        TextSegment childTR = ChildTextView.GetLineRange(tpLine.ChildPointer.CreatePointer(position.LogicalDirection)); 
                        if (!childTR.IsNull)
                        {
                            tpStart = new DocumentSequenceTextPointer(ChildBlock, childTR.Start);
                            tpEnd = new DocumentSequenceTextPointer(ChildBlock, childTR.End); 
                            return new TextSegment(tpStart, tpEnd, true);
                        } 
                    } 
                }
            } 
            return TextSegment.Null;
        }

        ///  
        /// Provides a collection of glyph properties corresponding to runs
        /// of Unicode code points. 
        ///  
        /// 
        /// A position preceding the first code point to examine. 
        /// 
        /// 
        /// A position following the last code point to examine.
        ///  
        /// 
        /// A collection of glyph property runs. 
        ///  
        /// 
        /// Throws InvalidOperationException if IsValid is false. 
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// 
        ///  
        /// A "glyph" in this context is the lowest level rendered representation
        /// of text.  Each entry in the output array describes a constant run of 
        /// properties on the glyphs corresponding to a range of Unicode code points. 
        /// With this array, it's possible to enumerate the glpyh properties for
        /// each code point in the specified text run. 
        /// 
        internal override  ReadOnlyCollection GetGlyphRuns(ITextPointer start, ITextPointer end)
        {
            throw new NotImplementedException(); 
        }
 
        ///  
        /// Determines whenever TextView contains specified position.
        ///  
        /// 
        /// A position to test.
        /// 
        ///  
        /// True if TextView contains specified text position.
        /// Otherwise returns false. 
        ///  
        /// 
        /// Throws InvalidOperationException if IsValid is false. 
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// 
        internal override bool Contains(ITextPointer position) 
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("Contains {0} {1}", position, position.LogicalDirection)); 
            DocumentSequenceTextPointer tp = null; 
            if (position != null)
            { 
                tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
            }

            // Note we do not handle cross page navigation 
            if (tp != null)
            { 
                if (ChildTextView != null) 
                {
                    if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer) 
                    {
                        return ChildTextView.Contains(tp.ChildPointer.CreatePointer(position.LogicalDirection));
                    }
                } 
            }
            return false; 
        } 

        ///  
        /// Makes sure that TextView is in a clean layout state and it is
        /// possible to retrieve layout related data.
        /// 
        ///  
        /// If IsValid returns false, it is required to call this method
        /// before calling any other method on TextView. 
        /// Validate method might be very expensive, because it may lead 
        /// to full layout update.
        ///  
        internal override bool Validate()
        {
            if (ChildTextView != null)
            { 
                ChildTextView.Validate();
            } 
 
            return ((ITextView)this).IsValid;
        } 

        /// 
        internal override bool Validate(Point point)
        { 
            if (ChildTextView != null)
            { 
                ChildTextView.Validate(point); 
            }
 
            return ((ITextView)this).IsValid;
        }

        #endregion Internal Methods 

        //------------------------------------------------------ 
        // 
        //  Internal Properties
        // 
        //------------------------------------------------------

        #region Internal Properties
 
        /// 
        ///  
        internal override UIElement RenderScope 
        {
            get 
            {
                Visual visual = _docPage.Visual;

                while (visual != null && !(visual is UIElement)) 
                {
                    visual = VisualTreeHelper.GetParent(visual) as Visual; 
                } 

                return visual as UIElement; 
            }
        }

        ///  
        /// TextContainer that stores content.
        ///  
        internal override ITextContainer TextContainer 
        {
            get 
            {
                return this._docPage.FixedDocumentSequence.TextContainer;
            }
        } 

        ///  
        /// Determines whenever layout is in clean state and it is possible 
        /// to retrieve layout related data.
        ///  
        internal override bool IsValid
        {
            get
            { 
                if (ChildTextView != null)
                { 
                    return ChildTextView.IsValid; 
                }
                return true; 
            }
        }

        ///  
        /// 
        ///  
        internal override bool RendersOwnSelection 
        {
            get 
            {
                return true;
            }
        } 

 
        ///  
        /// Collection of TextSegments representing content of the TextView.
        ///  
        internal override ReadOnlyCollection TextSegments
        {
            get
            { 
                if (_textSegments == null)
                { 
                    ReadOnlyCollection childSegments = ChildTextView.TextSegments; 
                    if (childSegments != null)
                    { 
                        List parentSegments = new List(childSegments.Count);
                        foreach (TextSegment segment in childSegments)
                        {
                            DocumentSequenceTextPointer ptpStart, ptpEnd; 
                            ptpStart = this._docPage.FixedDocumentSequence.TextContainer.MapChildPositionToParent(segment.Start);
                            ptpEnd = this._docPage.FixedDocumentSequence.TextContainer.MapChildPositionToParent(segment.End); 
                            parentSegments.Add(new TextSegment(ptpStart, ptpEnd,true)); 
                        }
                        _textSegments = new ReadOnlyCollection(parentSegments); 
                    }
                }
                return _textSegments;
            } 
        }
        #endregion Internal Properties 
 
        //-----------------------------------------------------
        // 
        //  Private Properties
        //
        //------------------------------------------------------
 
        #region Private Properties
        private ITextView ChildTextView 
        { 
            get
            { 
                if (_childTextView == null)
                {
                    IServiceProvider isp = _docPage.ChildDocumentPage as IServiceProvider;
                    if (isp != null) 
                    {
                        _childTextView = (ITextView)isp.GetService(typeof(ITextView)); 
                    } 
                }
                return _childTextView; 
            }
        }

 
        private ChildDocumentBlock ChildBlock
        { 
            get 
            {
                if (_childBlock == null) 
                {
                    _childBlock = _docPage.FixedDocumentSequence.TextContainer.FindChildBlock(_docPage.ChildDocumentReference);
                }
                return _childBlock; 
            }
        } 
 
        private DocumentSequenceTextContainer DocumentSequenceTextContainer
        { 
            get
            {
                return _docPage.FixedDocumentSequence.TextContainer;
            } 
        }
 
        #endregion Private Properties 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //----------------------------------------------------- 

        // The FixedDocumentSequenceDocumentPage for this TextView 
        private readonly FixedDocumentSequenceDocumentPage _docPage; 
        private ITextView _childTextView;
        private ReadOnlyCollection _textSegments; 
        private ChildDocumentBlock _childBlock;
    }
}
 


// 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