/// <summary>
        /// The given attached annotation was removed by the annotation service. 
        /// Find all annotation components and let them know.
        /// If an annotation component does not have any other attached annotations, remove it.
        /// Update the attachedAnnotations map.
        /// </summary> 
        /// <param name="attachedAnnotation">Attached annotation to remove</param>
        /// <param name="reorder">If true - update components ZOrder after removing the component</param> 
        internal void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation, bool reorder) 
        {
            Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null"); 

            if (!_attachedAnnotations.ContainsKey(attachedAnnotation))
            {
                // note, this is not always a bug, since an annotation might have resolved, but no annotation component found 
                // the tree traversal bug we have currently results in this failing even if annotation components were found, because
                // in certain cases annotationService.AttachedAnnotations returns wrong list. 
                return; 
            }
 
            IList<IAnnotationComponent> currentList = _attachedAnnotations[attachedAnnotation];

            _attachedAnnotations.Remove(attachedAnnotation); // clean up the map
            foreach (IAnnotationComponent component in currentList) 
            {
                component.RemoveAttachedAnnotation(attachedAnnotation);  // let the annotation component know 
                if (component.AttachedAnnotations.Count == 0) 
                { // if it has no more attached annotations, remove it
                    if (component.PresentationContext != null) 
                        component.PresentationContext.RemoveFromHost(component, reorder);
                }
            }
        } 
        /// <summary> 
        /// The given attached annotation was added by the annotation service
        /// Find annotation components for the given attached annotation, maintain
        /// mapping from attached annotation to annotation components, and add to the
        /// adorner layer if the annotation component is not already in a presentation context. 
        /// </summary>
        /// <param name="attachedAnnotation">Attached annotation to add</param> 
        /// <param name="reorder">If true - update components ZOrder after adding the component</param> 
        internal void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation, bool reorder)
        { 
            Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");

            IAnnotationComponent component = FindComponent(attachedAnnotation);
            if (component == null) return; 
            AddComponent(attachedAnnotation, component, reorder);
        } 
示例#3
0
        /// <summary>
        /// Add an IAttachedAnnotation to the annotation map.
        /// </summary>
        /// <param name="attachedAnnotation">the IAttachedAnnotation to be added to the map</param>
        internal void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            List<IAttachedAnnotation> list = null;
            if (!_annotationIdToAttachedAnnotations.TryGetValue(attachedAnnotation.Annotation.Id, out list))
            {
                list = new List<IAttachedAnnotation>(1);
                _annotationIdToAttachedAnnotations.Add(attachedAnnotation.Annotation.Id, list);
            }

            list.Add(attachedAnnotation);
        }
示例#4
0
 /// <summary>
 /// Remove an IAttachedAnnotation from the annotation map.
 /// </summary>
 /// <param name="attachedAnnotation"></param>
 internal void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
 {
     List<IAttachedAnnotation> list = null;
     if (_annotationIdToAttachedAnnotations.TryGetValue(attachedAnnotation.Annotation.Id, out list))
     {
         list.Remove(attachedAnnotation);
         if (list.Count == 0)
         {
             _annotationIdToAttachedAnnotations.Remove(attachedAnnotation.Annotation.Id);
         }
     }
 }
        /// <summary>
        /// Choose an IAnnotationComponent for a given IAttachedAnnotation.  Implementation in AnnotationComponentChooser knows
        /// about all out-of-box IAnnotationComponents.  The default mapping will be stated here later.
        /// Subclasses can overwrite this method to return application specific mapping.
        /// Note: In future release this method should be made virtual.
        /// </summary>
        /// <param name="attachedAnnotation">The IAttachedAnnotation that needs an IAnnotationComponent </param>
        /// <returns></returns>
        public IAnnotationComponent ChooseAnnotationComponent(IAttachedAnnotation attachedAnnotation)
        {           
            if (attachedAnnotation == null) throw new ArgumentNullException("attachedAnnotation");
                                    
            IAnnotationComponent ac = null;

            // Text StickyNote
            if (attachedAnnotation.Annotation.AnnotationType == StickyNoteControl.TextSchemaName)
            {
                ac = new StickyNoteControl(StickyNoteType.Text) as IAnnotationComponent;
            }
            // Ink StickyNote
            else if (attachedAnnotation.Annotation.AnnotationType == StickyNoteControl.InkSchemaName)
            {
                ac = new StickyNoteControl(StickyNoteType.Ink) as IAnnotationComponent;
            }
            // Highlight
            else if (attachedAnnotation.Annotation.AnnotationType == HighlightComponent.TypeName)
            {
                ac = new HighlightComponent() as IAnnotationComponent;
            }

            return ac;
        }
