/// <summary> /// Synchronises the shapes in the candidate slide with the shapes in the reference slide. /// Adds any shape that exists in the reference slide but is missing in the candidate slide. /// </summary> private static void SyncShapesFromReferenceSlide(PowerPointSlide refSlide, PowerPointSlide candidate, List<string> markedForDeletion) { if (refSlide == null || candidate == null || refSlide == candidate) { return; } DeleteShapesMarkedForDeletion(candidate, markedForDeletion); candidate.CopyBackgroundColourFrom(refSlide); candidate.Layout = refSlide.Layout; candidate.Design = refSlide.Design; // synchronize extra shapes other than visual items in reference slide var candidateSlideShapes = candidate.GetNameToShapeDictionary(); var extraShapes = refSlide.Shapes.Cast<Shape>() .Where(shape => !PowerPointSlide.IsIndicator(shape) && !PowerPointSlide.IsTemplateSlideMarker(shape) && !candidateSlideShapes.ContainsKey(shape.Name)) .Select(shape => shape.Name) .ToArray(); if (extraShapes.Length != 0) { var refShapes = refSlide.Shapes.Range(extraShapes); CopyShapesTo(refShapes, candidate); } // synchronize shapes position and size, except bullet content candidateSlideShapes = candidate.GetNameToShapeDictionary(); var sameShapes = refSlide.Shapes.Cast<Shape>() .Where(shape => !PowerPointSlide.IsIndicator(shape) && !PowerPointSlide.IsTemplateSlideMarker(shape) && candidateSlideShapes.ContainsKey(shape.Name)); var shapeOriginalZOrders = new SortedDictionary<int, Shape>(); foreach (var refShape in sameShapes) { var candidateShape = candidateSlideShapes[refShape.Name]; Graphics.SyncWholeShape(refShape, ref candidateShape, candidate); shapeOriginalZOrders.Add(refShape.ZOrderPosition, candidateShape); } SynchroniseZOrders(shapeOriginalZOrders); }