/// <summary> /// Applies font highlighting by section to the text in the bullet agenda. /// Set currentSection to the first section for everything to be unvisited. /// Set currentSection to AgendaSection.None for everything to be visited. /// </summary> private static void ApplyBulletFormats(TextRange2 textRange, BulletFormats bulletFormats, AgendaSection currentSection) { // - 1 because first section in agenda is at index 2 (exclude first section) int focusIndex = currentSection.IsNone() ? int.MaxValue : currentSection.Index - 1; textRange.Font.StrikeThrough = MsoTriState.msoFalse; for (var i = 1; i <= textRange.Paragraphs.Count; i++) { var currentParagraph = textRange.Paragraphs[i]; if (i == focusIndex) { Graphics.SyncTextRange(bulletFormats.Highlighted, currentParagraph, pickupTextContent: false); } else if (i < focusIndex) { Graphics.SyncTextRange(bulletFormats.Visited, currentParagraph, pickupTextContent: false); } else { Graphics.SyncTextRange(bulletFormats.Unvisited, currentParagraph, pickupTextContent: false); } } }
public void AddText() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count <= 0) { Error(TextCollection.DrawingsLabSelectAtLeastOneShape); return; } var text = DrawingsLabDialogs.ShowInsertTextDialog(); if (text == null) { return; } Globals.ThisAddIn.Application.StartNewUndoEntry(); foreach (var shape in shapes) { try { Graphics.SetText(shape, text); } catch (ArgumentException) { Debug.WriteLine("Unable to write text to " + shape.Name); } } }
public void RecordFormat() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count != 1) { Error(TextCollection.DrawingsLabSelectExactlyOneShape); return; } var shape = shapes[0]; try { var font = shape.TextFrame2.TextRange.Font; _dataSource.FormatText = Graphics.GetText(shape); _dataSource.FormatTextColor = font.Fill.ForeColor.RGB; _dataSource.FormatTextFontSize = font.Size; _dataSource.FormatTextFont = font.Name; _dataSource.FormatTextWrap = shape.TextFrame2.WordWrap == MsoTriState.msoTrue; _dataSource.FormatTextAutoSize = shape.TextFrame2.AutoSize; } catch (ArgumentException) { // ArgumentException is thrown if the shape does not have this property. } try { var line = shape.Line; _dataSource.FormatHasLine = line.Visible == MsoTriState.msoTrue; _dataSource.FormatLineColor = line.ForeColor.RGB; _dataSource.FormatLineWeight = line.Weight; _dataSource.FormatLineDashStyle = line.DashStyle; } catch (ArgumentException) { // ArgumentException is thrown if the shape does not have this property. } try { var fill = shape.Fill; _dataSource.FormatHasFill = fill.Visible == MsoTriState.msoTrue; _dataSource.FormatFillColor = fill.ForeColor.RGB; } catch (ArgumentException) { // ArgumentException is thrown if the shape does not have this property. } _dataSource.FormatWidth = shape.Width; _dataSource.FormatHeight = shape.Height; }
public void MultiCloneExtendTool() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count == 0 || shapes.Count % 2 != 0) { Error(TextCollection.DrawingsLabSelectTwoSetsOfShapes); return; } int clones = DrawingsLabDialogs.ShowMultiCloneNumericDialog(); if (clones <= 0) { return; } Globals.ThisAddIn.Application.StartNewUndoEntry(); int midpoint = shapes.Count / 2; for (int i = 0; i < shapes.Count / 2; ++i) { // Do the cloning for every pair of shapes (i, midpoint+i) var firstShape = shapes[i]; var secondShape = shapes[midpoint + i]; var newlyAddedShapes = new List <Shape>(); for (int j = 0; j < clones; ++j) { var newShape = firstShape.Duplicate()[1]; int index = j + 1; newShape.Left = secondShape.Left + (secondShape.Left - firstShape.Left) * index; newShape.Top = secondShape.Top + (secondShape.Top - firstShape.Top) * index; newShape.Rotation = secondShape.Rotation + (secondShape.Rotation - firstShape.Rotation) * index; newlyAddedShapes.Add(newShape); } // Set Z-Orders of newly created shapes. if (secondShape.ZOrderPosition < firstShape.ZOrderPosition) { // first shape in front of last shape. Order the in-between shapes accordingly. Shape prevShape = secondShape; foreach (var shape in newlyAddedShapes) { Graphics.MoveZUntilBehind(shape, prevShape); prevShape = shape; } } } }
private static void SynchroniseZOrders(SortedDictionary <int, Shape> shapeOriginalZOrders) { Shape lastShape = null; foreach (var entry in shapeOriginalZOrders.Reverse()) { var shape = entry.Value; if (lastShape != null) { Graphics.MoveZUntilBehind(shape, lastShape); } lastShape = shape; } }
private float GetX(Shape shape) { switch (_dataSource.AnchorHorizontal) { case DrawingsLabDataSource.Horizontal.Left: return(shape.Left); case DrawingsLabDataSource.Horizontal.Center: return(Graphics.GetMidpointX(shape)); case DrawingsLabDataSource.Horizontal.Right: return(Graphics.GetRight(shape)); } throw new ArgumentOutOfRangeException(); }
private float GetY(Shape shape) { switch (_dataSource.AnchorVertical) { case DrawingsLabDataSource.Vertical.Top: return(shape.Top); case DrawingsLabDataSource.Vertical.Middle: return(Graphics.GetMidpointY(shape)); case DrawingsLabDataSource.Vertical.Bottom: return(Graphics.GetBottom(shape)); } throw new ArgumentOutOfRangeException(); }
public void RemoveText() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count <= 0) { Error(TextCollection.DrawingsLabSelectAtLeastOneShape); return; } Globals.ThisAddIn.Application.StartNewUndoEntry(); foreach (var shape in shapes) { Graphics.SetText(shape, String.Empty); } }
/// <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); }
private static void SyncBulletAgendaSlide(PowerPointSlide refSlide, List <AgendaSection> sections, AgendaSection currentSection, List <string> deletedShapeNames, PowerPointSlide targetSlide) { SyncShapesFromReferenceSlide(refSlide, targetSlide, deletedShapeNames); var referenceContentShape = refSlide.GetShape(AgendaShape.WithPurpose(ShapePurpose.ContentShape)); var targetContentShape = targetSlide.GetShape(AgendaShape.WithPurpose(ShapePurpose.ContentShape)); var bulletFormats = BulletFormats.ExtractFormats(referenceContentShape); Graphics.SetText(targetContentShape, sections.Where(section => section.Index > 1) .Select(section => section.Name)); Graphics.SyncShape(referenceContentShape, targetContentShape, pickupTextContent: false, pickupTextFormat: false); ApplyBulletFormats(targetContentShape.TextFrame2.TextRange, bulletFormats, currentSection); targetSlide.DeletePlaceholderShapes(); }
private void SetY(Shape shape, float value) { switch (_dataSource.AnchorVertical) { case DrawingsLabDataSource.Vertical.Top: shape.Top = value; return; case DrawingsLabDataSource.Vertical.Middle: Graphics.SetMidpointY(shape, value); return; case DrawingsLabDataSource.Vertical.Bottom: Graphics.SetBottom(shape, value); return; } throw new ArgumentOutOfRangeException(); }
private void SetX(Shape shape, float value) { switch (_dataSource.AnchorHorizontal) { case DrawingsLabDataSource.Horizontal.Left: shape.Left = value; return; case DrawingsLabDataSource.Horizontal.Center: Graphics.SetMidpointX(shape, value); return; case DrawingsLabDataSource.Horizontal.Right: Graphics.SetRight(shape, value); return; } throw new ArgumentOutOfRangeException(); }
/// <summary> /// Within the slide, for all sections that have been "passed", replace their visual agenda image shape with /// an image of the end slide of the section. /// </summary> private static void ReplaceVisualImagesWithAfterZoomOutImages(PowerPointSlide slide, int sectionIndex) { var indexedShapes = new Dictionary <int, Shape>(); slide.Shapes.Cast <Shape>() .Where(AgendaShape.WithPurpose(ShapePurpose.VisualAgendaImage)) .ToList() .ForEach(shape => indexedShapes.Add(AgendaShape.Decode(shape).Section.Index, shape)); for (int i = 2; i < sectionIndex; ++i) { var imageShape = indexedShapes[i]; var sectionEndSlide = FindSectionLastNonAgendaSlide(i); var snapshotShape = slide.InsertExitSnapshotOfSlide(sectionEndSlide); snapshotShape.Name = imageShape.Name; Graphics.SyncShape(imageShape, snapshotShape, pickupShapeFormat: true, pickupTextContent: false, pickupTextFormat: false); imageShape.Delete(); } }
public void BringInFrontOfShape() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count < 2) { Error(TextCollection.DrawingsLabSelectAtLeastTwoShapes); return; } Globals.ThisAddIn.Application.StartNewUndoEntry(); var shapeToMoveInFront = shapes.Last(); shapes.RemoveAt(shapes.Count - 1); Graphics.SortByZOrder(shapes); foreach (var shape in shapes) { Graphics.MoveZUntilInFront(shape, shapeToMoveInFront); } }
public void PivotAroundTool() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count != 2) { Error(TextCollection.DrawingsLabSelectExactlyTwoShapes); return; } var sourceShape = shapes[0]; var pivotShape = shapes[1]; var dialog = new PivotAroundToolDialog(sourceShape, pivotShape); if (dialog.ShowDialog() != true) { return; } if (dialog.DialogResult != true) { return; } double dx = dialog.SourceCenterX - dialog.PivotCenterX; double dy = dialog.SourceCenterY - dialog.PivotCenterY; double radius = Math.Sqrt(dx * dx + dy * dy); double initialAngle = Math.Atan2(dy, dx) * 180 / Math.PI; if (!dialog.FixOriginalLocation) { double radAngle = dialog.StartAngle * Math.PI / 180; float cx = (float)(Math.Cos(radAngle) * radius + dialog.PivotCenterX); float cy = (float)(Math.Sin(radAngle) * radius + dialog.PivotCenterY); float anchorX = (float)dialog.SourceAnchorFractionX; float anchorY = (float)dialog.SourceAnchorFractionY; float angleDifference = (float)(dialog.StartAngle - initialAngle); Graphics.SetShapeX(sourceShape, cx, anchorX); Graphics.SetShapeY(sourceShape, cy, anchorY); if (dialog.RotateShape) { Graphics.RotateShapeAboutPivot(sourceShape, angleDifference, anchorX, anchorY); } } double angleStep = dialog.AngleDifference; if (!dialog.IsExtend) { angleStep /= (dialog.Copies - 1); } for (int i = 1; i < dialog.Copies; ++i) { var newShape = sourceShape.Duplicate()[1]; double angle = dialog.StartAngle + angleStep * i; double radAngle = angle * Math.PI / 180; float cx = (float)(Math.Cos(radAngle) * radius + dialog.PivotCenterX); float cy = (float)(Math.Sin(radAngle) * radius + dialog.PivotCenterY); float anchorX = (float)dialog.SourceAnchorFractionX; float anchorY = (float)dialog.SourceAnchorFractionY; float angleDifference = (float)(angleStep * i); Graphics.SetShapeX(newShape, cx, anchorX); Graphics.SetShapeY(newShape, cy, anchorY); if (dialog.RotateShape) { Graphics.RotateShapeAboutPivot(newShape, angleDifference, anchorX, anchorY); } } }
public void ApplyFormat(bool applyAllSettings = false) { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count <= 0) { Error(TextCollection.DrawingsLabSelectAtLeastOneShape); return; } Globals.ThisAddIn.Application.StartNewUndoEntry(); Action <bool, bool, Action> apply = (isDefaultSetting, condition, action) => { if (applyAllSettings && !isDefaultSetting) { return; } if (!applyAllSettings && !condition) { return; } try { action(); } catch (ArgumentException) { // ArgumentException is thrown if the shape does not have this property. } }; foreach (var s in shapes) { var shape = s; // Sync Text Style apply(false, _dataSource.FormatSyncTextStyle && _dataSource.FormatIncludeText, () => Graphics.SetText(shape, _dataSource.FormatText)); apply(true, _dataSource.FormatSyncTextStyle && _dataSource.FormatIncludeTextColor, () => shape.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = _dataSource.FormatTextColor); apply(true, _dataSource.FormatSyncTextStyle && _dataSource.FormatIncludeTextFontSize, () => shape.TextFrame2.TextRange.Font.Size = _dataSource.FormatTextFontSize); apply(true, _dataSource.FormatSyncTextStyle && _dataSource.FormatIncludeTextFont, () => shape.TextFrame2.TextRange.Font.Name = _dataSource.FormatTextFont); apply(true, _dataSource.FormatSyncTextStyle && _dataSource.FormatIncludeTextWrap, () => shape.TextFrame2.WordWrap = _dataSource.FormatTextWrap ? MsoTriState.msoTrue : MsoTriState.msoFalse); apply(true, _dataSource.FormatSyncTextStyle && _dataSource.FormatIncludeTextAutoSize, () => shape.TextFrame2.AutoSize = _dataSource.FormatTextAutoSize); // Sync Line Style apply(true, _dataSource.FormatSyncLineStyle && _dataSource.FormatIncludeHasLine, () => shape.Line.Visible = _dataSource.FormatHasLine ? MsoTriState.msoTrue : MsoTriState.msoFalse); apply(true, _dataSource.FormatSyncLineStyle && _dataSource.FormatIncludeLineColor, () => shape.Line.ForeColor.RGB = _dataSource.FormatLineColor); apply(true, _dataSource.FormatSyncLineStyle && _dataSource.FormatIncludeLineWeight, () => shape.Line.Weight = _dataSource.FormatLineWeight); apply(true, _dataSource.FormatSyncLineStyle && _dataSource.FormatIncludeLineDashStyle, () => shape.Line.DashStyle = _dataSource.FormatLineDashStyle); // Sync Fill Style apply(true, _dataSource.FormatSyncFillStyle && _dataSource.FormatIncludeHasFill, () => shape.Fill.Visible = _dataSource.FormatHasFill ? MsoTriState.msoTrue : MsoTriState.msoFalse); apply(true, _dataSource.FormatSyncFillStyle && _dataSource.FormatIncludeFillColor, () => shape.Fill.ForeColor.RGB = _dataSource.FormatFillColor); // Sync Size apply(false, _dataSource.FormatSyncSize && _dataSource.FormatIncludeWidth, () => shape.Width = _dataSource.FormatWidth); apply(false, _dataSource.FormatSyncSize && _dataSource.FormatIncludeHeight, () => shape.Height = _dataSource.FormatHeight); } }
public void MultiCloneGridTool() { var shapes = GetCurrentlySelectedShapes(); if (shapes.Count != 2) { Error(TextCollection.DrawingsLabSelectExactlyTwoShapes); return; } var sourceShape = shapes[0]; var targetShape = shapes[1]; var dialog = new MultiCloneGridDialog(sourceShape.Left, sourceShape.Top, targetShape.Left, targetShape.Top); if (dialog.ShowDialog() != true) { return; } if (dialog.DialogResult != true) { return; } Globals.ThisAddIn.Application.StartNewUndoEntry(); // Clone shapes in a grid. var newlyAddedShapes = new List <Shape>(); var dx = targetShape.Left - sourceShape.Left; var dy = targetShape.Top - sourceShape.Top; int skipIndexX = 1; int skipIndexY = 1; if (!dialog.IsExtend) { // Is between. dx = dx / (dialog.XCopies - 1); dy = dy / (dialog.YCopies - 1); skipIndexX = dialog.XCopies - 1; skipIndexY = dialog.YCopies - 1; } for (int y = 0; y < dialog.YCopies; ++y) { for (int x = 0; x < dialog.XCopies; ++x) { if (x == 0 && y == 0) { continue; } if (x == skipIndexX && y == skipIndexY) { continue; } var newShape = sourceShape.Duplicate()[1]; newShape.Left = sourceShape.Left + dx * x; newShape.Top = sourceShape.Top + dy * y; newlyAddedShapes.Add(newShape); } } // Set Z-Orders of newly created shapes. if (dialog.IsExtend) { // Multiclone Extend if (sourceShape.ZOrderPosition < targetShape.ZOrderPosition) { if (newlyAddedShapes.Count >= dialog.YCopies) { for (int i = 0; i < dialog.YCopies; ++i) { Graphics.MoveZToJustBehind(newlyAddedShapes[i], targetShape); } } } else { // first shape in front of last shape. Order the in-between shapes accordingly. Shape prevShape = targetShape; foreach (var shape in newlyAddedShapes) { Graphics.MoveZUntilBehind(shape, prevShape); prevShape = shape; } if (newlyAddedShapes.Count >= dialog.YCopies) { for (int i = 0; i < dialog.YCopies; ++i) { Graphics.MoveZToJustInFront(newlyAddedShapes[i], targetShape); } } } } else { // Multiclone Between if (sourceShape.ZOrderPosition < targetShape.ZOrderPosition) { // last shape in front of first shape. Order the in-between shapes accordingly. foreach (var shape in newlyAddedShapes) { Graphics.MoveZUntilBehind(shape, targetShape); } } else { // first shape in front of last shape. Order the in-between shapes accordingly. newlyAddedShapes.Reverse(); foreach (var shape in newlyAddedShapes) { Graphics.MoveZUntilBehind(shape, sourceShape); } } } }