示例#6
0
        /// <summary>
        /// Check if the attachment level of the two attached annotations is equal, if the
        /// two anchoes are TextAnchors and are equal
        /// </summary>
        /// <param name="firstAttachedAnnotation">first attached annotation</param>
        /// <param name="secondAttachedAnnotation">second attached annotation</param>
        /// <returns>true if the attachment level is equal and the two anchors are equal TextAnchors</returns>
        private bool AttachedAnchorsEqual(IAttachedAnnotation firstAttachedAnnotation, IAttachedAnnotation secondAttachedAnnotation)
        {

            //the annotation exists, but we do not know if the attached anchor has
            //changed, so we we always modify it
            object oldAttachedAnchor = firstAttachedAnnotation.AttachedAnchor;

            // WorkItem 41404 - Until we have a design that lets us get around
            // anchor specifics in the service we need this here.
            // If the attachment levels are the same, we want to test to see if the
            // anchors are the same as well - if they are we do nothing
            if (firstAttachedAnnotation.AttachmentLevel == secondAttachedAnnotation.AttachmentLevel)
            {
                // If new anchor is text anchor - compare it to old anchor to
                // detect if any changes actually happened.
                TextAnchor newAnchor = secondAttachedAnnotation.AttachedAnchor as TextAnchor;
                if (newAnchor != null)
                {
                    if (newAnchor.Equals(oldAttachedAnchor))
                       return true;
                }
            }

            return false;
        }
示例#7
0
        /// <summary>
        /// remove the passed in attachedAnnotation from the map and the internal DP
        /// </summary>
        /// <param name="attachedAnnotation"></param>
        private void DoRemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            Invariant.Assert(attachedAnnotation != null, "Parameter 'attachedAnnotation' is null.");

            DependencyObject element = attachedAnnotation.Parent;
            Invariant.Assert(element != null, "AttachedAnnotation being added should have non-null Parent.");

            _annotationMap.RemoveAttachedAnnotation(attachedAnnotation);

            List<IAttachedAnnotation> list = element.GetValue(AnnotationService.AttachedAnnotationsProperty) as List<IAttachedAnnotation>;

            if (list != null)
            {
                list.Remove(attachedAnnotation);
                // note, we do not guarantee DP change event firing, this is not used in our framework and the DP is internal

                if (list.Count == 0)
                {
                    element.ClearValue(AnnotationService.AttachedAnnotationsProperty);
                }
            }
        }
示例#8
0
        /// <summary>
        /// For the given annotation and anchor, attempt to fully resolve the anchor on the tree.
        /// This method turns any trimming to visible content off in order to get an anchor that
        /// includes non-visible content.  This lets us process anchors on virtualized content
        /// as if they were present.
        /// </summary>
        private void FullyResolveAnchor(IAttachedAnnotation attachedAnnotation)
        {
            Invariant.Assert(attachedAnnotation != null, "Attached annotation cannot be null.");

            // Do nothing if attachment level is already full.
            if (attachedAnnotation.AttachmentLevel == AttachmentLevel.Full)
                return;

            FixedPageProcessor fixedProcessor = null;
            TextSelectionProcessor flowRangeProcessor = null;
            TextSelectionProcessor flowAnchorProcessor = null;

            bool isFlow = false;
            FrameworkElement viewer = this.Root as FrameworkElement;

            if (viewer is DocumentViewerBase)
                isFlow = ((DocumentViewerBase)viewer).Document is FlowDocument;
            else if ((viewer is FlowDocumentScrollViewer) || (viewer is FlowDocumentReader))
                isFlow = true;
            else
                viewer = null;

            if (viewer != null)
            {
                try
                {
                    if (isFlow)
                    {
                        flowRangeProcessor = this.LocatorManager.GetSelectionProcessor(typeof(TextRange)) as TextSelectionProcessor;
                        Invariant.Assert(flowRangeProcessor != null, "TextSelectionProcessor should be available if we are processing flow content.");
                        flowRangeProcessor.Clamping = false;
                        flowAnchorProcessor = this.LocatorManager.GetSelectionProcessor(typeof(TextAnchor)) as TextSelectionProcessor;
                        Invariant.Assert(flowAnchorProcessor != null, "TextSelectionProcessor should be available if we are processing flow content.");
                        flowAnchorProcessor.Clamping = false;
                    }
                    else
                    {
                        fixedProcessor = this.LocatorManager.GetSubTreeProcessorForLocatorPart(FixedPageProcessor.CreateLocatorPart(0)) as FixedPageProcessor;
                        Invariant.Assert(fixedProcessor != null, "FixedPageProcessor should be available if we are processing fixed content.");
                        fixedProcessor.UseLogicalTree = true;
                    }

                    AttachmentLevel attachmentLevel;
                    object fullAnchor = FindAttachedAnchor(attachedAnnotation.Anchor, out attachmentLevel);
                    if (attachmentLevel == AttachmentLevel.Full)
                    {
                        ((AttachedAnnotation)attachedAnnotation).SetFullyAttachedAnchor(fullAnchor);
                    }
                }
                finally
                {
                    if (isFlow)
                    {
                        flowRangeProcessor.Clamping = true;
                        flowAnchorProcessor.Clamping = true;
                    }
                    else
                    {
                        fixedProcessor.UseLogicalTree = false;
                    }
                }
            }
        }
