Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Documents / FixedTextPointer.cs / 1 / FixedTextPointer.cs
//---------------------------------------------------------------------------- // // File: FixedTextPointer.cs // // Copyright (C) 2004 by Microsoft Corporation. All rights reserved. // // Description: // FixedTextPointer is an implementation of TextPointer/TextNavigator // for Fixed Document. It is the base class for FixedTextPosition and // FixedTextPointer. // //--------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // To enable presharp warning disables (#pragma suppress) below. namespace System.Windows.Documents { using MS.Utility; using System.Windows; using System; using System.Diagnostics; using MS.Internal; ////// FixedTextPointer is an implementation of TextPointer/TextNavigator /// for Fixed Document. /// ////// A FixedTextPointer is represented by a FlowPosition in the backing store /// internal class FixedTextPointer : ContentPosition, ITextPointer { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors internal FixedTextPointer(bool mutable, LogicalDirection gravity, FlowPosition flow) { _isFrozen = !mutable; _gravity = gravity; _flowPosition = flow; } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #if DEBUG ////// Debug only ToString override. /// public override string ToString() { return "FTP" + DebugId + " " + (this._isFrozen? "NV " : "PO ") + _flowPosition.ToString() + " " + this._gravity; } #endif // DEBUG ////// internal int CompareTo(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); return _flowPosition.CompareTo(ftp.FlowPosition); } int ITextPointer.CompareTo(StaticTextPointer position) { return ((ITextPointer)this).CompareTo((ITextPointer)position.Handle0); } #region TextPointer Methods ////// /// int ITextPointer.CompareTo(ITextPointer position) { return CompareTo(position); } ////// /// int ITextPointer.GetOffsetToPosition(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); return _flowPosition.GetDistance(ftp.FlowPosition); } ////// /// TextPointerContext ITextPointer.GetPointerContext(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); return _flowPosition.GetPointerContext(direction); } ////// /// ////// Return 0 if non-text run int ITextPointer.GetTextRunLength(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); if (_flowPosition.GetPointerContext(direction) != TextPointerContext.Text) { return 0; } return _flowPosition.GetTextRunLength(direction); } //string ITextPointer.GetTextInRun(LogicalDirection direction) { return TextPointerBase.GetTextInRun(this, direction); } /// /// ////// Only reutrn uninterrupted runs of text int ITextPointer.GetTextInRun(LogicalDirection direction, char[] textBuffer, int startIndex, int count) { ValidationHelper.VerifyDirection(direction, "direction"); if (textBuffer == null) { throw new ArgumentNullException("textBuffer"); } if (count < 0) { throw new ArgumentException(SR.Get(SRID.NegativeValue, "count")); } if (_flowPosition.GetPointerContext(direction) != TextPointerContext.Text) { return 0; } return _flowPosition.GetTextInRun(direction, count, textBuffer, startIndex); } ////// ////// Return null if the embedded object does not exist object ITextPointer.GetAdjacentElement(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); TextPointerContext tpc = _flowPosition.GetPointerContext(direction); if (!(tpc == TextPointerContext.EmbeddedElement || tpc == TextPointerContext.ElementStart || tpc == TextPointerContext.ElementEnd)) { return null; } return _flowPosition.GetAdjacentElement(direction); } ////// ////// Return null if no TextElement in the direction Type ITextPointer.GetElementType(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); TextPointerContext tt = _flowPosition.GetPointerContext(direction); if (tt == TextPointerContext.ElementStart || tt == TextPointerContext.ElementEnd) { FixedElement e = _flowPosition.GetElement(direction); return e.IsTextElement ? e.Type : null; } return null; } ////// bool ITextPointer.HasEqualScope(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); FixedElement thisFE = _flowPosition.GetScopingElement(); FixedElement thatFE = ftp.FlowPosition.GetScopingElement(); // We retun true even if both scoping elements are the // container element. return thisFE == thatFE; } ////// /// ////// return property values even if there is no scoping element object ITextPointer.GetValue(DependencyProperty property) { if (property == null) { throw new ArgumentNullException("property"); } FixedElement e = _flowPosition.GetScopingElement(); return e.GetValue(property); } ////// ////// Throws InvalidOperationException if there is no scoping element object ITextPointer.ReadLocalValue(DependencyProperty property) { if (property == null) { throw new ArgumentNullException("property"); } FixedElement e = _flowPosition.GetScopingElement(); if (!e.IsTextElement) { throw new InvalidOperationException(SR.Get(SRID.NoElementObject)); } return e.ReadLocalValue(property); } ////// ////// Returns an empty enumerator if there is no scoping element LocalValueEnumerator ITextPointer.GetLocalValueEnumerator() { FixedElement e = _flowPosition.GetScopingElement(); if (!e.IsTextElement) { return (new DependencyObject()).GetLocalValueEnumerator(); } return e.GetLocalValueEnumerator(); } ITextPointer ITextPointer.CreatePointer() { return ((ITextPointer)this).CreatePointer(0, ((ITextPointer)this).LogicalDirection); } // Unoptimized CreateStaticPointer implementation. // Creates a simple wrapper for an ITextPointer instance. StaticTextPointer ITextPointer.CreateStaticPointer() { return new StaticTextPointer(((ITextPointer)this).TextContainer, ((ITextPointer)this).CreatePointer()); } ITextPointer ITextPointer.CreatePointer(int distance) { return ((ITextPointer)this).CreatePointer(distance, ((ITextPointer)this).LogicalDirection); } ITextPointer ITextPointer.CreatePointer(LogicalDirection gravity) { return ((ITextPointer)this).CreatePointer(0, gravity); } ////// ITextPointer ITextPointer.CreatePointer(int distance, LogicalDirection gravity) { ValidationHelper.VerifyDirection(gravity, "gravity"); FlowPosition fp = (FlowPosition)_flowPosition.Clone(); if (!fp.Move(distance)) { throw new ArgumentException(SR.Get(SRID.BadDistance), "distance"); } return new FixedTextPointer(true, gravity, fp); } ///// void ITextPointer.Freeze() { _isFrozen = true; } /// /// ITextPointer ITextPointer.GetFrozenPointer(LogicalDirection logicalDirection) { return TextPointerBase.GetFrozenPointer(this, logicalDirection); } // Candidate for replacing MoveToNextContextPosition for immutable TextPointer model ITextPointer ITextPointer.GetNextContextPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); if (pointer.MoveToNextContextPosition(direction)) { pointer.Freeze(); } else { pointer = null; } return pointer; } // Candidate for replacing MoveToInsertionPosition for immutable TextPointer model ITextPointer ITextPointer.GetInsertionPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); pointer.MoveToInsertionPosition(direction); pointer.Freeze(); return pointer; } // Returns the closest insertion position, treating all unicode code points // as valid insertion positions. A useful performance win over // GetNextInsertionPosition when only formatting scopes are important. ITextPointer ITextPointer.GetFormatNormalizedPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); TextPointerBase.MoveToFormatNormalizedPosition(pointer, direction); pointer.Freeze(); return pointer; } // Candidate for replacing MoveToNextInsertionPosition for immutable TextPointer model ITextPointer ITextPointer.GetNextInsertionPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); if (pointer.MoveToNextInsertionPosition(direction)) { pointer.Freeze(); } else { pointer = null; } return pointer; } #endregion TextPointer Methods ////// /// /// void ITextPointer.SetLogicalDirection(LogicalDirection direction) { this.LogicalDirection = direction; } #region TextNavigator Methods ////// /// bool ITextPointer.MoveToNextContextPosition(LogicalDirection direction) { Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); ValidationHelper.VerifyDirection(direction, "direction"); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); return _flowPosition.Move(direction); } ////// /// int ITextPointer.MoveByOffset(int offset) { if (_isFrozen) throw new InvalidOperationException(SR.Get(SRID.TextPositionIsFrozen)); if (!_flowPosition.Move(offset)) { throw new ArgumentException(SR.Get(SRID.BadDistance), "distance"); } else { return offset; } } ////// /// void ITextPointer.MoveToPosition(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); _flowPosition.MoveTo(ftp.FlowPosition); } ////// /// void ITextPointer.MoveToElementEdge(ElementEdge edge) { ValidationHelper.VerifyElementEdge(edge, "edge"); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); FixedElement e = _flowPosition.GetScopingElement(); if (!e.IsTextElement) { throw new InvalidOperationException(SR.Get(SRID.NoElementObject)); } switch (edge) { case ElementEdge.BeforeStart: _flowPosition = (FlowPosition)e.Start.FlowPosition.Clone(); _flowPosition.Move(-1); break; case ElementEdge.AfterStart: _flowPosition = (FlowPosition)e.Start.FlowPosition.Clone(); break; case ElementEdge.BeforeEnd: _flowPosition = (FlowPosition)e.End.FlowPosition.Clone(); break; case ElementEdge.AfterEnd: _flowPosition = (FlowPosition)e.End.FlowPosition.Clone(); _flowPosition.Move(1); break; } } ///// int ITextPointer.MoveToLineBoundary(int count) { return TextPointerBase.MoveToLineBoundary(this, ((ITextPointer)this).TextContainer.TextView, count, true); } // Rect ITextPointer.GetCharacterRect(LogicalDirection direction) { return TextPointerBase.GetCharacterRect(this, direction); } bool ITextPointer.MoveToInsertionPosition(LogicalDirection direction) { return TextPointerBase.MoveToInsertionPosition(this, direction); } bool ITextPointer.MoveToNextInsertionPosition(LogicalDirection direction) { return TextPointerBase.MoveToNextInsertionPosition(this, direction); } // // TextContainer modification methods. Disabled by design. // // This is readonly Text OM. All modification methods returns false // /// /// void ITextPointer.InsertTextInRun(string textData) { if (textData == null) { throw new ArgumentNullException("textData"); } throw new InvalidOperationException(SR.Get(SRID.FixedDocumentReadonly)); } ////// void ITextPointer.DeleteContentToPosition(ITextPointer limit) { throw new InvalidOperationException(SR.Get(SRID.FixedDocumentReadonly)); } ///bool ITextPointer.ValidateLayout() { return TextPointerBase.ValidateLayout(this, ((ITextPointer)this).TextContainer.TextView); } #endregion TextNavigator Methods //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region TextPointer Properties // Type ITextPointer.ParentType { get { FixedElement e = _flowPosition.GetScopingElement(); return e.IsTextElement ? e.Type : ((ITextContainer)_flowPosition.TextContainer).Parent.GetType(); } } /// /// ITextContainer ITextPointer.TextContainer { get { return this.FixedTextContainer; } } ///// bool ITextPointer.HasValidLayout { get { return (((ITextPointer)this).TextContainer.TextView != null && ((ITextPointer)this).TextContainer.TextView.IsValid && ((ITextPointer)this).TextContainer.TextView.Contains(this)); } } // bool ITextPointer.IsAtCaretUnitBoundary { get { Invariant.Assert(((ITextPointer)this).HasValidLayout); ITextView textView = ((ITextPointer)this).TextContainer.TextView; bool isAtCaretUnitBoundary = textView.IsAtCaretUnitBoundary(this); if (!isAtCaretUnitBoundary && this.LogicalDirection == LogicalDirection.Backward) { // In MIL Text and TextView worlds, a position at trailing edge of a newline (with backward gravity) // is not an allowed caret stop. // However, in TextPointer world we must allow such a position to be a valid insertion position, // since it breaks textrange normalization for empty ranges. // Hence, we need to check for TextView.IsAtCaretUnitBoundary in reverse direction below. ITextPointer positionForwardGravity = ((ITextPointer)this).CreatePointer(LogicalDirection.Forward); isAtCaretUnitBoundary = textView.IsAtCaretUnitBoundary(positionForwardGravity); } return isAtCaretUnitBoundary; } } /// /// LogicalDirection ITextPointer.LogicalDirection { get { return this.LogicalDirection; } } bool ITextPointer.IsAtInsertionPosition { get { return TextPointerBase.IsAtInsertionPosition(this); } } ///// bool ITextPointer.IsFrozen { get { return _isFrozen; } } // int ITextPointer.Offset { get { return TextPointerBase.GetOffset(this); } } // Not implemented. int ITextPointer.CharOffset { get { #pragma warning suppress 56503 throw new NotImplementedException(); } } #endregion TextPointer Properties //----------------------------------------------------- // // Internal Property // //------------------------------------------------------ #region Internal Property internal FlowPosition FlowPosition { get { return _flowPosition; } } internal FixedTextContainer FixedTextContainer { get { return _flowPosition.TextContainer; } } internal LogicalDirection LogicalDirection { get { return _gravity; } set { ValidationHelper.VerifyDirection(value, "value"); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); _flowPosition = _flowPosition.GetClingPosition(value); _gravity = value; } } #if DEBUG internal uint DebugId { get { return _debugId; } } #endif #endregion Internal Property //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields private LogicalDirection _gravity; private FlowPosition _flowPosition; // FlowPosition in the content flow // True if Freeze has been called, in which case // this TextPointer is immutable and may not be repositioned. private bool _isFrozen; #if DEBUG private uint _debugId = (_debugIdCounter++); private static uint _debugIdCounter = 0; #endif #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // File: FixedTextPointer.cs // // Copyright (C) 2004 by Microsoft Corporation. All rights reserved. // // Description: // FixedTextPointer is an implementation of TextPointer/TextNavigator // for Fixed Document. It is the base class for FixedTextPosition and // FixedTextPointer. // //--------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // To enable presharp warning disables (#pragma suppress) below. namespace System.Windows.Documents { using MS.Utility; using System.Windows; using System; using System.Diagnostics; using MS.Internal; /// /// FixedTextPointer is an implementation of TextPointer/TextNavigator /// for Fixed Document. /// ////// A FixedTextPointer is represented by a FlowPosition in the backing store /// internal class FixedTextPointer : ContentPosition, ITextPointer { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors internal FixedTextPointer(bool mutable, LogicalDirection gravity, FlowPosition flow) { _isFrozen = !mutable; _gravity = gravity; _flowPosition = flow; } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #if DEBUG ////// Debug only ToString override. /// public override string ToString() { return "FTP" + DebugId + " " + (this._isFrozen? "NV " : "PO ") + _flowPosition.ToString() + " " + this._gravity; } #endif // DEBUG ////// internal int CompareTo(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); return _flowPosition.CompareTo(ftp.FlowPosition); } int ITextPointer.CompareTo(StaticTextPointer position) { return ((ITextPointer)this).CompareTo((ITextPointer)position.Handle0); } #region TextPointer Methods ////// /// int ITextPointer.CompareTo(ITextPointer position) { return CompareTo(position); } ////// /// int ITextPointer.GetOffsetToPosition(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); return _flowPosition.GetDistance(ftp.FlowPosition); } ////// /// TextPointerContext ITextPointer.GetPointerContext(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); return _flowPosition.GetPointerContext(direction); } ////// /// ////// Return 0 if non-text run int ITextPointer.GetTextRunLength(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); if (_flowPosition.GetPointerContext(direction) != TextPointerContext.Text) { return 0; } return _flowPosition.GetTextRunLength(direction); } //string ITextPointer.GetTextInRun(LogicalDirection direction) { return TextPointerBase.GetTextInRun(this, direction); } /// /// ////// Only reutrn uninterrupted runs of text int ITextPointer.GetTextInRun(LogicalDirection direction, char[] textBuffer, int startIndex, int count) { ValidationHelper.VerifyDirection(direction, "direction"); if (textBuffer == null) { throw new ArgumentNullException("textBuffer"); } if (count < 0) { throw new ArgumentException(SR.Get(SRID.NegativeValue, "count")); } if (_flowPosition.GetPointerContext(direction) != TextPointerContext.Text) { return 0; } return _flowPosition.GetTextInRun(direction, count, textBuffer, startIndex); } ////// ////// Return null if the embedded object does not exist object ITextPointer.GetAdjacentElement(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); TextPointerContext tpc = _flowPosition.GetPointerContext(direction); if (!(tpc == TextPointerContext.EmbeddedElement || tpc == TextPointerContext.ElementStart || tpc == TextPointerContext.ElementEnd)) { return null; } return _flowPosition.GetAdjacentElement(direction); } ////// ////// Return null if no TextElement in the direction Type ITextPointer.GetElementType(LogicalDirection direction) { ValidationHelper.VerifyDirection(direction, "direction"); TextPointerContext tt = _flowPosition.GetPointerContext(direction); if (tt == TextPointerContext.ElementStart || tt == TextPointerContext.ElementEnd) { FixedElement e = _flowPosition.GetElement(direction); return e.IsTextElement ? e.Type : null; } return null; } ////// bool ITextPointer.HasEqualScope(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); FixedElement thisFE = _flowPosition.GetScopingElement(); FixedElement thatFE = ftp.FlowPosition.GetScopingElement(); // We retun true even if both scoping elements are the // container element. return thisFE == thatFE; } ////// /// ////// return property values even if there is no scoping element object ITextPointer.GetValue(DependencyProperty property) { if (property == null) { throw new ArgumentNullException("property"); } FixedElement e = _flowPosition.GetScopingElement(); return e.GetValue(property); } ////// ////// Throws InvalidOperationException if there is no scoping element object ITextPointer.ReadLocalValue(DependencyProperty property) { if (property == null) { throw new ArgumentNullException("property"); } FixedElement e = _flowPosition.GetScopingElement(); if (!e.IsTextElement) { throw new InvalidOperationException(SR.Get(SRID.NoElementObject)); } return e.ReadLocalValue(property); } ////// ////// Returns an empty enumerator if there is no scoping element LocalValueEnumerator ITextPointer.GetLocalValueEnumerator() { FixedElement e = _flowPosition.GetScopingElement(); if (!e.IsTextElement) { return (new DependencyObject()).GetLocalValueEnumerator(); } return e.GetLocalValueEnumerator(); } ITextPointer ITextPointer.CreatePointer() { return ((ITextPointer)this).CreatePointer(0, ((ITextPointer)this).LogicalDirection); } // Unoptimized CreateStaticPointer implementation. // Creates a simple wrapper for an ITextPointer instance. StaticTextPointer ITextPointer.CreateStaticPointer() { return new StaticTextPointer(((ITextPointer)this).TextContainer, ((ITextPointer)this).CreatePointer()); } ITextPointer ITextPointer.CreatePointer(int distance) { return ((ITextPointer)this).CreatePointer(distance, ((ITextPointer)this).LogicalDirection); } ITextPointer ITextPointer.CreatePointer(LogicalDirection gravity) { return ((ITextPointer)this).CreatePointer(0, gravity); } ////// ITextPointer ITextPointer.CreatePointer(int distance, LogicalDirection gravity) { ValidationHelper.VerifyDirection(gravity, "gravity"); FlowPosition fp = (FlowPosition)_flowPosition.Clone(); if (!fp.Move(distance)) { throw new ArgumentException(SR.Get(SRID.BadDistance), "distance"); } return new FixedTextPointer(true, gravity, fp); } ///// void ITextPointer.Freeze() { _isFrozen = true; } /// /// ITextPointer ITextPointer.GetFrozenPointer(LogicalDirection logicalDirection) { return TextPointerBase.GetFrozenPointer(this, logicalDirection); } // Candidate for replacing MoveToNextContextPosition for immutable TextPointer model ITextPointer ITextPointer.GetNextContextPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); if (pointer.MoveToNextContextPosition(direction)) { pointer.Freeze(); } else { pointer = null; } return pointer; } // Candidate for replacing MoveToInsertionPosition for immutable TextPointer model ITextPointer ITextPointer.GetInsertionPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); pointer.MoveToInsertionPosition(direction); pointer.Freeze(); return pointer; } // Returns the closest insertion position, treating all unicode code points // as valid insertion positions. A useful performance win over // GetNextInsertionPosition when only formatting scopes are important. ITextPointer ITextPointer.GetFormatNormalizedPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); TextPointerBase.MoveToFormatNormalizedPosition(pointer, direction); pointer.Freeze(); return pointer; } // Candidate for replacing MoveToNextInsertionPosition for immutable TextPointer model ITextPointer ITextPointer.GetNextInsertionPosition(LogicalDirection direction) { ITextPointer pointer = ((ITextPointer)this).CreatePointer(); if (pointer.MoveToNextInsertionPosition(direction)) { pointer.Freeze(); } else { pointer = null; } return pointer; } #endregion TextPointer Methods ////// /// /// void ITextPointer.SetLogicalDirection(LogicalDirection direction) { this.LogicalDirection = direction; } #region TextNavigator Methods ////// /// bool ITextPointer.MoveToNextContextPosition(LogicalDirection direction) { Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); ValidationHelper.VerifyDirection(direction, "direction"); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); return _flowPosition.Move(direction); } ////// /// int ITextPointer.MoveByOffset(int offset) { if (_isFrozen) throw new InvalidOperationException(SR.Get(SRID.TextPositionIsFrozen)); if (!_flowPosition.Move(offset)) { throw new ArgumentException(SR.Get(SRID.BadDistance), "distance"); } else { return offset; } } ////// /// void ITextPointer.MoveToPosition(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); _flowPosition.MoveTo(ftp.FlowPosition); } ////// /// void ITextPointer.MoveToElementEdge(ElementEdge edge) { ValidationHelper.VerifyElementEdge(edge, "edge"); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); FixedElement e = _flowPosition.GetScopingElement(); if (!e.IsTextElement) { throw new InvalidOperationException(SR.Get(SRID.NoElementObject)); } switch (edge) { case ElementEdge.BeforeStart: _flowPosition = (FlowPosition)e.Start.FlowPosition.Clone(); _flowPosition.Move(-1); break; case ElementEdge.AfterStart: _flowPosition = (FlowPosition)e.Start.FlowPosition.Clone(); break; case ElementEdge.BeforeEnd: _flowPosition = (FlowPosition)e.End.FlowPosition.Clone(); break; case ElementEdge.AfterEnd: _flowPosition = (FlowPosition)e.End.FlowPosition.Clone(); _flowPosition.Move(1); break; } } ///// int ITextPointer.MoveToLineBoundary(int count) { return TextPointerBase.MoveToLineBoundary(this, ((ITextPointer)this).TextContainer.TextView, count, true); } // Rect ITextPointer.GetCharacterRect(LogicalDirection direction) { return TextPointerBase.GetCharacterRect(this, direction); } bool ITextPointer.MoveToInsertionPosition(LogicalDirection direction) { return TextPointerBase.MoveToInsertionPosition(this, direction); } bool ITextPointer.MoveToNextInsertionPosition(LogicalDirection direction) { return TextPointerBase.MoveToNextInsertionPosition(this, direction); } // // TextContainer modification methods. Disabled by design. // // This is readonly Text OM. All modification methods returns false // /// /// void ITextPointer.InsertTextInRun(string textData) { if (textData == null) { throw new ArgumentNullException("textData"); } throw new InvalidOperationException(SR.Get(SRID.FixedDocumentReadonly)); } ////// void ITextPointer.DeleteContentToPosition(ITextPointer limit) { throw new InvalidOperationException(SR.Get(SRID.FixedDocumentReadonly)); } ///bool ITextPointer.ValidateLayout() { return TextPointerBase.ValidateLayout(this, ((ITextPointer)this).TextContainer.TextView); } #endregion TextNavigator Methods //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region TextPointer Properties // Type ITextPointer.ParentType { get { FixedElement e = _flowPosition.GetScopingElement(); return e.IsTextElement ? e.Type : ((ITextContainer)_flowPosition.TextContainer).Parent.GetType(); } } /// /// ITextContainer ITextPointer.TextContainer { get { return this.FixedTextContainer; } } ///// bool ITextPointer.HasValidLayout { get { return (((ITextPointer)this).TextContainer.TextView != null && ((ITextPointer)this).TextContainer.TextView.IsValid && ((ITextPointer)this).TextContainer.TextView.Contains(this)); } } // bool ITextPointer.IsAtCaretUnitBoundary { get { Invariant.Assert(((ITextPointer)this).HasValidLayout); ITextView textView = ((ITextPointer)this).TextContainer.TextView; bool isAtCaretUnitBoundary = textView.IsAtCaretUnitBoundary(this); if (!isAtCaretUnitBoundary && this.LogicalDirection == LogicalDirection.Backward) { // In MIL Text and TextView worlds, a position at trailing edge of a newline (with backward gravity) // is not an allowed caret stop. // However, in TextPointer world we must allow such a position to be a valid insertion position, // since it breaks textrange normalization for empty ranges. // Hence, we need to check for TextView.IsAtCaretUnitBoundary in reverse direction below. ITextPointer positionForwardGravity = ((ITextPointer)this).CreatePointer(LogicalDirection.Forward); isAtCaretUnitBoundary = textView.IsAtCaretUnitBoundary(positionForwardGravity); } return isAtCaretUnitBoundary; } } /// /// LogicalDirection ITextPointer.LogicalDirection { get { return this.LogicalDirection; } } bool ITextPointer.IsAtInsertionPosition { get { return TextPointerBase.IsAtInsertionPosition(this); } } ///// bool ITextPointer.IsFrozen { get { return _isFrozen; } } // int ITextPointer.Offset { get { return TextPointerBase.GetOffset(this); } } // Not implemented. int ITextPointer.CharOffset { get { #pragma warning suppress 56503 throw new NotImplementedException(); } } #endregion TextPointer Properties //----------------------------------------------------- // // Internal Property // //------------------------------------------------------ #region Internal Property internal FlowPosition FlowPosition { get { return _flowPosition; } } internal FixedTextContainer FixedTextContainer { get { return _flowPosition.TextContainer; } } internal LogicalDirection LogicalDirection { get { return _gravity; } set { ValidationHelper.VerifyDirection(value, "value"); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); _flowPosition = _flowPosition.GetClingPosition(value); _gravity = value; } } #if DEBUG internal uint DebugId { get { return _debugId; } } #endif #endregion Internal Property //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields private LogicalDirection _gravity; private FlowPosition _flowPosition; // FlowPosition in the content flow // True if Freeze has been called, in which case // this TextPointer is immutable and may not be repositioned. private bool _isFrozen; #if DEBUG private uint _debugId = (_debugIdCounter++); private static uint _debugIdCounter = 0; #endif #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EntityDataSourceSelectingEventArgs.cs
- RegionInfo.cs
- DataServiceBehavior.cs
- LinkGrep.cs
- TrimSurroundingWhitespaceAttribute.cs
- VsPropertyGrid.cs
- XPathNavigator.cs
- CommandID.cs
- SmtpException.cs
- GradientStop.cs
- BinaryFormatter.cs
- SqlReferenceCollection.cs
- StreamGeometryContext.cs
- SafeArchiveContext.cs
- EntityWrapperFactory.cs
- Highlights.cs
- GeometryHitTestParameters.cs
- ListBoxDesigner.cs
- AddIn.cs
- ObjectQueryProvider.cs
- AssemblyResourceLoader.cs
- PeerValidationBehavior.cs
- Point3DConverter.cs
- BinaryFormatter.cs
- DbDataSourceEnumerator.cs
- SweepDirectionValidation.cs
- PkcsMisc.cs
- DrawingState.cs
- CodeRegionDirective.cs
- ExpressionBuilderCollection.cs
- Line.cs
- SimpleApplicationHost.cs
- ToolStripArrowRenderEventArgs.cs
- ListBox.cs
- JsonReader.cs
- ThreadLocal.cs
- UnauthorizedWebPart.cs
- ConstraintStruct.cs
- Deflater.cs
- BlurBitmapEffect.cs
- FormClosingEvent.cs
- ReadOnlyDictionary.cs
- CngKeyBlobFormat.cs
- RenderDataDrawingContext.cs
- WsatTransactionInfo.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- AppDomainFactory.cs
- Label.cs
- SafeViewOfFileHandle.cs
- Int16.cs
- PriorityQueue.cs
- GeometryValueSerializer.cs
- ListViewInsertEventArgs.cs
- TableLayoutPanel.cs
- FigureHelper.cs
- PageContent.cs
- ViewSimplifier.cs
- SvcMapFile.cs
- BaseProcessProtocolHandler.cs
- IconBitmapDecoder.cs
- BezierSegment.cs
- XmlBoundElement.cs
- HelpInfo.cs
- StylusCaptureWithinProperty.cs
- SerializerDescriptor.cs
- wgx_render.cs
- DescendantQuery.cs
- KeyedPriorityQueue.cs
- ObjectDataSourceMethodEventArgs.cs
- SHA1.cs
- QuaternionAnimation.cs
- AutoFocusStyle.xaml.cs
- MasterPage.cs
- ZipIOExtraFieldZip64Element.cs
- RestHandlerFactory.cs
- CqlBlock.cs
- DecoratedNameAttribute.cs
- IncomingWebResponseContext.cs
- AppModelKnownContentFactory.cs
- ObjectListDataBindEventArgs.cs
- HttpRequestTraceRecord.cs
- PrincipalPermission.cs
- NonSerializedAttribute.cs
- FaultConverter.cs
- LazyTextWriterCreator.cs
- LessThanOrEqual.cs
- CapacityStreamGeometryContext.cs
- SqlCacheDependencySection.cs
- CurrencyWrapper.cs
- FileIOPermission.cs
- XPathDocumentBuilder.cs
- HostingPreferredMapPath.cs
- TypeConverterAttribute.cs
- WebResourceUtil.cs
- baseaxisquery.cs
- CanonicalFontFamilyReference.cs
- StringExpressionSet.cs
- TextDataBindingHandler.cs
- FormsAuthenticationUser.cs
- PassportPrincipal.cs