/// <summary> /// Creates a selection object spanning the portion of 'startNode' /// specified by 'locatorPart'. /// </summary> /// <param name="locatorPart">locator part specifying data to be spanned</param> /// <param name="startNode">the node to be spanned by the created /// selection</param> /// <param name="attachmentLevel">set to AttachmentLevel.Full if the entire range of text /// was resolved, otherwise set to StartPortion, MiddlePortion, or EndPortion based on /// which part of the range was resolved</param> /// <returns>a selection spanning the portion of 'startNode' specified by /// 'locatorPart', null if selection described by locator part could not be /// recreated</returns> /// <exception cref="ArgumentNullException">locatorPart or startNode are /// null</exception> /// <exception cref="ArgumentException">locatorPart is of the incorrect type</exception> public override Object ResolveLocatorPart(ContentLocatorPart locatorPart, DependencyObject startNode, out AttachmentLevel attachmentLevel) { if (startNode == null) { throw new ArgumentNullException("startNode"); } if (locatorPart == null) { throw new ArgumentNullException("locatorPart"); } if (CharacterRangeElementName != locatorPart.PartType) { throw new ArgumentException(SR.Get(SRID.IncorrectLocatorPartType, locatorPart.PartType.Namespace + ":" + locatorPart.PartType.Name), "locatorPart"); } // First we extract the offset and length of the // text range from the locator part. int startOffset = 0; int endOffset = 0; string stringCount = locatorPart.NameValuePairs[CountAttribute]; if (stringCount == null) { throw new ArgumentException(SR.Get(SRID.InvalidLocatorPart, TextSelectionProcessor.CountAttribute)); } int count = Int32.Parse(stringCount, NumberFormatInfo.InvariantInfo); TextAnchor anchor = new TextAnchor(); attachmentLevel = AttachmentLevel.Unresolved; for (int i = 0; i < count; i++) { GetLocatorPartSegmentValues(locatorPart, i, out startOffset, out endOffset); // Now we grab the TextRange so we can create a selection. // TextBox doesn't expose its internal TextRange so we use // its API for creating and getting the selection. ITextPointer elementStart; ITextPointer elementEnd; // If we can't get the start/end of the node then we can't resolve the locator part if (!GetNodesStartAndEnd(startNode, out elementStart, out elementEnd)) { return(null); } // If the offset is not withing the element's text range we return null int textRangeLength = elementStart.GetOffsetToPosition(elementEnd); if (startOffset > textRangeLength) { return(null); } ITextPointer start = elementStart.CreatePointer(startOffset);// new TextPointer((TextPointer)elementStart, startOffset); ITextPointer end = (textRangeLength <= endOffset) ? elementEnd.CreatePointer() : //new TextPointer((TextPointer)elementEnd) : elementStart.CreatePointer(endOffset); // new TextPointer((TextPointer)elementStart, endOffset); //we do not process 0 length selection if (start.CompareTo(end) >= 0) { return(null); } anchor.AddTextSegment(start, end); } //we do not support 0 or negative length selection if (anchor.IsEmpty) { throw new ArgumentException(SR.Get(SRID.IncorrectAnchorLength), "locatorPart"); } attachmentLevel = AttachmentLevel.Full; if (_clamping) { ITextPointer currentStart = anchor.Start; ITextPointer currentEnd = anchor.End; IServiceProvider serviceProvider = null; ITextView textView = null; if (_targetPage != null) { serviceProvider = _targetPage as IServiceProvider; } else { FlowDocument content = currentStart.TextContainer.Parent as FlowDocument; serviceProvider = PathNode.GetParent(content as DependencyObject) as IServiceProvider; } Invariant.Assert(serviceProvider != null, "No ServiceProvider found to get TextView from."); textView = serviceProvider.GetService(typeof(ITextView)) as ITextView; Invariant.Assert(textView != null, "Null TextView provided by ServiceProvider."); anchor = TextAnchor.TrimToIntersectionWith(anchor, textView.TextSegments); if (anchor == null) { attachmentLevel = AttachmentLevel.Unresolved; } else { if (anchor.Start.CompareTo(currentStart) != 0) { attachmentLevel &= ~AttachmentLevel.StartPortion; } if (anchor.End.CompareTo(currentEnd) != 0) { attachmentLevel &= ~AttachmentLevel.EndPortion; } } } return(anchor); }
// Token: 0x06007C46 RID: 31814 RVA: 0x0022F3A8 File Offset: 0x0022D5A8 public override object ResolveLocatorPart(ContentLocatorPart locatorPart, DependencyObject startNode, out AttachmentLevel attachmentLevel) { if (startNode == null) { throw new ArgumentNullException("startNode"); } if (locatorPart == null) { throw new ArgumentNullException("locatorPart"); } if (TextSelectionProcessor.CharacterRangeElementName != locatorPart.PartType) { throw new ArgumentException(SR.Get("IncorrectLocatorPartType", new object[] { locatorPart.PartType.Namespace + ":" + locatorPart.PartType.Name }), "locatorPart"); } int num = 0; int num2 = 0; string text = locatorPart.NameValuePairs["Count"]; if (text == null) { throw new ArgumentException(SR.Get("InvalidLocatorPart", new object[] { "Count" })); } int num3 = int.Parse(text, NumberFormatInfo.InvariantInfo); TextAnchor textAnchor = new TextAnchor(); attachmentLevel = AttachmentLevel.Unresolved; for (int i = 0; i < num3; i++) { TextSelectionProcessor.GetLocatorPartSegmentValues(locatorPart, i, out num, out num2); ITextPointer textPointer; ITextPointer textPointer2; if (!this.GetNodesStartAndEnd(startNode, out textPointer, out textPointer2)) { return(null); } int offsetToPosition = textPointer.GetOffsetToPosition(textPointer2); if (num > offsetToPosition) { return(null); } ITextPointer textPointer3 = textPointer.CreatePointer(num); ITextPointer textPointer4 = (offsetToPosition <= num2) ? textPointer2.CreatePointer() : textPointer.CreatePointer(num2); if (textPointer3.CompareTo(textPointer4) >= 0) { return(null); } textAnchor.AddTextSegment(textPointer3, textPointer4); } if (textAnchor.IsEmpty) { throw new ArgumentException(SR.Get("IncorrectAnchorLength"), "locatorPart"); } attachmentLevel = AttachmentLevel.Full; if (this._clamping) { ITextPointer start = textAnchor.Start; ITextPointer end = textAnchor.End; IServiceProvider serviceProvider; if (this._targetPage != null) { serviceProvider = this._targetPage; } else { FlowDocument node = start.TextContainer.Parent as FlowDocument; serviceProvider = (PathNode.GetParent(node) as IServiceProvider); } Invariant.Assert(serviceProvider != null, "No ServiceProvider found to get TextView from."); ITextView textView = serviceProvider.GetService(typeof(ITextView)) as ITextView; Invariant.Assert(textView != null, "Null TextView provided by ServiceProvider."); textAnchor = TextAnchor.TrimToIntersectionWith(textAnchor, textView.TextSegments); if (textAnchor == null) { attachmentLevel = AttachmentLevel.Unresolved; } else { if (textAnchor.Start.CompareTo(start) != 0) { attachmentLevel &= ~AttachmentLevel.StartPortion; } if (textAnchor.End.CompareTo(end) != 0) { attachmentLevel &= ~AttachmentLevel.EndPortion; } } } return(textAnchor); }