示例#9
0
        /// <summary>
        /// handle the case when an anchor is modified
        /// </summary>
        /// <param name="annotation">the annotation which anchor was affected</param>
        /// <param name="anchor">the modified anchor</param>
        /// <returns></returns>
        private AttachedAnnotationChangedEventArgs AnchorModified(Annotation annotation, AnnotationResource anchor)
        {
            Invariant.Assert(annotation != null && anchor != null, "Parameter 'annotation' or 'anchor' is null.");

            AttachedAnnotationChangedEventArgs args = null;
            AttachmentLevel newAttachmentLevel;
            bool previouslyAttached = false;

            // anchor has changed, need to find new attached anchor
            object newAttachedAnchor = FindAttachedAnchor(anchor, out newAttachmentLevel);

            // Since we will be modifying this collection, we make a copy of it to iterate on
            IList<IAttachedAnnotation> annotations = _annotationMap.GetAttachedAnnotations(annotation.Id);
            IAttachedAnnotation[] list = new IAttachedAnnotation[annotations.Count];
            annotations.CopyTo(list, 0);

            foreach (IAttachedAnnotation attachedAnnotation in list)
            {
                if (attachedAnnotation.Anchor == anchor)
                {
                    previouslyAttached = true;

                    if (newAttachmentLevel != AttachmentLevel.Unresolved)
                    {
                        Invariant.Assert(newAttachedAnchor != null, "AttachedAnnotation with AttachmentLevel != Unresolved should have non-null AttachedAnchor.");

                        object oldAttachedAnchor = attachedAnnotation.AttachedAnchor;
                        AttachmentLevel oldAttachmentLevel = attachedAnnotation.AttachmentLevel;

                        ((AttachedAnnotation)attachedAnnotation).Update(newAttachedAnchor, newAttachmentLevel, null);

                        // Update the full anchor
                        FullyResolveAnchor(attachedAnnotation);

                        // No need to update map - we just changed the AttachedAnnotation in-place
                        args = AttachedAnnotationChangedEventArgs.Modified(attachedAnnotation, oldAttachedAnchor, oldAttachmentLevel);
                    }
                    else
                    {
                        // the new modified anchor doesn't resolve
                        // we need to delete the original attached annotation
                        DoRemoveAttachedAnnotation(attachedAnnotation);
                        args = AttachedAnnotationChangedEventArgs.Deleted(attachedAnnotation);
                    }
                    break;
                }
            }

            // If it wasn't previously attached, but can be resolved now we create an AttachedAnnotation
            if (!previouslyAttached && newAttachmentLevel != AttachmentLevel.Unresolved && newAttachmentLevel != AttachmentLevel.Incomplete)
            {
                Invariant.Assert(newAttachedAnchor != null, "AttachedAnnotation with AttachmentLevel != Unresolved should have non-null AttachedAnchor.");
                AttachedAnnotation attachedAnnotation = new AttachedAnnotation(
                    this.LocatorManager,
                    annotation,
                    anchor,
                    newAttachedAnchor,
                    newAttachmentLevel);

                DoAddAttachedAnnotation(attachedAnnotation);
                args = AttachedAnnotationChangedEventArgs.Added(attachedAnnotation);
            }

            return args;
        }
