Exemplo n.º 1
0
 /// <summary>
 /// Finds the degenerate range nearest to a screen coordinate.
 /// </summary>
 /// <param name="location">The location in screen coordinates.
 /// The provider should check that the coordinates are within the client
 /// area of the provider, and should throw an InvalidOperation exception 
 /// if they are not.</param>
 /// <returns>A degenerate range nearest the specified location.</returns>
 ITextRangeProvider ITextProvider.RangeFromPoint(Point location)
 {
     TextRangeAdaptor range = null;
     ITextView textView = GetUpdatedTextView();
     if (textView != null)
     {
         // Convert the screen point to the element space coordinates.
         location = ScreenToClient(location, textView.RenderScope);
         ITextPointer position = textView.GetTextPositionFromPoint(location, true);
         if (position != null)
         {
             range = new TextRangeAdaptor(this, position, position, _textPeer);
         }
     }
     if (range == null)
     {
         throw new ArgumentException(SR.Get(SRID.TextProvider_InvalidPoint));
     }
     return range;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Retrieves the range of a child object.
        /// </summary>
        /// <param name="childElementProvider">The child element.  A provider should check that the 
        /// passed element is a child of the text container, and should throw an 
        /// InvalidOperationException if it is not.</param>
        /// <returns>A range that spans the child element.</returns>
        ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElementProvider)
        {
            if (childElementProvider == null)
            {
                throw new ArgumentNullException("childElementProvider");
            }

            // Retrieve DependencyObject from AutomationElement
            DependencyObject childElement;
            if (_textPeer is TextAutomationPeer)
            {
                childElement = ((TextAutomationPeer)_textPeer).ElementFromProvider(childElementProvider);
            }
            else
            {
                childElement = ((ContentTextAutomationPeer)_textPeer).ElementFromProvider(childElementProvider);
            }

            TextRangeAdaptor range = null;
            if (childElement != null)
            {
                ITextPointer rangeStart = null;
                ITextPointer rangeEnd = null;

                // Retrieve start and end positions for given element.
                // If element is TextElement, retrieve its Element Start and End positions.
                // If element is UIElement hosted by UIContainer (Inlien of Block), 
                // retrieve content Start and End positions of the container.
                // Otherwise scan ITextContainer to find a range for given element.
                if (childElement is TextElement)
                {
                    rangeStart = ((TextElement)childElement).ElementStart;
                    rangeEnd = ((TextElement)childElement).ElementEnd;
                }
                else
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(childElement);
                    if (parent is InlineUIContainer || parent is BlockUIContainer)
                    {
                        rangeStart = ((TextElement)parent).ContentStart;
                        rangeEnd = ((TextElement)parent).ContentEnd;
                    }
                    else
                    {
                        ITextPointer position = _textContainer.Start.CreatePointer();
                        while (position.CompareTo(_textContainer.End) < 0)
                        {
                            TextPointerContext context = position.GetPointerContext(LogicalDirection.Forward);
                            if (context == TextPointerContext.ElementStart)
                            {
                                if (childElement == position.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    rangeStart = position.CreatePointer(LogicalDirection.Forward);
                                    position.MoveToElementEdge(ElementEdge.AfterEnd);
                                    rangeEnd = position.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            else if (context == TextPointerContext.EmbeddedElement)
                            {
                                if (childElement == position.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    rangeStart = position.CreatePointer(LogicalDirection.Forward);
                                    position.MoveToNextContextPosition(LogicalDirection.Forward);
                                    rangeEnd = position.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            position.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                }
                // Create range
                if (rangeStart != null && rangeEnd != null)
                {
                    range = new TextRangeAdaptor(this, rangeStart, rangeEnd, _textPeer);
                }
            }
            if (range == null)
            {
                throw new InvalidOperationException(SR.Get(SRID.TextProvider_InvalidChildElement));
            }
            return range;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Searches for an occurrence of text within the range.
        /// </summary>
        /// <param name="text">The text to search for.</param>
        /// <param name="backward">true if the last occurring range should be returned instead of the first.</param>
        /// <param name="ignoreCase">true if case should be ignored for the purposes of comparison.</param>
        /// <returns>A subrange with the specified text, or null if no such subrange exists.</returns>
        ITextRangeProvider ITextRangeProvider.FindText(string text, bool backward, bool ignoreCase)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            if (text.Length == 0)
            {
                throw new ArgumentException(SR.Get(SRID.TextRangeProvider_EmptyStringParameter, "text"));
            }

            Normalize();

            if (_start.CompareTo(_end) == 0)
            {
                return null;
            }

            TextRangeAdaptor range = null;
            FindFlags findFlags = FindFlags.None;
            if (!ignoreCase)
            {
                findFlags |= FindFlags.MatchCase;
            }
            if (backward)
            {
                findFlags |= FindFlags.FindInReverse;
            }
            ITextRange findResult = TextFindEngine.Find(_start, _end, text, findFlags, CultureInfo.CurrentCulture);
            if (findResult != null && !findResult.IsEmpty)
            {
                range = new TextRangeAdaptor(_textAdaptor, findResult.Start, findResult.End, _textPeer);
            }

            return range;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Retrieves the visible ranges of text.
        /// </summary>
        /// <returns>The ranges of text that are visible, or possibly an empty array if there is
        /// no visible text whatsoever.  Text in the range may still be obscured by an overlapping
        /// window.  Also, portions
        /// of the range at the beginning, in the middle, or at the end may not be visible
        /// because they are scrolled off to the side.
        /// Providers should ensure they return at most a range from the beginning of the first
        /// line with portions visible through the end of the last line with portions visible.</returns>
        ITextRangeProvider[] ITextProvider.GetVisibleRanges()
        {
            ITextRangeProvider[] ranges = null;
            ITextView textView = GetUpdatedTextView();
            if (textView != null)
            {
                List<TextSegment> visibleTextSegments = new List<TextSegment>();

                // Get visible portion of the document. 
                // 




                if (textView is MultiPageTextView)
                {
                    // For MultiPageTextView assume that all current pages are entirely visible.
                    visibleTextSegments.AddRange(textView.TextSegments);
                }
                else
                {
                    // For all others TextViews get visible rectangle and hittest TopLeft and 
                    // BottomRight points to retrieve visible range.
                    // Find out the bounds of the area visible through all nested scroll areas
                    Rect visibleRect = GetVisibleRectangle(textView);
                    if (!visibleRect.IsEmpty)
                    {
                        ITextPointer visibleStart = textView.GetTextPositionFromPoint(visibleRect.TopLeft, true);
                        ITextPointer visibleEnd = textView.GetTextPositionFromPoint(visibleRect.BottomRight, true);
                        visibleTextSegments.Add(new TextSegment(visibleStart, visibleEnd, true));
                    }
                }

                // Create collection of TextRangeProviders for visible ranges.
                if (visibleTextSegments.Count > 0)
                {
                    ranges = new ITextRangeProvider[visibleTextSegments.Count];
                    for (int i = 0; i < visibleTextSegments.Count; i++)
                    {
                        ranges[i] = new TextRangeAdaptor(this, visibleTextSegments[i].Start, visibleTextSegments[i].End, _textPeer);
                    }
                }
            }
            // If no text is visible in the control, return the degenerate text range 
            // (empty range) at the beginning of the document.
            if (ranges == null)
            {
                ranges = new ITextRangeProvider[] { new TextRangeAdaptor(this, _textContainer.Start, _textContainer.Start, _textPeer) };
            }
            return ranges;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Searches for a subrange of text that has the specified attribute.  To search the entire document use the text provider's
        /// document range.
        /// </summary>
        /// <param name="attributeId">The attribute to search for.</param>
        /// <param name="value">The value of the specified attribute to search for.</param>
        /// <param name="backward">true if the last occurring range should be returned instead of the first.</param>
        /// <returns>A subrange with the specified attribute, or null if no such subrange exists.</returns>
        ITextRangeProvider ITextRangeProvider.FindAttribute(int attributeId, object value, bool backward)
        {
            AutomationTextAttribute attribute = AutomationTextAttribute.LookupById(attributeId);
            if (attribute == null)
            {
                throw new ArgumentNullException("attributeId");
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (!_textPatternAttributes.ContainsKey(attribute))
            {
                return null;
            }

            Normalize();

            ITextRangeProvider resultRange = null;
            ITextPointer attrStart = null;
            ITextPointer attrEnd = null;
            TextAttributeHelper attr = (TextAttributeHelper)_textPatternAttributes[attribute];
            if (backward)
            {
                ITextPointer stop = _start;
                ITextPointer position = _end.CreatePointer(LogicalDirection.Backward);

                // Go backward from the range end position until we find a position that 
                // has our attribute or we hit the start position of the search range.
                attrStart = stop;
                while (position.CompareTo(stop) > 0)
                {
                    if (attr.AreEqual(value, attr.GetValueAt(position)))
                    {
                        if (attrEnd == null)
                        {
                            attrEnd = position.CreatePointer(LogicalDirection.Backward);
                        }
                    }
                    else
                    {
                        if (attrEnd != null)
                        {
                            attrStart = position.CreatePointer(LogicalDirection.Forward);
                            break;
                        }
                    }
                    if (!position.MoveToNextContextPosition(LogicalDirection.Backward))
                    {
                        break;
                    }
                }
            }
            else
            {
                ITextPointer stop = _end;
                ITextPointer position = _start.CreatePointer(LogicalDirection.Forward);

                // Go backward from the range end position until we find a position that 
                // has our attribute or we hit the start position of the search range.
                attrEnd = stop;
                while (position.CompareTo(stop) < 0)
                {
                    if (attr.AreEqual(value, attr.GetValueAt(position)))
                    {
                        if (attrStart == null)
                        {
                            attrStart = position.CreatePointer(LogicalDirection.Forward);
                        }
                    }
                    else
                    {
                        if (attrStart != null)
                        {
                            attrEnd = position.CreatePointer(LogicalDirection.Backward);
                            break;
                        }
                    }
                    if (!position.MoveToNextContextPosition(LogicalDirection.Forward))
                    {
                        break;
                    }
                }
            }
            if (attrStart != null && attrEnd != null)
            {
                resultRange = new TextRangeAdaptor(_textAdaptor, attrStart, attrEnd, _textPeer);
            }

            return resultRange;
        }