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
- DivideByZeroException.cs
- SqlParameterizer.cs
- WindowsPrincipal.cs
- SafeFileMappingHandle.cs
- securitycriticaldata.cs
- DependencyPropertyKind.cs
- CompiledQueryCacheKey.cs
- FormatConvertedBitmap.cs
- NotificationContext.cs
- Marshal.cs
- ListMarkerSourceInfo.cs
- RouteUrlExpressionBuilder.cs
- ConfigurationElementProperty.cs
- ContextQuery.cs
- FontFamily.cs
- ValidationSummary.cs
- DependencyPropertyHelper.cs
- CancelEventArgs.cs
- AbandonedMutexException.cs
- XmlHierarchyData.cs
- FacetValueContainer.cs
- ControlTemplate.cs
- EDesignUtil.cs
- FontResourceCache.cs
- DetailsViewDeletedEventArgs.cs
- SystemThemeKey.cs
- DataGridAutoFormat.cs
- RuntimeIdentifierPropertyAttribute.cs
- ChannelFactoryBase.cs
- DataGridRelationshipRow.cs
- AccessText.cs
- NavigationPropertyEmitter.cs
- DoubleAnimationUsingKeyFrames.cs
- PtsPage.cs
- HtmlInputButton.cs
- WebBrowserDocumentCompletedEventHandler.cs
- MetadataItemEmitter.cs
- SyndicationLink.cs
- categoryentry.cs
- HighContrastHelper.cs
- ItemCheckedEvent.cs
- ProjectionPruner.cs
- BitmapDownload.cs
- InternalsVisibleToAttribute.cs
- dbdatarecord.cs
- ZeroOpNode.cs
- ConnectionPointCookie.cs
- srgsitem.cs
- PersonalizationAdministration.cs
- OdbcReferenceCollection.cs
- DetailsViewRow.cs
- InvalidateEvent.cs
- CmsInterop.cs
- SmtpAuthenticationManager.cs
- SafeArrayRankMismatchException.cs
- ColorAnimation.cs
- Dispatcher.cs
- Transform3DGroup.cs
- VariantWrapper.cs
- KerberosRequestorSecurityToken.cs
- TextElement.cs
- WebPartDescription.cs
- ItemContainerProviderWrapper.cs
- EntityViewContainer.cs
- EditorZone.cs
- SpecialNameAttribute.cs
- DetailsViewDeletedEventArgs.cs
- SizeFConverter.cs
- PropertyConverter.cs
- AutomationIdentifierGuids.cs
- DesignerProperties.cs
- Popup.cs
- PropertyPath.cs
- CodeCommentStatementCollection.cs
- CrossContextChannel.cs
- BinarySerializer.cs
- BamlLocalizableResource.cs
- SchemaComplexType.cs
- DescendantOverDescendantQuery.cs
- MediaPlayer.cs
- MtomMessageEncoder.cs
- PasswordRecovery.cs
- COM2Enum.cs
- PropertyEntry.cs
- Mouse.cs
- Rijndael.cs
- RelationshipNavigation.cs
- SQLInt32Storage.cs
- Socket.cs
- XmlSchemaAnyAttribute.cs
- BrowserCapabilitiesFactory35.cs
- PictureBox.cs
- CriticalFinalizerObject.cs
- DefaultDiscoveryService.cs
- FileLoadException.cs
- XmlSchemaDatatype.cs
- ItemPager.cs
- StrongNameSignatureInformation.cs
- SqlExpander.cs
- FieldAccessException.cs