示例#10
0
        /// <summary>
        /// add the passed in attachedAnnotation to the map and to the internal DP to the element tree
        /// </summary>
        /// <param name="attachedAnnotation">the attachedannotation to be added to the map and the element tree</param>
        private void DoAddAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            Invariant.Assert(attachedAnnotation != null, "Parameter 'attachedAnnotation' is null.");

            DependencyObject element = attachedAnnotation.Parent;
            Invariant.Assert(element != null, "AttachedAnnotation being added should have non-null Parent.");

            List<IAttachedAnnotation> list = element.GetValue(AnnotationService.AttachedAnnotationsProperty) as List<IAttachedAnnotation>;

            if (list == null)
            {
                list = new List<IAttachedAnnotation>(1);
                element.SetValue(AnnotationService.AttachedAnnotationsProperty, list);
            }
            list.Add(attachedAnnotation);

            _annotationMap.AddAttachedAnnotation(attachedAnnotation);

            // Now we do a full resolve of the anchor - fully anchors are used for activation of sticky notes
            FullyResolveAnchor(attachedAnnotation);
        }
 /// <summary> 
 /// Modify an attached annotation that is held by the component
 /// </summary>
 /// <param name="attachedAnnotation">The attached annotation after modification</param>
 /// <param name="previousAttachedAnchor">The attached anchor previously associated with the attached annotation.</param> 
 /// <param name="previousAttachmentLevel">The previous attachment level of the attached annotation.</param>
 public void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel) 
 { 
     throw new NotSupportedException(SR.Get(SRID.NotSupported));
 } 
        /// <summary> 
        /// given an attachedAnnotation find the chooser attached at its parent 
        /// and ask it to choose a component suitable to handle the attachedAnnotation
        /// </summary> 
        /// <param name="attachedAnnotation">the attachedAnnotation we are to find a component for</param>
        /// <returns>an IAnnotationComponent that can handle the attachedAnnotation (or null)</returns>
        private IAnnotationComponent FindComponent(IAttachedAnnotation attachedAnnotation)
        { 
            Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
 
            UIElement annotatedElement = attachedAnnotation.Parent as UIElement; // casted from DependencyObject 
            Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");
 
            AnnotationComponentChooser chooser = AnnotationService.GetChooser(annotatedElement);

            // should we return a list instead?
            IAnnotationComponent component = chooser.ChooseAnnotationComponent(attachedAnnotation); 

            return component; 
        } 
        /// <summary>
        /// factory method to create an AttachedAnnotationChangedEventArgs for the action modified
        /// </summary>
        /// <param name="attachedAnnotation">the IAttachedAnnotation associated with the event</param>
        /// <param name="previousAttachedAnchor">the previous attached anchor for the attached annotation</param>
        /// <param name="previousAttachmentLevel">the previous attachment level for the attached annotation</param>
        /// <returns>the constructed AttachedAnnotationChangedEventArgs</returns>
        internal static AttachedAnnotationChangedEventArgs Modified(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel)
        {
            Invariant.Assert(attachedAnnotation != null && previousAttachedAnchor != null);

            return new AttachedAnnotationChangedEventArgs(AttachedAnnotationAction.AnchorModified, attachedAnnotation, previousAttachedAnchor, previousAttachmentLevel);
        }
示例#14
0
        /// <summary>
        /// Removes an attached annotations from this StickyNoteControl.
        /// </summary>
        /// <param name="attachedAnnotation">An IAttachedAnnotation instance</param>
        void IAnnotationComponent.RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (attachedAnnotation == null)
            {
                throw new ArgumentNullException("attachedAnnotation");
            }

            if (attachedAnnotation == _attachedAnnotation)
            {
                //fire trace event
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedSNBegin);

                GiveUpFocus();

                ClearAnnotation();

                //fire trace event
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedSNEnd);

            }
            else
            {
                throw new ArgumentException(SR.Get(SRID.InvalidValueSpecified), "attachedAnnotation");
            }
        }
示例#15
0
        /// <summary> 
        /// Remove an attached annotation from the component 
        /// </summary>
        /// <param name="attachedAnnotation">The attached annotation to be removed from the component</param> 
        public void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (attachedAnnotation == null)
            { 
                throw new ArgumentNullException("attachedAnnotation");
            } 
 
            if (attachedAnnotation != _attachedAnnotation)
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnnotation), "attachedAnnotation");
            }

            Invariant.Assert(_range != null, "null highlight range"); 

            //fire trace event 
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedHighlightBegin); 

            //check input data and retrieve the TextContainer 
            ITextContainer textContainer = CheckInputData(attachedAnnotation);

            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");
 
            //get AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
            Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized"); 

            //unregister of cargo changes 
            _attachedAnnotation.Annotation.CargoChanged -= new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);

            highlightLayer.RemoveRange(this);
 
            //highlight is removed - remove the attached annotation and the data
            _attachedAnnotation = null; 
 
            //fire trace event
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedHighlightEnd); 


        }
