Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / Annotations / AnnotationDocumentPaginator.cs / 1 / AnnotationDocumentPaginator.cs
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
//
// Spec: http://team/sites/ag/Specifications/ NEED SPEC
//
// History:
// 06/14/2005: rruiz: Created new class for printing support.
//
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows.Annotations.Storage;
using System.Windows.Documents;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Shapes;
using MS.Internal;
using MS.Internal.Annotations;
using MS.Internal.Annotations.Anchoring;
using MS.Internal.Annotations.Component;
using MS.Internal.Documents;
namespace System.Windows.Annotations
{
///
///
///
public sealed class AnnotationDocumentPaginator : DocumentPaginator
{
//-----------------------------------------------------
//
// Public Constructors
//
//-----------------------------------------------------
#region Public Constructors
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, Stream annotationStore) : this(originalPaginator, new XmlStreamStore(annotationStore), FlowDirection.LeftToRight)
{
}
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
///
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, Stream annotationStore, FlowDirection flowDirection) : this(originalPaginator, new XmlStreamStore(annotationStore), flowDirection)
{
}
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, AnnotationStore annotationStore) : this(originalPaginator, annotationStore, FlowDirection.LeftToRight)
{
}
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
///
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, AnnotationStore annotationStore, FlowDirection flowDirection)
{
_isFixedContent = originalPaginator is FixedDocumentPaginator || originalPaginator is FixedDocumentSequencePaginator;
if (!_isFixedContent && !(originalPaginator is FlowDocumentPaginator))
throw new ArgumentException(SR.Get(SRID.OnlyFlowAndFixedSupported));
_originalPaginator = originalPaginator;
_annotationStore = annotationStore;
_locatorManager = new LocatorManager(_annotationStore);
_flowDirection = flowDirection;
// Register for events
_originalPaginator.GetPageCompleted += new GetPageCompletedEventHandler(HandleGetPageCompleted);
_originalPaginator.ComputePageCountCompleted += new AsyncCompletedEventHandler(HandleComputePageCountCompleted);
_originalPaginator.PagesChanged += new PagesChangedEventHandler(HandlePagesChanged);
}
#endregion Public Constructors
//------------------------------------------------------
//
// Public Properties
//
//-----------------------------------------------------
#region Public Properties
///
/// Whether PageCount is currently valid. If False, then the value of
/// PageCount is the number of pages that have currently been formatted.
///
///
/// This value may revert to False after being True, in cases where
/// PageSize or content changes, forcing a repagination.
///
public override bool IsPageCountValid
{
get { return _originalPaginator.IsPageCountValid; }
}
///
/// If IsPageCountValid is True, this value is the number of pages
/// of content. If False, this is the number of pages that have
/// currently been formatted.
///
///
/// Value may change depending upon changes in PageSize or content changes.
///
public override int PageCount
{
get { return _originalPaginator.PageCount; }
}
///
/// The suggested size for formatting pages.
///
///
/// Note that the paginator may override the specified page size. Users
/// should check DocumentPage.Size.
///
public override Size PageSize
{
get { return _originalPaginator.PageSize; }
set { _originalPaginator.PageSize = value; }
}
///
///
///
public override IDocumentPaginatorSource Source
{
get { return _originalPaginator.Source; }
}
#endregion Public Properties
//------------------------------------------------------
//
// Public Methods
//
//------------------------------------------------------
#region Public Methods
///
/// Retrieves the DocumentPage for the given page number. PageNumber
/// is zero-based.
///
/// Page number.
///
/// Returns DocumentPage.Missing if the given page does not exist.
///
///
/// Multiple requests for the same page number may return the same
/// object (this is implementation specific).
///
///
/// Throws ArgumentOutOfRangeException if PageNumber is negative.
///
public override DocumentPage GetPage(int pageNumber)
{
DocumentPage documentPage = _originalPaginator.GetPage(pageNumber);
if (documentPage != DocumentPage.Missing)
{
documentPage = ComposePageWithAnnotationVisuals(pageNumber, documentPage);
}
return documentPage;
}
///
/// Async version of
///
/// Page number.
/// Unique identifier for the asynchronous task.
///
/// Throws ArgumentOutOfRangeException if PageNumber is negative.
///
public override void GetPageAsync(int pageNumber, object userState)
{
_originalPaginator.GetPageAsync(pageNumber, userState);
}
///
/// Computes the number of pages of content. IsPageCountValid will be
/// True immediately after this is called.
///
///
/// If content is modified or PageSize is changed (or any other change
/// that causes a repagination) after this method is called,
/// IsPageCountValid will likely revert to False.
///
public override void ComputePageCount()
{
_originalPaginator.ComputePageCount();
}
///
/// Async version of
///
/// Unique identifier for the asynchronous task.
public override void ComputePageCountAsync(object userState)
{
_originalPaginator.ComputePageCountAsync(userState);
}
///
/// Cancels all asynchronous calls made with the given userState.
/// If userState is NULL, all asynchronous calls are cancelled.
///
/// Unique identifier for the asynchronous task.
public override void CancelAsync(object userState)
{
_originalPaginator.CancelAsync(userState);
}
#endregion Public Methods
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
///
/// We are being notified by the wrapped paginator. If getting the page
/// was successful, we use the resulting page to produce a new page that
/// includes annotatons. In either case, we fire an event from this instance.
///
/// source of the event
/// the args for this event
private void HandleGetPageCompleted(object sender, GetPageCompletedEventArgs e)
{
// If no errors, not cancelled, and page isn't missing, create a new page
// with annotations and create a new event args for that page.
if (!e.Cancelled && e.Error == null && e.DocumentPage != DocumentPage.Missing)
{
// Since we can't change the page the args is holding we create a new
// args object with the page we produce.
DocumentPage documentPage = ComposePageWithAnnotationVisuals(e.PageNumber, e.DocumentPage);
e = new GetPageCompletedEventArgs(documentPage, e.PageNumber, e.Error, e.Cancelled, e.UserState);
}
// Fire the event
OnGetPageCompleted(e);
}
///
/// We are notified by the wrapped paginator. In response we fire
/// an event from this instance.
///
/// source of the event
/// args for the event
private void HandleComputePageCountCompleted(object sender, AsyncCompletedEventArgs e)
{
// Fire the event
OnComputePageCountCompleted(e);
}
///
/// We are notified by the wrapped paginator. In response we fire
/// an event from this instance.
///
/// source of the event
/// args for the event
private void HandlePagesChanged(object sender, PagesChangedEventArgs e)
{
// Fire the event
OnPagesChanged(e);
}
///
/// For a given page # and a page, returns a page that include the original
/// page along with any annotations that are displayed on that page.
///
///
///
private DocumentPage ComposePageWithAnnotationVisuals(int pageNumber, DocumentPage page)
{
// Need to store these because our current highlight mechanism
// causes the page to be disposed
Size tempSize = page.Size;
AdornerDecorator decorator = new AdornerDecorator();
decorator.FlowDirection = _flowDirection;
DocumentPageView dpv = new DocumentPageView();
dpv.UseAsynchronousGetPage = false;
dpv.DocumentPaginator = _originalPaginator;
dpv.PageNumber = pageNumber;
decorator.Child = dpv;
// Arrange the first time to get the DPV setup right
decorator.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
decorator.Arrange(new Rect(decorator.DesiredSize));
decorator.UpdateLayout();
// Create a new one for each page because it keeps a cache of annotation components
// and we don't want to be holding them in memory once the page is no longer used
AnnotationComponentManager manager = new MS.Internal.Annotations.Component.AnnotationComponentManager(null);
// Setup DPs and processors for annotation handling. If the service isn't already
// enabled the processors will be registered by the service when it is enabled.
if (_isFixedContent)
{
// Setup service to look for FixedPages in the content
AnnotationService.SetSubTreeProcessorId(decorator, FixedPageProcessor.Id);
// If the service is already registered, set it up for fixed content
_locatorManager.RegisterSelectionProcessor(new FixedTextSelectionProcessor(), typeof(TextRange));
}
else
{
// Setup up an initial DataId used to identify the document
AnnotationService.SetDataId(decorator, "FlowDocument");
_locatorManager.RegisterSelectionProcessor(new TextViewSelectionProcessor(), typeof(DocumentPageView));
// Setup the selection processor, pre-targeting it at a specific DocumentPageView
TextSelectionProcessor textSelectionProcessor = new TextSelectionProcessor();
textSelectionProcessor.SetTargetDocumentPageView(dpv);
_locatorManager.RegisterSelectionProcessor(textSelectionProcessor, typeof(TextRange));
}
// Get attached annotations for the page
IList attachedAnnotations = ProcessAnnotations(dpv);
// Now make sure they have a visual component added to the DPV via the component manager
foreach (IAttachedAnnotation attachedAnnotation in attachedAnnotations)
{
if (attachedAnnotation.AttachmentLevel != AttachmentLevel.Unresolved && attachedAnnotation.AttachmentLevel != AttachmentLevel.Incomplete)
{
manager.AddAttachedAnnotation(attachedAnnotation, false);
}
}
// Update layout a second time to get the annotations layed out correctly
decorator.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
decorator.Arrange(new Rect(decorator.DesiredSize));
decorator.UpdateLayout();
/* Look into using the VisualBrush in order to get a dead page instead of a live one...
VisualBrush visualBrush = new VisualBrush(decorator);
Rectangle rectangle = new Rectangle();
rectangle.Fill = visualBrush;
rectangle.Margin = new Thickness(0);
*/
return new AnnotatedDocumentPage(page, decorator, tempSize, new Rect(tempSize), new Rect(tempSize));
}
private IList ProcessAnnotations(DocumentPageView dpv)
{
if (dpv == null)
throw new ArgumentNullException("dpv");
IList attachedAnnotations = new List();
IList locators = _locatorManager.GenerateLocators(dpv);
if (locators.Count > 0)
{
// LocatorBases for a single node should always be Locators
ContentLocator[] lists = new ContentLocator[locators.Count];
locators.CopyTo(lists, 0);
IList annotations = _annotationStore.GetAnnotations(lists[0]);
foreach (ContentLocator locator in locators)
{
if (locator.Parts[locator.Parts.Count - 1].NameValuePairs.ContainsKey(TextSelectionProcessor.IncludeOverlaps))
{
locator.Parts.RemoveAt(locator.Parts.Count - 1);
}
}
foreach (Annotation annotation in annotations)
{
foreach (AnnotationResource anchor in annotation.Anchors)
{
foreach (ContentLocatorBase locator in anchor.ContentLocators)
{
AttachmentLevel attachmentLevel;
object attachedAnchor = _locatorManager.FindAttachedAnchor(dpv, lists, locator, out attachmentLevel);
if (attachmentLevel != AttachmentLevel.Unresolved)
{
Invariant.Assert(VisualTreeHelper.GetChildrenCount(dpv) == 1, "DocumentPageView has no visual children.");
DependencyObject firstElement = VisualTreeHelper.GetChild(dpv, 0);
attachedAnnotations.Add(new AttachedAnnotation(_locatorManager, annotation, anchor, attachedAnchor, attachmentLevel, firstElement as DocumentPageHost));
// Only process one locator per resource
break;
}
}
}
}
}
return attachedAnnotations;
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Classes
///
/// AnnotationDocumentPage implements IContentHost and delegates all calls
/// to the wrapped DocumentPage. This allows XPS serialization to make use
/// of the IContentHost info from the wrapped page in order to provide
/// clickable hyperlinks.
///
private class AnnotatedDocumentPage : DocumentPage, IContentHost
{
///
/// Creates an AnnotationDocumentPage for the wrapped page with the specified
/// visual and sizes.
///
public AnnotatedDocumentPage(DocumentPage basePage, Visual visual, Size pageSize, Rect bleedBox, Rect contentBox)
: base(visual, pageSize, bleedBox, contentBox)
{
_basePage = basePage as IContentHost;
}
///
/// Returns the set of HostedElements in this page.
///
public IEnumerator HostedElements
{
get
{
if (_basePage != null)
{
return _basePage.HostedElements;
}
else
{
return new HostedElements(new ReadOnlyCollection(new List(0)));
}
}
}
///
/// Returns the rectangles that are 'hot spots' for the specified element.
///
public ReadOnlyCollection GetRectangles(ContentElement child)
{
if (_basePage != null)
{
return _basePage.GetRectangles(child);
}
else
{
return new ReadOnlyCollection(new List(0));
}
}
///
/// Performs a hit-test with the given point on this page.
///
public IInputElement InputHitTest(Point point)
{
if (_basePage != null)
{
return _basePage.InputHitTest(point);
}
else
{
return null;
}
}
///
/// Lets the page recalculate the rectangles for this element when its desired
/// size has changed.
///
public void OnChildDesiredSizeChanged(UIElement child)
{
if (_basePage != null)
{
_basePage.OnChildDesiredSizeChanged(child);
}
}
// DocumentPage being wrapped by this DocumentPage
private IContentHost _basePage;
}
#endregion Private Classes
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
// Store used to retrieve annotations from
private AnnotationStore _annotationStore;
// Document we are loading annotations for
private DocumentPaginator _originalPaginator;
// LocatorManager used to generate and resolve locators
private LocatorManager _locatorManager;
// Specifies whether the paginator is for fixed content
private bool _isFixedContent;
// FlowDirection to use when laying the annotations out
private FlowDirection _flowDirection;
#endregion Private Fields
}
}
// 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:
//
// Spec: http://team/sites/ag/Specifications/ NEED SPEC
//
// History:
// 06/14/2005: rruiz: Created new class for printing support.
//
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows.Annotations.Storage;
using System.Windows.Documents;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Shapes;
using MS.Internal;
using MS.Internal.Annotations;
using MS.Internal.Annotations.Anchoring;
using MS.Internal.Annotations.Component;
using MS.Internal.Documents;
namespace System.Windows.Annotations
{
///
///
///
public sealed class AnnotationDocumentPaginator : DocumentPaginator
{
//-----------------------------------------------------
//
// Public Constructors
//
//-----------------------------------------------------
#region Public Constructors
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, Stream annotationStore) : this(originalPaginator, new XmlStreamStore(annotationStore), FlowDirection.LeftToRight)
{
}
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
///
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, Stream annotationStore, FlowDirection flowDirection) : this(originalPaginator, new XmlStreamStore(annotationStore), flowDirection)
{
}
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, AnnotationStore annotationStore) : this(originalPaginator, annotationStore, FlowDirection.LeftToRight)
{
}
///
/// Create an instance of AnnotationDocumentPaginator for a given document and annotation store.
///
/// document to add annotations to
/// store to retrieve annotations from
///
public AnnotationDocumentPaginator(DocumentPaginator originalPaginator, AnnotationStore annotationStore, FlowDirection flowDirection)
{
_isFixedContent = originalPaginator is FixedDocumentPaginator || originalPaginator is FixedDocumentSequencePaginator;
if (!_isFixedContent && !(originalPaginator is FlowDocumentPaginator))
throw new ArgumentException(SR.Get(SRID.OnlyFlowAndFixedSupported));
_originalPaginator = originalPaginator;
_annotationStore = annotationStore;
_locatorManager = new LocatorManager(_annotationStore);
_flowDirection = flowDirection;
// Register for events
_originalPaginator.GetPageCompleted += new GetPageCompletedEventHandler(HandleGetPageCompleted);
_originalPaginator.ComputePageCountCompleted += new AsyncCompletedEventHandler(HandleComputePageCountCompleted);
_originalPaginator.PagesChanged += new PagesChangedEventHandler(HandlePagesChanged);
}
#endregion Public Constructors
//------------------------------------------------------
//
// Public Properties
//
//-----------------------------------------------------
#region Public Properties
///
/// Whether PageCount is currently valid. If False, then the value of
/// PageCount is the number of pages that have currently been formatted.
///
///
/// This value may revert to False after being True, in cases where
/// PageSize or content changes, forcing a repagination.
///
public override bool IsPageCountValid
{
get { return _originalPaginator.IsPageCountValid; }
}
///
/// If IsPageCountValid is True, this value is the number of pages
/// of content. If False, this is the number of pages that have
/// currently been formatted.
///
///
/// Value may change depending upon changes in PageSize or content changes.
///
public override int PageCount
{
get { return _originalPaginator.PageCount; }
}
///
/// The suggested size for formatting pages.
///
///
/// Note that the paginator may override the specified page size. Users
/// should check DocumentPage.Size.
///
public override Size PageSize
{
get { return _originalPaginator.PageSize; }
set { _originalPaginator.PageSize = value; }
}
///
///
///
public override IDocumentPaginatorSource Source
{
get { return _originalPaginator.Source; }
}
#endregion Public Properties
//------------------------------------------------------
//
// Public Methods
//
//------------------------------------------------------
#region Public Methods
///
/// Retrieves the DocumentPage for the given page number. PageNumber
/// is zero-based.
///
/// Page number.
///
/// Returns DocumentPage.Missing if the given page does not exist.
///
///
/// Multiple requests for the same page number may return the same
/// object (this is implementation specific).
///
///
/// Throws ArgumentOutOfRangeException if PageNumber is negative.
///
public override DocumentPage GetPage(int pageNumber)
{
DocumentPage documentPage = _originalPaginator.GetPage(pageNumber);
if (documentPage != DocumentPage.Missing)
{
documentPage = ComposePageWithAnnotationVisuals(pageNumber, documentPage);
}
return documentPage;
}
///
/// Async version of
///
/// Page number.
/// Unique identifier for the asynchronous task.
///
/// Throws ArgumentOutOfRangeException if PageNumber is negative.
///
public override void GetPageAsync(int pageNumber, object userState)
{
_originalPaginator.GetPageAsync(pageNumber, userState);
}
///
/// Computes the number of pages of content. IsPageCountValid will be
/// True immediately after this is called.
///
///
/// If content is modified or PageSize is changed (or any other change
/// that causes a repagination) after this method is called,
/// IsPageCountValid will likely revert to False.
///
public override void ComputePageCount()
{
_originalPaginator.ComputePageCount();
}
///
/// Async version of
///
/// Unique identifier for the asynchronous task.
public override void ComputePageCountAsync(object userState)
{
_originalPaginator.ComputePageCountAsync(userState);
}
///
/// Cancels all asynchronous calls made with the given userState.
/// If userState is NULL, all asynchronous calls are cancelled.
///
/// Unique identifier for the asynchronous task.
public override void CancelAsync(object userState)
{
_originalPaginator.CancelAsync(userState);
}
#endregion Public Methods
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
///
/// We are being notified by the wrapped paginator. If getting the page
/// was successful, we use the resulting page to produce a new page that
/// includes annotatons. In either case, we fire an event from this instance.
///
/// source of the event
/// the args for this event
private void HandleGetPageCompleted(object sender, GetPageCompletedEventArgs e)
{
// If no errors, not cancelled, and page isn't missing, create a new page
// with annotations and create a new event args for that page.
if (!e.Cancelled && e.Error == null && e.DocumentPage != DocumentPage.Missing)
{
// Since we can't change the page the args is holding we create a new
// args object with the page we produce.
DocumentPage documentPage = ComposePageWithAnnotationVisuals(e.PageNumber, e.DocumentPage);
e = new GetPageCompletedEventArgs(documentPage, e.PageNumber, e.Error, e.Cancelled, e.UserState);
}
// Fire the event
OnGetPageCompleted(e);
}
///
/// We are notified by the wrapped paginator. In response we fire
/// an event from this instance.
///
/// source of the event
/// args for the event
private void HandleComputePageCountCompleted(object sender, AsyncCompletedEventArgs e)
{
// Fire the event
OnComputePageCountCompleted(e);
}
///
/// We are notified by the wrapped paginator. In response we fire
/// an event from this instance.
///
/// source of the event
/// args for the event
private void HandlePagesChanged(object sender, PagesChangedEventArgs e)
{
// Fire the event
OnPagesChanged(e);
}
///
/// For a given page # and a page, returns a page that include the original
/// page along with any annotations that are displayed on that page.
///
///
///
private DocumentPage ComposePageWithAnnotationVisuals(int pageNumber, DocumentPage page)
{
// Need to store these because our current highlight mechanism
// causes the page to be disposed
Size tempSize = page.Size;
AdornerDecorator decorator = new AdornerDecorator();
decorator.FlowDirection = _flowDirection;
DocumentPageView dpv = new DocumentPageView();
dpv.UseAsynchronousGetPage = false;
dpv.DocumentPaginator = _originalPaginator;
dpv.PageNumber = pageNumber;
decorator.Child = dpv;
// Arrange the first time to get the DPV setup right
decorator.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
decorator.Arrange(new Rect(decorator.DesiredSize));
decorator.UpdateLayout();
// Create a new one for each page because it keeps a cache of annotation components
// and we don't want to be holding them in memory once the page is no longer used
AnnotationComponentManager manager = new MS.Internal.Annotations.Component.AnnotationComponentManager(null);
// Setup DPs and processors for annotation handling. If the service isn't already
// enabled the processors will be registered by the service when it is enabled.
if (_isFixedContent)
{
// Setup service to look for FixedPages in the content
AnnotationService.SetSubTreeProcessorId(decorator, FixedPageProcessor.Id);
// If the service is already registered, set it up for fixed content
_locatorManager.RegisterSelectionProcessor(new FixedTextSelectionProcessor(), typeof(TextRange));
}
else
{
// Setup up an initial DataId used to identify the document
AnnotationService.SetDataId(decorator, "FlowDocument");
_locatorManager.RegisterSelectionProcessor(new TextViewSelectionProcessor(), typeof(DocumentPageView));
// Setup the selection processor, pre-targeting it at a specific DocumentPageView
TextSelectionProcessor textSelectionProcessor = new TextSelectionProcessor();
textSelectionProcessor.SetTargetDocumentPageView(dpv);
_locatorManager.RegisterSelectionProcessor(textSelectionProcessor, typeof(TextRange));
}
// Get attached annotations for the page
IList attachedAnnotations = ProcessAnnotations(dpv);
// Now make sure they have a visual component added to the DPV via the component manager
foreach (IAttachedAnnotation attachedAnnotation in attachedAnnotations)
{
if (attachedAnnotation.AttachmentLevel != AttachmentLevel.Unresolved && attachedAnnotation.AttachmentLevel != AttachmentLevel.Incomplete)
{
manager.AddAttachedAnnotation(attachedAnnotation, false);
}
}
// Update layout a second time to get the annotations layed out correctly
decorator.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
decorator.Arrange(new Rect(decorator.DesiredSize));
decorator.UpdateLayout();
/* Look into using the VisualBrush in order to get a dead page instead of a live one...
VisualBrush visualBrush = new VisualBrush(decorator);
Rectangle rectangle = new Rectangle();
rectangle.Fill = visualBrush;
rectangle.Margin = new Thickness(0);
*/
return new AnnotatedDocumentPage(page, decorator, tempSize, new Rect(tempSize), new Rect(tempSize));
}
private IList ProcessAnnotations(DocumentPageView dpv)
{
if (dpv == null)
throw new ArgumentNullException("dpv");
IList attachedAnnotations = new List();
IList locators = _locatorManager.GenerateLocators(dpv);
if (locators.Count > 0)
{
// LocatorBases for a single node should always be Locators
ContentLocator[] lists = new ContentLocator[locators.Count];
locators.CopyTo(lists, 0);
IList annotations = _annotationStore.GetAnnotations(lists[0]);
foreach (ContentLocator locator in locators)
{
if (locator.Parts[locator.Parts.Count - 1].NameValuePairs.ContainsKey(TextSelectionProcessor.IncludeOverlaps))
{
locator.Parts.RemoveAt(locator.Parts.Count - 1);
}
}
foreach (Annotation annotation in annotations)
{
foreach (AnnotationResource anchor in annotation.Anchors)
{
foreach (ContentLocatorBase locator in anchor.ContentLocators)
{
AttachmentLevel attachmentLevel;
object attachedAnchor = _locatorManager.FindAttachedAnchor(dpv, lists, locator, out attachmentLevel);
if (attachmentLevel != AttachmentLevel.Unresolved)
{
Invariant.Assert(VisualTreeHelper.GetChildrenCount(dpv) == 1, "DocumentPageView has no visual children.");
DependencyObject firstElement = VisualTreeHelper.GetChild(dpv, 0);
attachedAnnotations.Add(new AttachedAnnotation(_locatorManager, annotation, anchor, attachedAnchor, attachmentLevel, firstElement as DocumentPageHost));
// Only process one locator per resource
break;
}
}
}
}
}
return attachedAnnotations;
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Classes
///
/// AnnotationDocumentPage implements IContentHost and delegates all calls
/// to the wrapped DocumentPage. This allows XPS serialization to make use
/// of the IContentHost info from the wrapped page in order to provide
/// clickable hyperlinks.
///
private class AnnotatedDocumentPage : DocumentPage, IContentHost
{
///
/// Creates an AnnotationDocumentPage for the wrapped page with the specified
/// visual and sizes.
///
public AnnotatedDocumentPage(DocumentPage basePage, Visual visual, Size pageSize, Rect bleedBox, Rect contentBox)
: base(visual, pageSize, bleedBox, contentBox)
{
_basePage = basePage as IContentHost;
}
///
/// Returns the set of HostedElements in this page.
///
public IEnumerator HostedElements
{
get
{
if (_basePage != null)
{
return _basePage.HostedElements;
}
else
{
return new HostedElements(new ReadOnlyCollection(new List(0)));
}
}
}
///
/// Returns the rectangles that are 'hot spots' for the specified element.
///
public ReadOnlyCollection GetRectangles(ContentElement child)
{
if (_basePage != null)
{
return _basePage.GetRectangles(child);
}
else
{
return new ReadOnlyCollection(new List(0));
}
}
///
/// Performs a hit-test with the given point on this page.
///
public IInputElement InputHitTest(Point point)
{
if (_basePage != null)
{
return _basePage.InputHitTest(point);
}
else
{
return null;
}
}
///
/// Lets the page recalculate the rectangles for this element when its desired
/// size has changed.
///
public void OnChildDesiredSizeChanged(UIElement child)
{
if (_basePage != null)
{
_basePage.OnChildDesiredSizeChanged(child);
}
}
// DocumentPage being wrapped by this DocumentPage
private IContentHost _basePage;
}
#endregion Private Classes
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
// Store used to retrieve annotations from
private AnnotationStore _annotationStore;
// Document we are loading annotations for
private DocumentPaginator _originalPaginator;
// LocatorManager used to generate and resolve locators
private LocatorManager _locatorManager;
// Specifies whether the paginator is for fixed content
private bool _isFixedContent;
// FlowDirection to use when laying the annotations out
private FlowDirection _flowDirection;
#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
- RSAOAEPKeyExchangeDeformatter.cs
- XmlWellformedWriter.cs
- IndexedEnumerable.cs
- EpmContentSerializer.cs
- BinaryEditor.cs
- SchemaHelper.cs
- MenuItemStyleCollection.cs
- Int64KeyFrameCollection.cs
- NumberFormatter.cs
- ValidationError.cs
- LockedHandleGlyph.cs
- AlignmentYValidation.cs
- WCFBuildProvider.cs
- FlowDocumentReader.cs
- GridItemPatternIdentifiers.cs
- ConfigurationValue.cs
- HTMLTextWriter.cs
- CodeAssignStatement.cs
- isolationinterop.cs
- ProjectionNode.cs
- CookieParameter.cs
- GridLengthConverter.cs
- ProxyHwnd.cs
- DataColumnMapping.cs
- CheckBox.cs
- AppendHelper.cs
- DataServiceQueryProvider.cs
- BroadcastEventHelper.cs
- ExternalCalls.cs
- ArrayConverter.cs
- IdleTimeoutMonitor.cs
- ThumbButtonInfo.cs
- HealthMonitoringSection.cs
- TrueReadOnlyCollection.cs
- HyperLinkColumn.cs
- CodeMethodReturnStatement.cs
- DropShadowBitmapEffect.cs
- Clause.cs
- ObjectItemNoOpAssemblyLoader.cs
- Size3D.cs
- TextElementEnumerator.cs
- Splitter.cs
- HtmlFormParameterWriter.cs
- Inline.cs
- DataKey.cs
- QilUnary.cs
- MarginsConverter.cs
- LinkDescriptor.cs
- IndexerNameAttribute.cs
- SecurityAccessDeniedException.cs
- CodeAccessSecurityEngine.cs
- LogLogRecordHeader.cs
- Size.cs
- nulltextnavigator.cs
- PresentationAppDomainManager.cs
- DiagnosticsConfiguration.cs
- ProgressBarHighlightConverter.cs
- NativeBuffer.cs
- PropertyOverridesTypeEditor.cs
- PageBuildProvider.cs
- CompiledELinqQueryState.cs
- FloaterBaseParaClient.cs
- ExpressionPrinter.cs
- ProtocolElement.cs
- WindowsListViewItemCheckBox.cs
- Privilege.cs
- AppSettingsExpressionEditor.cs
- TreeWalker.cs
- ScalarRestriction.cs
- QueryResponse.cs
- Label.cs
- CounterSample.cs
- WebPermission.cs
- SafeCryptoHandles.cs
- MarkedHighlightComponent.cs
- OpenFileDialog.cs
- TextEditorMouse.cs
- SequenceFullException.cs
- ImageMapEventArgs.cs
- ScriptReferenceEventArgs.cs
- ListViewHitTestInfo.cs
- RecognizerBase.cs
- SettingsPropertyWrongTypeException.cs
- StreamHelper.cs
- SelectionRange.cs
- Type.cs
- PeerNameRecordCollection.cs
- StylusButtonCollection.cs
- xmlsaver.cs
- PageFunction.cs
- Table.cs
- SystemFonts.cs
- XmlDataLoader.cs
- MouseOverProperty.cs
- URLString.cs
- IgnoreFlushAndCloseStream.cs
- Visitors.cs
- Merger.cs
- ColumnClickEvent.cs
- PartitionResolver.cs