Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / Annotations / Anchoring / TextSelectionHelper.cs / 1 / TextSelectionHelper.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // TextSelectionHelper is a helper class used by TextSelectionProvcrssor // and DynamicSelectionProcessor // // History: // 03/28/2004: ssimova: Created based on TextSelectionProcessor code // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Windows; using System.Windows.Annotations; using System.Windows.Annotations.Storage; using MS.Internal.Annotations.Component; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Documents; using System.Windows.Media; using System.Xml; using MS.Internal.Documents; using MS.Utility; namespace MS.Internal.Annotations.Anchoring { ////// TextSelectionHelper uses TextAnchors to represent portions /// of text that are anchors. It produces locator parts that /// represent these TextAnchors and can generate TextAnchors from /// the locator parts. /// internal class TextSelectionHelper { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// This ctor is added to prevent the compiler from /// generating a public default ctor. This class /// should not be instantiated /// private TextSelectionHelper() { } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Merges the two anchors into one, if possible. /// /// anchor to merge /// other anchor to merge /// new anchor that contains the data from both /// anchor1 and anchor2 ///true if the anchors were merged, false otherwise /// ///anchor1 or anchor2 are null public static bool MergeSelections(Object anchor1, Object anchor2, out Object newAnchor) { TextAnchor firstAnchor = anchor1 as TextAnchor; TextAnchor secondAnchor = anchor2 as TextAnchor; if ((anchor1 != null) && (firstAnchor == null)) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "anchor1: type = " + anchor1.GetType().ToString()); if ((anchor2 != null) && (secondAnchor == null)) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "Anchor2: type = " + anchor2.GetType().ToString()); if (firstAnchor == null) { newAnchor = secondAnchor; return newAnchor != null; } if (secondAnchor == null) { newAnchor = firstAnchor; return newAnchor != null; } newAnchor = TextAnchor.ExclusiveUnion(firstAnchor, secondAnchor); return true; } ////// Gets the tree elements spanned by the selection. /// /// the selection to examine ///a list of elements spanned by the selection; never returns /// null ///selection is null ///selection is of wrong type public static IListGetSelectedNodes(Object selection) { if (selection == null) throw new ArgumentNullException("selection"); IList segments; ITextPointer start = null; ITextPointer end = null; CheckSelection(selection, out start, out end, out segments); IList list = new List (); // If the selection is of length 0, then we simply add the parent of the // text container and return. if (start.CompareTo(end) == 0) { list.Add(((TextPointer)start).Parent); return list; } TextPointer current = (TextPointer)start.CreatePointer(); while (((ITextPointer)current).CompareTo(end) < 0) { DependencyObject node = current.Parent; if (!list.Contains(node)) { list.Add(node); } current.MoveToNextContextPosition(LogicalDirection.Forward); } return list; } /// /// Gets the parent element of this selection. /// /// the selection to examine ///the parent element of the selection; can be null ///selection is null ///selection is of wrong type public static UIElement GetParent(Object selection) { if (selection == null) throw new ArgumentNullException("selection"); ITextPointer start = null; ITextPointer end = null; IListsegments; CheckSelection(selection, out start, out end, out segments); return GetParent(start); } /// /// Gets the parent element of ITextPointer. /// /// the pointer to examine ///the parent element of this pointer; can be null ///pointer is null public static UIElement GetParent(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); DependencyObject document = pointer.TextContainer.Parent; DependencyObject parent = PathNode.GetParent(document); FlowDocumentScrollViewer scrollViewer = parent as FlowDocumentScrollViewer; if (scrollViewer != null) { return (UIElement)scrollViewer.ScrollViewer.Content; } // Special case - for paginated content we want the DocumentPageHost for the // specific page instead of the viewer. DocumentViewerBase documentViewerBase = parent as DocumentViewerBase; if (documentViewerBase != null) { int pageNumber; // We get the content again here GetPointerPage handles // special cases like FixedDocumentSequences IDocumentPaginatorSource content = GetPointerPage(pointer.CreatePointer(LogicalDirection.Forward), out pageNumber); if (pageNumber >= 0) { foreach (DocumentPageView dpv in documentViewerBase.PageViews) { if (dpv.PageNumber == pageNumber) { // DPVs always have one child - the DocumentPageHost int count = VisualTreeHelper.GetChildrenCount(dpv); Invariant.Assert(count == 1); return VisualTreeHelper.GetChild(dpv, 0) as DocumentPageHost; } } // Page must not be visible. return null; } } return parent as UIElement; } ////// Gets the anchor point for the selection /// /// the anchor to examine ////// The anchor point of the selection; /// If there is no valid AnchorPoint returns Point(Double.NaN, Double.NaN). /// ///anchor is null ///anchor is of wrong type public static Point GetAnchorPoint(Object selection) { if (selection == null) throw new ArgumentNullException("selection"); TextAnchor anchor = selection as TextAnchor; if (anchor == null) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "selection"); return GetAnchorPointForPointer(anchor.Start.CreatePointer(LogicalDirection.Forward)); } ////// Gets the anchor point for the text pointer /// /// the pointer to examine ////// The anchor point of the text pointer /// ///pointer is null public static Point GetAnchorPointForPointer(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); Rect rect = GetAnchorRectangle(pointer); if (rect != Rect.Empty) { return new Point(rect.Left, rect.Top + rect.Height); } return new Point(0, 0); } ////// Gets a point for the text pointer that can be turned back into /// the TextPointer at a later time. /// /// the pointer to examine ////// A point that can be turned back into the TextPointer at a later time /// ///pointer is null public static Point GetPointForPointer(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); Rect rect = GetAnchorRectangle(pointer); if (rect != Rect.Empty) { return new Point(rect.Left, rect.Top + rect.Height / 2); } return new Point(0, 0); } ////// Gets the rectangle for this ITextPointer /// /// the pointer to examine ////// The anchor point of the selection; /// If there is no valid AnchorPoint returns Point(Double.NaN, Double.NaN). /// ///pointer is null public static Rect GetAnchorRectangle(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); bool extension = false; ITextView textView = GetDocumentPageTextView(pointer); if (pointer.CompareTo(pointer.TextContainer.End) == 0) { //we can not get rectangle for the end of the TextContainer //so get the last symbol Point endPoint = new Point(Double.MaxValue, Double.MaxValue); pointer = textView.GetTextPositionFromPoint(endPoint, true); //we need to move the resulting rectangle at half space because //the geometry calculating function does the same extension = true; } if (textView != null && textView.IsValid && TextDocumentView.Contains(pointer, textView.TextSegments)) { Rect rect = textView.GetRectangleFromTextPosition(pointer); if (extension && rect != Rect.Empty) { rect.X += rect.Height / 2.0; } return rect; } return Rect.Empty; } ////// Gets DocumentViewerBase and a page number for specified TextPointer /// /// a TP from the container /// the page number ///DocumentViewerBase public static IDocumentPaginatorSource GetPointerPage(ITextPointer pointer, out int pageNumber) { Invariant.Assert(pointer != null, "unknown pointer"); IDocumentPaginatorSource idp = pointer.TextContainer.Parent as IDocumentPaginatorSource; FixedDocument fixedDoc = idp as FixedDocument; if (fixedDoc != null) { FixedDocumentSequence sequence = fixedDoc.Parent as FixedDocumentSequence; if (sequence != null) idp = sequence; } Invariant.Assert(idp != null); DynamicDocumentPaginator ddp = idp.DocumentPaginator as DynamicDocumentPaginator; pageNumber = ddp != null ? ddp.GetPageNumber((ContentPosition)pointer) : -1; return idp; } #endregion Public Methods //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods ////// Gets the start, end and text segments of the selection. Throws an exception if the /// selection is of the wrong type. /// internal static void CheckSelection(object selection, out ITextPointer start, out ITextPointer end, out IListsegments) { ITextRange textRange = selection as ITextRange; if (textRange != null) { start = textRange.Start; end = textRange.End; segments = textRange.TextSegments; } else { TextAnchor textAnchor = selection as TextAnchor; if (textAnchor == null) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "selection"); start = textAnchor.Start; end = textAnchor.End; segments = textAnchor.TextSegments; } } /// /// Gets the TextView exposed by the page where this pointer lives /// /// the pointer ///the TextView internal static ITextView GetDocumentPageTextView(ITextPointer pointer) { int pageNumber; DependencyObject content = pointer.TextContainer.Parent as DependencyObject; if (content != null) { FlowDocumentScrollViewer scrollViewer = PathNode.GetParent(content) as FlowDocumentScrollViewer; if (scrollViewer != null) { IServiceProvider provider = scrollViewer.ScrollViewer.Content as IServiceProvider; Invariant.Assert(provider != null, "FlowDocumentScrollViewer should be an IServiceProvider."); return provider.GetService(typeof(ITextView)) as ITextView; } } IDocumentPaginatorSource idp = GetPointerPage(pointer, out pageNumber); if (idp != null && pageNumber >= 0) { DocumentPage docPage = idp.DocumentPaginator.GetPage(pageNumber); IServiceProvider isp = docPage as IServiceProvider; if (isp != null) return isp.GetService(typeof(ITextView)) as ITextView; } return null; } ////// Gets a list of ITextViews spanned by this text segment /// /// the text segment ///the TextViews list internal static ListGetDocumentPageTextViews(TextSegment segment) { List res = null; int startPageNumber, endPageNumber; //revert the logical direction of the pointers ITextPointer start = segment.Start.CreatePointer(LogicalDirection.Forward); ITextPointer end = segment.End.CreatePointer(LogicalDirection.Backward); DependencyObject content = start.TextContainer.Parent as DependencyObject; if (content != null) { FlowDocumentScrollViewer scrollViewer = PathNode.GetParent(content) as FlowDocumentScrollViewer; if (scrollViewer != null) { IServiceProvider provider = scrollViewer.ScrollViewer.Content as IServiceProvider; Invariant.Assert(provider != null, "FlowDocumentScrollViewer should be an IServiceProvider."); res = new List (1); res.Add(provider.GetService(typeof(ITextView)) as ITextView); return res; } } IDocumentPaginatorSource idp = GetPointerPage(start, out startPageNumber); DynamicDocumentPaginator ddp = idp.DocumentPaginator as DynamicDocumentPaginator; endPageNumber = ddp != null ? ddp.GetPageNumber((ContentPosition)end) : -1; if (startPageNumber == -1 || endPageNumber == -1) { // If either page couldn't be found, we return an empty list. This // could be caused by a failure in paginating the document. res = new List (0); } else if (startPageNumber == endPageNumber) { res = ProcessSinglePage(idp, startPageNumber); } else { res = ProcessMultiplePages(idp, startPageNumber, endPageNumber); } return res; } #endregion Internal Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods /// /// Gets a single page TextView throug the idp.GetPage. cALL this API only when /// it is sure that the page is loaded /// /// IDocumentPaginatorSource /// page number ///returns a list of one view private static ListProcessSinglePage(IDocumentPaginatorSource idp, int pageNumber) { Invariant.Assert(idp != null, "IDocumentPaginatorSource is null"); DocumentPage docPage = idp.DocumentPaginator.GetPage(pageNumber); IServiceProvider isp = docPage as IServiceProvider; List res = null; if (isp != null) { res = new List (1); ITextView view = isp.GetService(typeof(ITextView)) as ITextView; if (view != null) res.Add(view); } return res; } /// /// Gets existing views for pages from start to end. Scans only existing view to /// avoid loading of unloaded pages. /// /// IDocumentPaginatorSource /// start page number /// end page number ///returns a list of text views private static ListProcessMultiplePages(IDocumentPaginatorSource idp, int startPageNumber, int endPageNumber) { Invariant.Assert(idp != null, "IDocumentPaginatorSource is null"); //now get available views DocumentViewerBase viewer = PathNode.GetParent(idp as DependencyObject) as DocumentViewerBase; Invariant.Assert(viewer != null, "DocumentViewer not found"); // If the pages for the text segment are reversed (possibly a floater where the floater // reflow on to a page that comes after its anchor) we just swap them if (endPageNumber < startPageNumber) { int temp = endPageNumber; endPageNumber = startPageNumber; startPageNumber = temp; } List res = null; if (idp != null && startPageNumber >= 0 && endPageNumber >= startPageNumber) { res = new List (endPageNumber - startPageNumber + 1); for (int pageNb = startPageNumber; pageNb <= endPageNumber; pageNb++) { DocumentPageView view = AnnotationHelper.FindView(viewer, pageNb); if (view != null) { IServiceProvider serviceProvider = view.DocumentPage as IServiceProvider; if (serviceProvider != null) { ITextView textView = serviceProvider.GetService(typeof(ITextView)) as ITextView; if (textView != null) res.Add(textView); } } } } return res; } #endregion Private Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // // // Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // TextSelectionHelper is a helper class used by TextSelectionProvcrssor // and DynamicSelectionProcessor // // History: // 03/28/2004: ssimova: Created based on TextSelectionProcessor code // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Windows; using System.Windows.Annotations; using System.Windows.Annotations.Storage; using MS.Internal.Annotations.Component; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Documents; using System.Windows.Media; using System.Xml; using MS.Internal.Documents; using MS.Utility; namespace MS.Internal.Annotations.Anchoring { ////// TextSelectionHelper uses TextAnchors to represent portions /// of text that are anchors. It produces locator parts that /// represent these TextAnchors and can generate TextAnchors from /// the locator parts. /// internal class TextSelectionHelper { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// This ctor is added to prevent the compiler from /// generating a public default ctor. This class /// should not be instantiated /// private TextSelectionHelper() { } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Merges the two anchors into one, if possible. /// /// anchor to merge /// other anchor to merge /// new anchor that contains the data from both /// anchor1 and anchor2 ///true if the anchors were merged, false otherwise /// ///anchor1 or anchor2 are null public static bool MergeSelections(Object anchor1, Object anchor2, out Object newAnchor) { TextAnchor firstAnchor = anchor1 as TextAnchor; TextAnchor secondAnchor = anchor2 as TextAnchor; if ((anchor1 != null) && (firstAnchor == null)) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "anchor1: type = " + anchor1.GetType().ToString()); if ((anchor2 != null) && (secondAnchor == null)) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "Anchor2: type = " + anchor2.GetType().ToString()); if (firstAnchor == null) { newAnchor = secondAnchor; return newAnchor != null; } if (secondAnchor == null) { newAnchor = firstAnchor; return newAnchor != null; } newAnchor = TextAnchor.ExclusiveUnion(firstAnchor, secondAnchor); return true; } ////// Gets the tree elements spanned by the selection. /// /// the selection to examine ///a list of elements spanned by the selection; never returns /// null ///selection is null ///selection is of wrong type public static IListGetSelectedNodes(Object selection) { if (selection == null) throw new ArgumentNullException("selection"); IList segments; ITextPointer start = null; ITextPointer end = null; CheckSelection(selection, out start, out end, out segments); IList list = new List (); // If the selection is of length 0, then we simply add the parent of the // text container and return. if (start.CompareTo(end) == 0) { list.Add(((TextPointer)start).Parent); return list; } TextPointer current = (TextPointer)start.CreatePointer(); while (((ITextPointer)current).CompareTo(end) < 0) { DependencyObject node = current.Parent; if (!list.Contains(node)) { list.Add(node); } current.MoveToNextContextPosition(LogicalDirection.Forward); } return list; } /// /// Gets the parent element of this selection. /// /// the selection to examine ///the parent element of the selection; can be null ///selection is null ///selection is of wrong type public static UIElement GetParent(Object selection) { if (selection == null) throw new ArgumentNullException("selection"); ITextPointer start = null; ITextPointer end = null; IListsegments; CheckSelection(selection, out start, out end, out segments); return GetParent(start); } /// /// Gets the parent element of ITextPointer. /// /// the pointer to examine ///the parent element of this pointer; can be null ///pointer is null public static UIElement GetParent(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); DependencyObject document = pointer.TextContainer.Parent; DependencyObject parent = PathNode.GetParent(document); FlowDocumentScrollViewer scrollViewer = parent as FlowDocumentScrollViewer; if (scrollViewer != null) { return (UIElement)scrollViewer.ScrollViewer.Content; } // Special case - for paginated content we want the DocumentPageHost for the // specific page instead of the viewer. DocumentViewerBase documentViewerBase = parent as DocumentViewerBase; if (documentViewerBase != null) { int pageNumber; // We get the content again here GetPointerPage handles // special cases like FixedDocumentSequences IDocumentPaginatorSource content = GetPointerPage(pointer.CreatePointer(LogicalDirection.Forward), out pageNumber); if (pageNumber >= 0) { foreach (DocumentPageView dpv in documentViewerBase.PageViews) { if (dpv.PageNumber == pageNumber) { // DPVs always have one child - the DocumentPageHost int count = VisualTreeHelper.GetChildrenCount(dpv); Invariant.Assert(count == 1); return VisualTreeHelper.GetChild(dpv, 0) as DocumentPageHost; } } // Page must not be visible. return null; } } return parent as UIElement; } ////// Gets the anchor point for the selection /// /// the anchor to examine ////// The anchor point of the selection; /// If there is no valid AnchorPoint returns Point(Double.NaN, Double.NaN). /// ///anchor is null ///anchor is of wrong type public static Point GetAnchorPoint(Object selection) { if (selection == null) throw new ArgumentNullException("selection"); TextAnchor anchor = selection as TextAnchor; if (anchor == null) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "selection"); return GetAnchorPointForPointer(anchor.Start.CreatePointer(LogicalDirection.Forward)); } ////// Gets the anchor point for the text pointer /// /// the pointer to examine ////// The anchor point of the text pointer /// ///pointer is null public static Point GetAnchorPointForPointer(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); Rect rect = GetAnchorRectangle(pointer); if (rect != Rect.Empty) { return new Point(rect.Left, rect.Top + rect.Height); } return new Point(0, 0); } ////// Gets a point for the text pointer that can be turned back into /// the TextPointer at a later time. /// /// the pointer to examine ////// A point that can be turned back into the TextPointer at a later time /// ///pointer is null public static Point GetPointForPointer(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); Rect rect = GetAnchorRectangle(pointer); if (rect != Rect.Empty) { return new Point(rect.Left, rect.Top + rect.Height / 2); } return new Point(0, 0); } ////// Gets the rectangle for this ITextPointer /// /// the pointer to examine ////// The anchor point of the selection; /// If there is no valid AnchorPoint returns Point(Double.NaN, Double.NaN). /// ///pointer is null public static Rect GetAnchorRectangle(ITextPointer pointer) { if (pointer == null) throw new ArgumentNullException("pointer"); bool extension = false; ITextView textView = GetDocumentPageTextView(pointer); if (pointer.CompareTo(pointer.TextContainer.End) == 0) { //we can not get rectangle for the end of the TextContainer //so get the last symbol Point endPoint = new Point(Double.MaxValue, Double.MaxValue); pointer = textView.GetTextPositionFromPoint(endPoint, true); //we need to move the resulting rectangle at half space because //the geometry calculating function does the same extension = true; } if (textView != null && textView.IsValid && TextDocumentView.Contains(pointer, textView.TextSegments)) { Rect rect = textView.GetRectangleFromTextPosition(pointer); if (extension && rect != Rect.Empty) { rect.X += rect.Height / 2.0; } return rect; } return Rect.Empty; } ////// Gets DocumentViewerBase and a page number for specified TextPointer /// /// a TP from the container /// the page number ///DocumentViewerBase public static IDocumentPaginatorSource GetPointerPage(ITextPointer pointer, out int pageNumber) { Invariant.Assert(pointer != null, "unknown pointer"); IDocumentPaginatorSource idp = pointer.TextContainer.Parent as IDocumentPaginatorSource; FixedDocument fixedDoc = idp as FixedDocument; if (fixedDoc != null) { FixedDocumentSequence sequence = fixedDoc.Parent as FixedDocumentSequence; if (sequence != null) idp = sequence; } Invariant.Assert(idp != null); DynamicDocumentPaginator ddp = idp.DocumentPaginator as DynamicDocumentPaginator; pageNumber = ddp != null ? ddp.GetPageNumber((ContentPosition)pointer) : -1; return idp; } #endregion Public Methods //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods ////// Gets the start, end and text segments of the selection. Throws an exception if the /// selection is of the wrong type. /// internal static void CheckSelection(object selection, out ITextPointer start, out ITextPointer end, out IListsegments) { ITextRange textRange = selection as ITextRange; if (textRange != null) { start = textRange.Start; end = textRange.End; segments = textRange.TextSegments; } else { TextAnchor textAnchor = selection as TextAnchor; if (textAnchor == null) throw new ArgumentException(SR.Get(SRID.WrongSelectionType), "selection"); start = textAnchor.Start; end = textAnchor.End; segments = textAnchor.TextSegments; } } /// /// Gets the TextView exposed by the page where this pointer lives /// /// the pointer ///the TextView internal static ITextView GetDocumentPageTextView(ITextPointer pointer) { int pageNumber; DependencyObject content = pointer.TextContainer.Parent as DependencyObject; if (content != null) { FlowDocumentScrollViewer scrollViewer = PathNode.GetParent(content) as FlowDocumentScrollViewer; if (scrollViewer != null) { IServiceProvider provider = scrollViewer.ScrollViewer.Content as IServiceProvider; Invariant.Assert(provider != null, "FlowDocumentScrollViewer should be an IServiceProvider."); return provider.GetService(typeof(ITextView)) as ITextView; } } IDocumentPaginatorSource idp = GetPointerPage(pointer, out pageNumber); if (idp != null && pageNumber >= 0) { DocumentPage docPage = idp.DocumentPaginator.GetPage(pageNumber); IServiceProvider isp = docPage as IServiceProvider; if (isp != null) return isp.GetService(typeof(ITextView)) as ITextView; } return null; } ////// Gets a list of ITextViews spanned by this text segment /// /// the text segment ///the TextViews list internal static ListGetDocumentPageTextViews(TextSegment segment) { List res = null; int startPageNumber, endPageNumber; //revert the logical direction of the pointers ITextPointer start = segment.Start.CreatePointer(LogicalDirection.Forward); ITextPointer end = segment.End.CreatePointer(LogicalDirection.Backward); DependencyObject content = start.TextContainer.Parent as DependencyObject; if (content != null) { FlowDocumentScrollViewer scrollViewer = PathNode.GetParent(content) as FlowDocumentScrollViewer; if (scrollViewer != null) { IServiceProvider provider = scrollViewer.ScrollViewer.Content as IServiceProvider; Invariant.Assert(provider != null, "FlowDocumentScrollViewer should be an IServiceProvider."); res = new List (1); res.Add(provider.GetService(typeof(ITextView)) as ITextView); return res; } } IDocumentPaginatorSource idp = GetPointerPage(start, out startPageNumber); DynamicDocumentPaginator ddp = idp.DocumentPaginator as DynamicDocumentPaginator; endPageNumber = ddp != null ? ddp.GetPageNumber((ContentPosition)end) : -1; if (startPageNumber == -1 || endPageNumber == -1) { // If either page couldn't be found, we return an empty list. This // could be caused by a failure in paginating the document. res = new List (0); } else if (startPageNumber == endPageNumber) { res = ProcessSinglePage(idp, startPageNumber); } else { res = ProcessMultiplePages(idp, startPageNumber, endPageNumber); } return res; } #endregion Internal Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods /// /// Gets a single page TextView throug the idp.GetPage. cALL this API only when /// it is sure that the page is loaded /// /// IDocumentPaginatorSource /// page number ///returns a list of one view private static ListProcessSinglePage(IDocumentPaginatorSource idp, int pageNumber) { Invariant.Assert(idp != null, "IDocumentPaginatorSource is null"); DocumentPage docPage = idp.DocumentPaginator.GetPage(pageNumber); IServiceProvider isp = docPage as IServiceProvider; List res = null; if (isp != null) { res = new List (1); ITextView view = isp.GetService(typeof(ITextView)) as ITextView; if (view != null) res.Add(view); } return res; } /// /// Gets existing views for pages from start to end. Scans only existing view to /// avoid loading of unloaded pages. /// /// IDocumentPaginatorSource /// start page number /// end page number ///returns a list of text views private static ListProcessMultiplePages(IDocumentPaginatorSource idp, int startPageNumber, int endPageNumber) { Invariant.Assert(idp != null, "IDocumentPaginatorSource is null"); //now get available views DocumentViewerBase viewer = PathNode.GetParent(idp as DependencyObject) as DocumentViewerBase; Invariant.Assert(viewer != null, "DocumentViewer not found"); // If the pages for the text segment are reversed (possibly a floater where the floater // reflow on to a page that comes after its anchor) we just swap them if (endPageNumber < startPageNumber) { int temp = endPageNumber; endPageNumber = startPageNumber; startPageNumber = temp; } List res = null; if (idp != null && startPageNumber >= 0 && endPageNumber >= startPageNumber) { res = new List (endPageNumber - startPageNumber + 1); for (int pageNb = startPageNumber; pageNb <= endPageNumber; pageNb++) { DocumentPageView view = AnnotationHelper.FindView(viewer, pageNb); if (view != null) { IServiceProvider serviceProvider = view.DocumentPage as IServiceProvider; if (serviceProvider != null) { ITextView textView = serviceProvider.GetService(typeof(ITextView)) as ITextView; if (textView != null) res.Add(textView); } } } } return res; } #endregion Private Methods } } // 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
- X509WindowsSecurityToken.cs
- loginstatus.cs
- SplitContainerDesigner.cs
- ServiceErrorHandler.cs
- FontWeightConverter.cs
- VisualTreeUtils.cs
- SerializationStore.cs
- XmlSchemaImporter.cs
- NamedPipeProcessProtocolHandler.cs
- LocatorPartList.cs
- RichTextBoxConstants.cs
- SQLByte.cs
- TextDecorationCollection.cs
- MouseGestureConverter.cs
- OdbcParameterCollection.cs
- httpstaticobjectscollection.cs
- ObjectView.cs
- UITypeEditor.cs
- SiteMap.cs
- GroupBox.cs
- ReaderOutput.cs
- SqlDataSourceView.cs
- uribuilder.cs
- CLRBindingWorker.cs
- ManualWorkflowSchedulerService.cs
- EngineSiteSapi.cs
- Transform.cs
- DataSourceGeneratorException.cs
- ParameterElementCollection.cs
- DefaultTextStoreTextComposition.cs
- ExpressionPrefixAttribute.cs
- AssemblyUtil.cs
- DebuggerAttributes.cs
- NodeFunctions.cs
- WebPartVerbCollection.cs
- SecurityElement.cs
- ProxyWebPartManager.cs
- BitmapEffectCollection.cs
- ECDiffieHellmanCngPublicKey.cs
- ObjectHandle.cs
- CryptoApi.cs
- OdbcError.cs
- ComponentResourceManager.cs
- ComplexTypeEmitter.cs
- ApplySecurityAndSendAsyncResult.cs
- StateItem.cs
- PkcsUtils.cs
- TemplateControlBuildProvider.cs
- NameObjectCollectionBase.cs
- EnlistmentTraceIdentifier.cs
- DateTimeUtil.cs
- ResourceExpression.cs
- InfoCardSymmetricCrypto.cs
- UTF7Encoding.cs
- AttributeQuery.cs
- MenuTracker.cs
- DeclarativeCatalogPart.cs
- CheckBoxPopupAdapter.cs
- EventsTab.cs
- AcceleratedTokenProviderState.cs
- IntellisenseTextBox.designer.cs
- RepeaterCommandEventArgs.cs
- ConsoleCancelEventArgs.cs
- ISCIIEncoding.cs
- BitmapEffectInputConnector.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- Thickness.cs
- IDReferencePropertyAttribute.cs
- TaiwanCalendar.cs
- PackageProperties.cs
- ChtmlTextWriter.cs
- XmlDataProvider.cs
- FontStretch.cs
- TextContainer.cs
- AsymmetricSignatureDeformatter.cs
- _ConnectStream.cs
- SoundPlayerAction.cs
- MessageEncodingBindingElementImporter.cs
- Attributes.cs
- Graphics.cs
- InvalidOperationException.cs
- StrokeNode.cs
- ClientScriptManager.cs
- EntityDataSourceReferenceGroup.cs
- DownloadProgressEventArgs.cs
- GroupBox.cs
- NopReturnReader.cs
- ScriptResourceInfo.cs
- DesigntimeLicenseContextSerializer.cs
- RIPEMD160.cs
- BlurBitmapEffect.cs
- DesignerWithHeader.cs
- BinaryWriter.cs
- BinaryWriter.cs
- TextSchema.cs
- SplineKeyFrames.cs
- Sql8ExpressionRewriter.cs
- ThrowHelper.cs
- CachedPathData.cs
- DiscardableAttribute.cs