示例#16
0
        /// <summary>
        /// Add an attached annotation to the component. The attached anchor will be used to add
        /// a highlight to the appropriate TextContainer
        /// </summary> 
        /// <param name="attachedAnnotation">The attached annotation to be added to the component</param>
        public void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation) 
        { 
            if (_attachedAnnotation != null)
            { 
                throw new ArgumentException(SR.Get(SRID.MoreThanOneAttachedAnnotation));
            }

            //fire trace event 
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedHighlightBegin);
 
            //check input data and retrieve the TextContainer 
            ITextContainer textContainer = CheckInputData(attachedAnnotation);
 
            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;

            //Get highlight Colors from the cargo. For undefined Colors the default values are used
            GetColors(attachedAnnotation.Annotation, out _background, out _selectedBackground); 
            _range = textAnchor;
 
            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null"); 

            //get or create AnnotationHighlightLayer in the textContainer 
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer;
            if (highlightLayer == null)
            {
                highlightLayer = new AnnotationHighlightLayer(); 
                textContainer.Highlights.AddLayer(highlightLayer);
            } 
 
            //save the attached annotation
            _attachedAnnotation = attachedAnnotation; 

            //register for cargo changes
            _attachedAnnotation.Annotation.CargoChanged += new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);
 
            //add this highlight range
            highlightLayer.AddRange(this); 
            HighlightBrush = new SolidColorBrush(_background); 
            IsHitTestVisible = false;
 
            //fire trace event
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedHighlightEnd);

        } 
        /// <summary> 
        /// Add to the map from attached annotations -> annotation components
        /// </summary>
        /// <param name="attachedAnnotation">The attached annotation to use as key</param>
        /// <param name="component">The component to add to list</param> 
        private void AddToAttachedAnnotations(IAttachedAnnotation attachedAnnotation, IAnnotationComponent component)
        { 
            Debug.Assert(attachedAnnotation != null, "attachedAnnotation should not be null"); 
            Debug.Assert(component != null, "component should not be null");
 
            IList<IAnnotationComponent> currentList;

            if (!_attachedAnnotations.TryGetValue(attachedAnnotation, out currentList))
            { 
                currentList = new List<IAnnotationComponent>();
                _attachedAnnotations[attachedAnnotation] = currentList; 
            } 

            currentList.Add(component); 
        }
        /// <summary> 
        /// Service indicates attached annotation has changed. 
        /// For now, take all annotation components maped from old attached annotation and map from new.
        /// Then iterate through annotation components to let them know. 
        /// Note, this needs to change later.  If modify is radical, existing component might not want it anymore,
        /// and new one might need to be found...
        /// </summary>
        /// <param name="attachedAnnotation">The modified attached annotation</param> 
        /// <param name="previousAttachedAnchor">The previous attached anchor for the attached annotation</param>
        /// <param name="previousAttachmentLevel">The previous attachment level for the attached annotation</param> 
        private void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel) 
        {
            Debug.Assert(attachedAnnotation != null, "attachedAnnotation should not be null"); 
            Debug.Assert(previousAttachedAnchor != null, "previousAttachedAnchor should not be null");

            // if there was no component found for this attached annotation
            // then we treat the modify case as an add 
            if (!_attachedAnnotations.ContainsKey(attachedAnnotation))
            { 
                // this is not necessarily a bug, it can be that the old attached annotation does not have an 
                // associated annotation component.
                this.AddAttachedAnnotation(attachedAnnotation, true); 
                return;
            }

            // we have a previous component for this attached annotation 
            // we find the chooser for the new attached annotation
            // and ask it to choose a component 
            // 1- if it returned null then we just remove the attached annotation 
            // 2- if it returned a different component, then we treat it as a remove/add
            // 3- if it returned the same component then we call ModifyAttachedAnnotation on the component 
            IAnnotationComponent newComponent = FindComponent(attachedAnnotation);
            if (newComponent == null)
            {
                RemoveAttachedAnnotation(attachedAnnotation, true); 
            }
            else 
            { 
                IList<IAnnotationComponent> currentList = _attachedAnnotations[attachedAnnotation]; //save the current list
 
                // if we found the new component in any of the list of components we already have for this
                // attached annotation
                if (currentList.Contains(newComponent))
                { 
                    // ask the components to handle the anchor modification event
                    foreach (IAnnotationComponent component in currentList) 
                    { 
                        component.ModifyAttachedAnnotation(attachedAnnotation, previousAttachedAnchor, previousAttachmentLevel);  // let the annotation component know
                        if (component.AttachedAnnotations.Count == 0) 
                        {
                            // if component decides it can not handle it, remove it
                            component.PresentationContext.RemoveFromHost(component, true);
                        } 
                    }
                } 
                else 
                {
                    // remove all components 
                    RemoveAttachedAnnotation(attachedAnnotation, true);

                    // add the new component
                    AddComponent(attachedAnnotation, newComponent, true); 
                }
            } 
        } 
        /// <summary> 
        /// Add an attached annotation to a component and add the component to the adorner layer
        /// if the annotation component is not already in a presentation context.
        /// </summary>
        /// <param name="attachedAnnotation">the attachedAnnotation we are to add to the component</param> 
        /// <param name="component">the component we are to add to the adorner layer</param>
        /// <param name="reorder">if true - the z-order must be reevaluated</param> 
        private void AddComponent(IAttachedAnnotation attachedAnnotation, IAnnotationComponent component, bool reorder) 
        {
            UIElement annotatedElement = attachedAnnotation.Parent as UIElement; // casted from DependencyObject 
            Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");

            // if annotation component is already in presentation context, nothing else to do
            if (component.PresentationContext != null) return; 

            // otherwise host in the appropriate adorner layer 
            AdornerLayer layer = AdornerLayer.GetAdornerLayer(annotatedElement); // note, GetAdornerLayer requires UIElement 
            if (layer == null)
            { 
                if (PresentationSource.FromVisual(annotatedElement) == null)
                {
                    // The annotated element is no longer part of the application tree.
                    // This probably means we are out of [....] - trying to add an annotation 
                    // for an element that has already gone away.  Bug # 1580288 tracks
                    // the need to figure this out. 
                    return; 
                }
 
                throw new InvalidOperationException(SR.Get(SRID.NoPresentationContextForGivenElement, annotatedElement));
            }

            // add to the attachedAnnotations 
            this.AddToAttachedAnnotations(attachedAnnotation, component);
 
            // let the annotation component know about the attached annotation 
            // call add before adding to adorner layer so the component can be initialized
            component.AddAttachedAnnotation(attachedAnnotation); // this might cause recursion in modify if annotation component adds to annotation 

            AdornerPresentationContext.HostComponent(layer, component, annotatedElement, reorder);

        } 
        /// <summary>
        /// Add an attached annotation to the component. The attached anchor will be used to add
        /// a highlight to the appropriate TextContainer 
        /// </summary>
        /// <param name="attachedAnnotation">The attached annotation to be added to the component</param> 
        public void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation) 
        {
            if (_attachedAnnotation != null) 
            {
                throw new ArgumentException(SR.Get(SRID.MoreThanOneAttachedAnnotation));
            }
 
            //fire trace event
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedMHBegin); 
 
            //save the attached annotation
            _attachedAnnotation = attachedAnnotation; 

            //create anchor markers
            if ((attachedAnnotation.AttachmentLevel & AttachmentLevel.StartPortion) != 0)
                _leftMarker = CreateMarker(GetMarkerGeometry()); 
            if ((attachedAnnotation.AttachmentLevel & AttachmentLevel.EndPortion) != 0)
                _rightMarker = CreateMarker(GetMarkerGeometry()); 
 
            //create highlight, markers and register for TextSelection.Changed and other events
            RegisterAnchor(); 

            //fire trace event
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedMHEnd);
 
        }
