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
- SecurityPolicySection.cs
- UpDownBase.cs
- RoutingTable.cs
- GuidelineSet.cs
- TextTabProperties.cs
- SystemResources.cs
- MessageParameterAttribute.cs
- WorkflowDefinitionDispenser.cs
- XpsColorContext.cs
- SqlException.cs
- KnownIds.cs
- GlyphRunDrawing.cs
- SafeLibraryHandle.cs
- VersionedStream.cs
- DtrList.cs
- Rules.cs
- Operator.cs
- RectangleConverter.cs
- CommandLibraryHelper.cs
- ConstraintStruct.cs
- ConfigsHelper.cs
- BaseDataBoundControl.cs
- SiteMapNode.cs
- NativeMethods.cs
- XmlSiteMapProvider.cs
- XmlUtf8RawTextWriter.cs
- ArglessEventHandlerProxy.cs
- AutomationEventArgs.cs
- ConstraintEnumerator.cs
- BmpBitmapEncoder.cs
- DockProviderWrapper.cs
- RtfNavigator.cs
- XsdBuilder.cs
- ImportCatalogPart.cs
- IncrementalHitTester.cs
- RawContentTypeMapper.cs
- DocumentPageHost.cs
- Rect.cs
- WindowsScrollBar.cs
- UriSection.cs
- SecurityManager.cs
- JsonDeserializer.cs
- HttpApplicationFactory.cs
- IISMapPath.cs
- TextServicesProperty.cs
- EventLogPermission.cs
- HttpWebResponse.cs
- CookieHandler.cs
- AlignmentYValidation.cs
- Padding.cs
- PrintPreviewDialog.cs
- MapPathBasedVirtualPathProvider.cs
- TableCell.cs
- DataKey.cs
- WindowsStatusBar.cs
- DistributedTransactionPermission.cs
- Vector3DCollectionConverter.cs
- MessageSmuggler.cs
- ServiceProviders.cs
- VisemeEventArgs.cs
- RemoveStoryboard.cs
- SimpleBitVector32.cs
- PieceDirectory.cs
- ProcessingInstructionAction.cs
- TextBox.cs
- GridProviderWrapper.cs
- datacache.cs
- CollectionViewGroup.cs
- SimpleWebHandlerParser.cs
- ContainerActivationHelper.cs
- Point3D.cs
- ThumbAutomationPeer.cs
- AvtEvent.cs
- PathStreamGeometryContext.cs
- ScrollContentPresenter.cs
- IdentityModelStringsVersion1.cs
- MobileResource.cs
- WorkflowOperationBehavior.cs
- AssemblyAttributes.cs
- oledbmetadatacolumnnames.cs
- OrderPreservingPipeliningMergeHelper.cs
- Pen.cs
- ToolStripContentPanel.cs
- XsdBuilder.cs
- ModuleBuilder.cs
- Root.cs
- BufferModesCollection.cs
- IconBitmapDecoder.cs
- Operators.cs
- SynchronizedInputHelper.cs
- DbQueryCommandTree.cs
- ScrollBar.cs
- UIntPtr.cs
- DataGridViewAccessibleObject.cs
- OleDbCommand.cs
- ToolStripItemEventArgs.cs
- CompareValidator.cs
- DataTemplate.cs
- Membership.cs
- OleDbParameterCollection.cs