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
- UtilityExtension.cs
- X509ThumbprintKeyIdentifierClause.cs
- ClipboardData.cs
- StylusPoint.cs
- HitTestFilterBehavior.cs
- Calendar.cs
- XmlSerializer.cs
- SqlFacetAttribute.cs
- DataGridViewSortCompareEventArgs.cs
- DesignerAttributeInfo.cs
- Translator.cs
- ContainerUtilities.cs
- InternalCache.cs
- Soap12ProtocolReflector.cs
- LiteralSubsegment.cs
- ZipIOFileItemStream.cs
- ApplicationContext.cs
- ProtocolsSection.cs
- HiddenFieldPageStatePersister.cs
- TraceSource.cs
- XamlTreeBuilderBamlRecordWriter.cs
- OleCmdHelper.cs
- PkcsUtils.cs
- TriState.cs
- WSSecurityPolicy11.cs
- DesignerTransaction.cs
- JapaneseLunisolarCalendar.cs
- GridViewRowPresenterBase.cs
- EventLogEntryCollection.cs
- PeerCollaboration.cs
- ResourceExpression.cs
- PowerModeChangedEventArgs.cs
- BlurEffect.cs
- SendMailErrorEventArgs.cs
- Camera.cs
- FormsAuthenticationUserCollection.cs
- StatusBar.cs
- MsmqAuthenticationMode.cs
- BindingContext.cs
- ByteFacetDescriptionElement.cs
- BatchStream.cs
- Parsers.cs
- CodeTypeParameterCollection.cs
- IImplicitResourceProvider.cs
- EventHandlingScope.cs
- XmlDataContract.cs
- SymmetricKeyWrap.cs
- TypeDescriptor.cs
- Size.cs
- DesignTimeType.cs
- StaticExtensionConverter.cs
- ServiceDefaults.cs
- CheckableControlBaseAdapter.cs
- SmiConnection.cs
- NativeConfigurationLoader.cs
- SimpleWebHandlerParser.cs
- QueryCursorEventArgs.cs
- TextBreakpoint.cs
- ProfileService.cs
- StatusBar.cs
- Context.cs
- SynchronousSendBindingElement.cs
- WindowsAuthenticationEventArgs.cs
- VisualTreeFlattener.cs
- FixedBufferAttribute.cs
- WebEvents.cs
- MD5HashHelper.cs
- BatchParser.cs
- DuplicateWaitObjectException.cs
- Freezable.cs
- ThreadAbortException.cs
- ExpressionVisitorHelpers.cs
- AssemblyBuilder.cs
- SignedInfo.cs
- DataControlButton.cs
- ListViewEditEventArgs.cs
- XPathParser.cs
- SqlParameter.cs
- AutomationProperties.cs
- CacheSection.cs
- ViewGenResults.cs
- sortedlist.cs
- FontSource.cs
- AttachedAnnotation.cs
- XmlValueConverter.cs
- UnsafeNativeMethods.cs
- ADRoleFactoryConfiguration.cs
- Debug.cs
- SystemIcmpV6Statistics.cs
- ExceptionUtil.cs
- PeerObject.cs
- MemberDescriptor.cs
- ParameterReplacerVisitor.cs
- FrameworkContentElementAutomationPeer.cs
- SystemIPInterfaceProperties.cs
- LineProperties.cs
- InputBuffer.cs
- ProviderBase.cs
- DocumentSequence.cs
- DataGridViewImageColumn.cs