示例#21
0
        //-------------------------------------------------------------------------------
        //
        // IAnnotationComponent Interface
        //
        //-------------------------------------------------------------------------------

        #region IAnnotationComponent Members
        /// <summary>
        /// Adds an attached annotations to this StickyNoteControl
        /// </summary>
        /// <param name="attachedAnnotation">An IAttachedAnnotation instance</param>
        void IAnnotationComponent.AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (attachedAnnotation == null)
            {
                throw new ArgumentNullException("attachedAnnotation");
            }

            if (_attachedAnnotation == null)
            {
                //fire trace event
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedSNBegin);

                SetAnnotation(attachedAnnotation);

                //fire trace event
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.AddAttachedSNEnd);
            }
            else
            {
                throw new InvalidOperationException(SR.Get(SRID.AddAnnotationsNotImplemented));
            }
        }
        /// <summary> 
        /// Remove an attached annotation from the component
        /// </summary> 
        /// <param name="attachedAnnotation">The attached annotation to be removed from the component</param>
        public void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (attachedAnnotation == null) 
            {
                throw new ArgumentNullException("attachedAnnotation"); 
            } 

            if (attachedAnnotation != _attachedAnnotation) 
            {
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnnotation), "attachedAnnotation");
            }
 
            //fire trace event
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedMHBegin); 
 
            //unregister markers from the adorner layer aND LISTENERS
            CleanUpAnchor(); 

            _attachedAnnotation = null;

            //fire trace event 
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordAnnotation, EventTrace.Event.RemoveAttachedMHEnd);
 
        } 
示例#23
0
        /// <summary>
        /// handle the case when an anchor is removed from the annotation
        /// </summary>
        /// <param name="annotation">the annotation which anchor was affected</param>
        /// <param name="anchor">the removed anchor</param>
        /// <returns>EventArgs to use when firing an AttachedAnnotationChanged event</returns>
        private AttachedAnnotationChangedEventArgs AnchorRemoved(Annotation annotation, AnnotationResource anchor)
        {
            Invariant.Assert(annotation != null && anchor != null, "Parameter 'annotation' or 'anchor' is null.");

            AttachedAnnotationChangedEventArgs args = null;

            IList<IAttachedAnnotation> annotations = _annotationMap.GetAttachedAnnotations(annotation.Id);

            if (annotations.Count > 0)
            {
                // Since we will be modifying this collection, we make a copy of it to iterate on
                IAttachedAnnotation[] list = new IAttachedAnnotation[annotations.Count];
                annotations.CopyTo(list, 0);

                foreach (IAttachedAnnotation attachedAnnotation in list)
                {
                    if (attachedAnnotation.Anchor == anchor)
                    {
                        DoRemoveAttachedAnnotation(attachedAnnotation);
                        args = AttachedAnnotationChangedEventArgs.Deleted(attachedAnnotation);
                        break;
                    }
                }
            }

            return args;
        }
        /// <summary>
        /// factory method to create an AttachedAnnotationChangedEventArgs for the action Unloaded
        /// </summary>
        /// <param name="attachedAnnotation">the IAttachedAnnotation associated with the event</param>
        /// <returns>the constructed AttachedAnnotationChangedEventArgs</returns>
        internal static AttachedAnnotationChangedEventArgs Unloaded(IAttachedAnnotation attachedAnnotation)
        {
            Invariant.Assert(attachedAnnotation != null);

            return new AttachedAnnotationChangedEventArgs(AttachedAnnotationAction.Unloaded, attachedAnnotation, null, AttachmentLevel.Unresolved);
        }
示例#25
0
        /// <summary> 
        /// Checks if this attachedAnnotation data - AttachedAnchor and Annotation
        /// </summary> 
        /// <param name="attachedAnnotation">The AttachedAnnotation</param>
        /// <returns>The AttachedAnchor TextContainer</returns>
        private ITextContainer CheckInputData(IAttachedAnnotation attachedAnnotation)
        { 

            if (attachedAnnotation == null) 
            { 
                throw new ArgumentNullException("attachedAnnotation");
            } 

            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;
            if (textAnchor == null)
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnchor), "attachedAnnotation");
            } 
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 

            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");

            if (attachedAnnotation.Annotation == null) 
            {
                throw new ArgumentException(SR.Get(SRID.AnnotationIsNull), "attachedAnnotation"); 
            } 

            //check annotation type 
            if (!_type.Equals(attachedAnnotation.Annotation.AnnotationType))
            {
                throw new ArgumentException(SR.Get(SRID.NotHighlightAnnotationType, attachedAnnotation.Annotation.AnnotationType.ToString()), "attachedAnnotation");
            } 

            return textContainer; 
 
        }
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        /// <summary>
        /// internal constructor that creates an AttachedAnnotationChangedEventArgs
        /// </summary>
        /// <param name="action">action represented by this instance</param>
        /// <param name="attachedAnnotation">annotation that was added/deleted/modified</param>
        /// <param name="previousAttachedAnchor">if action is modified, previous attached anchor</param>
        /// <param name="previousAttachmentLevel">if action is modified, previous attachment level</param>
        internal AttachedAnnotationChangedEventArgs(AttachedAnnotationAction action, IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel) 
        {
            Invariant.Assert(attachedAnnotation != null);

            _action = action;       
            _attachedAnnotation = attachedAnnotation;
            _previousAttachedAnchor = previousAttachedAnchor;
            _previousAttachmentLevel = previousAttachmentLevel;
        }
示例#27
0
        /// <summary>
        ///  searches match to an attachedAnnotation in a list of attachedAnnotations
        /// </summary>
        /// <param name="attachedAnnotation">the attached annotation</param>
        /// <param name="list">the list</param>
        /// <returns>the annotation form the list if mathing is found</returns>
        private IAttachedAnnotation FindAnnotationInList(IAttachedAnnotation attachedAnnotation, IList<IAttachedAnnotation> list)
        {
            foreach (IAttachedAnnotation aa in list)
            {
                if (aa.Annotation == attachedAnnotation.Annotation &&
                    aa.Anchor == attachedAnnotation.Anchor &&
                    aa.Parent == attachedAnnotation.Parent)
                {
                    return aa;
                }
            }

            return null;
        }
示例#28
0
        /// <summary>
        /// a handler for the storeupdate annotation deleted action
        /// </summary>
        /// <param name="annotationId">the id of the deleted annotation</param>
        private void AnnotationDeleted(Guid annotationId)
        {
            IList<IAttachedAnnotation> annotations = _annotationMap.GetAttachedAnnotations(annotationId);

            // Do nothing if this annotation isn't already loaded
            if (annotations.Count > 0)
            {
                // Since we will be modifying this collection, we make a copy of it to iterate on
                IAttachedAnnotation[] list = new IAttachedAnnotation[annotations.Count];
                annotations.CopyTo(list, 0);

                List<AttachedAnnotationChangedEventArgs> eventsToFire = new List<AttachedAnnotationChangedEventArgs>(list.Length);

                foreach (IAttachedAnnotation attachedAnnotation in list)
                {
                    DoRemoveAttachedAnnotation(attachedAnnotation);
                    eventsToFire.Add(AttachedAnnotationChangedEventArgs.Deleted(attachedAnnotation));
                }

                FireEvents(eventsToFire);
            }
        }
示例#29
0
        /// <summary>
        /// The method sets an instance of the IAttachedAnnotation to the StickyNoteControl.
        /// It will be called by IAnnotationComponent.AddAttachedAnnotation.
        /// </summary>
        /// <param name="attachedAnnotation">The instance of the IAttachedAnnotation</param>
        private void SetAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            SNCAnnotation sncAnnotation = new SNCAnnotation(attachedAnnotation.Annotation);

            // Retrieve the data type. Then set the StickyNote to correct type.
            // If we have empty data, we won't change the current StickyNote type.
            bool hasInkData = sncAnnotation.HasInkData;
            bool hasTextData = sncAnnotation.HasTextData;
            if (hasInkData && hasTextData)
            {
                throw new ArgumentException(SR.Get(SRID.InvalidStickyNoteAnnotation), "attachedAnnotation");
            }
            else if (hasInkData)
            {
                _stickyNoteType = StickyNoteType.Ink;
            }
            else if (hasTextData)
            {
                _stickyNoteType = StickyNoteType.Text;
            }

            // If we already created a Content control, make sure it matches our new type or
            // gets recreated to match.
            if (Content != null)
            {
                EnsureStickyNoteType();
            }

            //create cargo if it is a new Annotation so it is not considered as new next time
            if (sncAnnotation.IsNewAnnotation)
            {
                AnnotationResource cargo = new AnnotationResource(SNBConstants.MetaResourceName);
                attachedAnnotation.Annotation.Cargos.Add(cargo);
            }

            // Set the internal variables
            _attachedAnnotation = attachedAnnotation;
            _attachedAnnotation.Annotation.CargoChanged += new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);
            _attachedAnnotation.Annotation.AuthorChanged += new AnnotationAuthorChangedEventHandler(OnAuthorUpdated);
            _sncAnnotation = sncAnnotation;
            _anchor.AddAttachedAnnotation(attachedAnnotation);

            // Update all value
            UpdateSNCWithAnnotation(SNCAnnotation.AllValues);

            // The internal data is just [....]'ed to the store. So, reset the dirty to false.
            IsDirty = false;

            //now check if the SN must be seen
            if ((_attachedAnnotation.AttachmentLevel & AttachmentLevel.StartPortion) == 0)
            {
                //we do not need to show the StickyNote
                SetValue(UIElement.VisibilityProperty, Visibility.Collapsed);
            }
            else
            {
                //if it is seen we need to take care about bringing into view when needed
                RequestBringIntoView += new RequestBringIntoViewEventHandler(OnRequestBringIntoView);
            }
        }