private static void UpdateBeamOnSlide(PowerPointSlide slide, Shape refBeamShape) { RemoveBeamAgendaFromSlide(slide); refBeamShape.Copy(); var beamShape = slide.Shapes.Paste(); var section = GetSlideSection(slide); beamShape.GroupItems.Cast <Shape>() .Where(AgendaShape.WithPurpose(ShapePurpose.BeamShapeHighlightedText)) .ToList() .ForEach(shape => shape.Delete()); if (section.Index == 1) { return; } var beamFormats = BeamFormats.ExtractFormats(refBeamShape); var currentSectionTextBox = beamShape.GroupItems .Cast <Shape>() .Where(AgendaShape.MeetsConditions(shape => shape.ShapePurpose == ShapePurpose.BeamShapeText && shape.Section.Index == section.Index)) .FirstOrDefault(); var currentSectionText = currentSectionTextBox.TextFrame2.TextRange; Graphics.SyncTextRange(beamFormats.Highlighted, currentSectionText, pickupTextContent: false); }
private static void RemoveBeamAgendaFromSlide(PowerPointSlide slide) { slide.Shapes.Cast <Shape>() .Where(AgendaShape.WithPurpose(ShapePurpose.BeamShapeMainGroup)) .ToList() .ForEach(shape => shape.Delete()); }
private static PowerPointSlide CreateBulletReferenceSlide() { var refSlide = PowerPointSlide.FromSlideFactory(PowerPointPresentation.Current .Presentation .Slides .Add(1, PpSlideLayout.ppLayoutText)); refSlide.Transition.EntryEffect = PpEntryEffect.ppEffectPushUp; refSlide.Transition.Duration = 0.8f; var titleShape = refSlide.Shapes.Placeholders[1]; var contentShape = refSlide.Shapes.Placeholders[2]; AgendaShape.SetShapeName(contentShape, ShapePurpose.ContentShape, AgendaSection.None); Graphics.SetText(titleShape, TextCollection.AgendaLabTitleContent); Graphics.SetText(contentShape, TextCollection.AgendaLabBulletVisitedContent, TextCollection.AgendaLabBulletHighlightedContent, TextCollection.AgendaLabBulletUnvisitedContent); var paragraphs = Graphics.GetParagraphs(contentShape); paragraphs[0].Font.Fill.ForeColor.RGB = Graphics.ConvertColorToRgb(Color.Gray); paragraphs[1].Font.Fill.ForeColor.RGB = Graphics.ConvertColorToRgb(Color.Red); paragraphs[2].Font.Fill.ForeColor.RGB = Graphics.ConvertColorToRgb(Color.Black); AgendaSlide.SetAsReferenceSlideName(refSlide, Type.Bullet); refSlide.AddTemplateSlideMarker(); refSlide.Hidden = true; return(refSlide); }
private static Dictionary <int, Shape> GetImageShapeAssignment(PowerPointSlide inSlide, out List <Shape> unassignedShapes) { var shapes = inSlide.Shapes.Cast <Shape>(); unassignedShapes = new List <Shape>(); var shapeAssignment = new Dictionary <int, Shape>(); foreach (var shape in shapes) { var agendaShape = AgendaShape.Decode(shape); if (agendaShape == null || agendaShape.ShapePurpose != ShapePurpose.VisualAgendaImage) { continue; } int index = agendaShape.Section.Index; if (shapeAssignment.ContainsKey(index)) { unassignedShapes.Add(shape); } else { shapeAssignment.Add(index, shape); } } return(shapeAssignment); }
private static void DeleteVisualAgendaImageShapes(PowerPointSlide slide) { slide.Shapes.Cast <Shape>() .Where(AgendaShape.WithPurpose(ShapePurpose.VisualAgendaImage)) .ToList() .ForEach(shape => shape.Delete()); }
/// <summary> /// Reorganises the positions of all the text boxes in the beam. /// </summary> private static void ReorganiseBeam(PowerPointSlide refSlide, List <AgendaSection> newSections, Shape highlightedTextBox, Shape background, BeamFormats beamFormats, List <Shape> oldTextBoxes, Shape beamShape) { var newTextBoxes = CreateBeamAgendaTextBoxes(refSlide, newSections); SetupBeamTextBoxPositions(newTextBoxes, highlightedTextBox, background); for (int i = 0; i < newTextBoxes.Count; ++i) { var referenceTextFormat = beamFormats.Regular; if (i < oldTextBoxes.Count) { referenceTextFormat = oldTextBoxes[i].TextFrame2.TextRange; } Graphics.SyncTextRange(referenceTextFormat, newTextBoxes[i].TextFrame2.TextRange, pickupTextContent: false); } oldTextBoxes.ForEach(shape => shape.Delete()); var beamShapeShapes = beamShape.Ungroup().Cast <Shape>().ToList(); beamShapeShapes.AddRange(newTextBoxes); beamShape = refSlide.GroupShapes(beamShapeShapes); AgendaShape.SetShapeName(beamShape, ShapePurpose.BeamShapeMainGroup, AgendaSection.None); }
private static Shape CreateSectionImage(PowerPointSlide refSlide, AgendaSection section) { var sectionFirstSlide = FindSectionFirstNonAgendaSlide(section.Index); var shape = refSlide.InsertEntrySnapshotOfSlide(sectionFirstSlide); AgendaShape.SetShapeName(shape, ShapePurpose.VisualAgendaImage, section); return(shape); }
private static Shape PrepareBeamAgendaBackground(PowerPointSlide slide) { var background = slide.Shapes.AddShape(MsoAutoShapeType.msoShapeRectangle, 0, 0, 0, 0); AgendaShape.SetShapeName(background, ShapePurpose.BeamShapeBackground, AgendaSection.None); background.Line.Visible = MsoTriState.msoFalse; background.Fill.ForeColor.RGB = Graphics.ConvertColorToRgb(Color.Black); background.Width = PowerPointPresentation.Current.SlideWidth; return(background); }
public static bool IsBeamShape(Shape shape) { AgendaShape agendaShape = Decode(shape); if (agendaShape == null) { return(false); } return(agendaShape.ShapePurpose == ShapePurpose.BeamShapeMainGroup); }
private static Shape PrepareBeamAgendaBeamItem(PowerPointSlide slide, AgendaSection section) { var textBox = slide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 0, 0); AgendaShape.SetShapeName(textBox, ShapePurpose.BeamShapeText, section); textBox.TextFrame.AutoSize = PpAutoSize.ppAutoSizeShapeToFitText; textBox.TextFrame.WordWrap = MsoTriState.msoFalse; textBox.TextFrame.TextRange.Text = section.Name; textBox.TextFrame.TextRange.Font.Color.RGB = Graphics.ConvertColorToRgb(Color.White); return(textBox); }
/// <summary> /// Returns a condition (function) that is true iff the shape's purpose is the purpose specified in the argument. /// </summary> public static Func <Shape, bool> WithPurpose(ShapePurpose purpose) { return(shape => { AgendaShape agendaShape = Decode(shape); if (agendaShape == null) { return false; } return agendaShape.ShapePurpose == purpose; }); }
/// <summary> /// </summary> /// <param name="condition">Input a condition on (AgendaShape : bool)</param> /// <returns>Output a condition on (Shape : bool).</returns> public static Func <Shape, bool> MeetsConditions(Predicate <AgendaShape> condition) { return(shape => { AgendaShape agendaShape = Decode(shape); if (agendaShape == null) { return false; } return condition(agendaShape); }); }
private static Shape CreateHighlightedTextBox(PowerPointSlide slide) { var textBox = slide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 0, 0); AgendaShape.SetShapeName(textBox, ShapePurpose.BeamShapeHighlightedText, AgendaSection.None); textBox.TextFrame.AutoSize = PpAutoSize.ppAutoSizeShapeToFitText; textBox.TextFrame.WordWrap = MsoTriState.msoFalse; textBox.TextFrame.TextRange.Text = TextCollection.AgendaLabBeamHighlightedText; textBox.TextFrame.TextRange.Font.Color.RGB = Graphics.ConvertColorToRgb(Color.Yellow); return(textBox); }
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(); }
/// <summary> /// Extracts a list of the current sections from textboxes of the beamshape. /// If the textboxes are not consistent (e.g. repeated or missing section), returns null instead. /// </summary> private static List <AgendaSection> ExtractAgendaSectionsFromBeam(Shape beamShape) { var agendaSections = beamShape.GroupItems.Cast <Shape>() .Where(AgendaShape.WithPurpose(ShapePurpose.BeamShapeText)) .Select(shape => AgendaShape.Decode(shape).Section) .ToList(); agendaSections.Sort((s1, s2) => s1.Index - s2.Index); for (int i = 0; i < agendaSections.Count; ++i) { if (agendaSections[i].Index != i + 2) { return(null); } } return(agendaSections); }
/// <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(); } }
private static void CreateBeamAgendaShapes(PowerPointSlide refSlide, Direction beamDirection = Direction.Top) { var sections = GetAllButFirstSection(); var background = PrepareBeamAgendaBackground(refSlide); var textBoxes = CreateBeamAgendaTextBoxes(refSlide, sections); var highlightedTextBox = CreateHighlightedTextBox(refSlide); SetupBeamTextBoxPositions(textBoxes, highlightedTextBox, background); MatchColour(highlightedTextBox, background); var beamShapeItems = new List <Shape>(); beamShapeItems.Add(background); beamShapeItems.Add(highlightedTextBox); beamShapeItems.AddRange(textBoxes); var group = refSlide.GroupShapes(beamShapeItems); AgendaShape.SetShapeName(group, ShapePurpose.BeamShapeMainGroup, AgendaSection.None); }
/// <summary> /// Assumes that all shapes in textboxes are beam shape textboxes. /// </summary> private static Dictionary <int, Shape> GetBeamTextboxAssignment(IEnumerable <Shape> textboxes, out List <Shape> unassignedShapes) { unassignedShapes = new List <Shape>(); var shapeAssignment = new Dictionary <int, Shape>(); foreach (var shape in textboxes) { var agendaShape = AgendaShape.Decode(shape); int index = agendaShape.Section.Index; if (shapeAssignment.ContainsKey(index)) { unassignedShapes.Add(shape); } else { shapeAssignment.Add(index, shape); } } return(shapeAssignment); }
/// <summary> /// Does not reogranise the positions of the text boxes in the beam. Instead, it only deletes text boxes /// that no longer correspond to a section, and creates new text boxes for the new sections. /// </summary> private static void UpdateBeamItems(PowerPointSlide refSlide, List <AgendaSection> newSections, Shape highlightedTextBox, Shape background, BeamFormats beamFormats, List <Shape> oldTextBoxes, Shape beamShape) { List <Shape> markedForDeletion; var textboxAssignment = GetBeamTextboxAssignment(oldTextBoxes, out markedForDeletion); var reassignedTextboxIndexes = new HashSet <int>(); var newTextboxes = new List <Shape>(); foreach (var section in newSections) { int index = section.Index; if (textboxAssignment.ContainsKey(index)) { // Reuse old textbox var textbox = textboxAssignment[index]; Graphics.SetText(textbox, section.Name); AgendaShape.SetShapeName(textbox, ShapePurpose.BeamShapeText, section); reassignedTextboxIndexes.Add(index); } else { // Create new textbox var textbox = PrepareBeamAgendaBeamItem(refSlide, section); var referenceTextFormat = beamFormats.Regular; Graphics.SyncTextRange(referenceTextFormat, textbox.TextFrame2.TextRange, pickupTextContent: false); newTextboxes.Add(textbox); } } markedForDeletion.AddRange(from entry in textboxAssignment where !reassignedTextboxIndexes.Contains(entry.Key) select entry.Value); markedForDeletion.ForEach(shape => shape.Delete()); var beamShapeShapes = beamShape.Ungroup().Cast <Shape>().ToList(); beamShapeShapes.AddRange(newTextboxes); beamShape = refSlide.GroupShapes(beamShapeShapes); AgendaShape.SetShapeName(beamShape, ShapePurpose.BeamShapeMainGroup, AgendaSection.None); }
#pragma warning disable 0618 #region Main Synchronisation Function /// <summary> /// Call the function like this for example: /// SynchroniseSlidesUsingTemplate(slideTracker, refSlide, () => new VisualAgendaTemplate()); /// generateTemplate is a function that returns a newly created template. /// </summary> private static void SynchroniseSlidesUsingTemplate(SlideSelectionTracker slideTracker, PowerPointSlide refSlide, Func <AgendaTemplate> generateTemplate) { List <AgendaSection> sections = Sections; List <string> deletedShapeNames = RetrieveTrackedDeletions(refSlide); refSlide.DeleteSlideNumberShapes(); refSlide.MakeShapeNamesNonDefault(); refSlide.MakeShapeNamesUnique(shape => !AgendaShape.IsAnyAgendaShape(shape) && !PowerPointSlide.IsTemplateSlideMarker(shape)); ScrambleSlideSectionNames(); foreach (AgendaSection currentSection in sections) { AgendaTemplate template = generateTemplate(); ConfigureTemplate(currentSection, template); TemplateIndexTable templateTable = RebuildSectionUsingTemplate(slideTracker, currentSection, template); SynchroniseAllSlides(template, templateTable, refSlide, sections, deletedShapeNames, currentSection); } TrackShapesInSlide(refSlide); }
private static void AdjustBulletReferenceSlideContent(PowerPointSlide refSlide) { int numberOfSections = NumberOfSections; // post process bullet points var contentHolder = refSlide.GetShape(AgendaShape.WithPurpose(ShapePurpose.ContentShape)); var textRange = contentHolder.TextFrame2.TextRange; while (textRange.Paragraphs.Count < numberOfSections) { textRange.InsertAfter("\r "); } while (textRange.Paragraphs.Count > 3 && textRange.Paragraphs.Count > numberOfSections) { textRange.Paragraphs[textRange.Paragraphs.Count].Delete(); } for (var i = 4; i <= textRange.Paragraphs.Count; i++) { textRange.Paragraphs[i].ParagraphFormat.Bullet.Type = MsoBulletType.msoBulletNone; } }
public static List <Shape> GetAllShapesWithPurpose(Shape beamShape, ShapePurpose purpose) { return(beamShape.GroupItems.Cast <Shape>().Where(AgendaShape.WithPurpose(purpose)).ToList()); }
public static Shape GetShapeWithPurpose(Shape beamShape, ShapePurpose purpose) { return(beamShape.GroupItems.Cast <Shape>().FirstOrDefault(AgendaShape.WithPurpose(purpose))); }
/// <summary> /// Searches for the visual agenda image shape that corresponds to the given section index in the slide and returns it. /// </summary> private static Shape FindShapeCorrespondingToSection(PowerPointSlide inSlide, int sectionIndex) { return(inSlide.GetShape(AgendaShape.MeetsConditions(shape => shape.ShapePurpose == ShapePurpose.VisualAgendaImage && sectionIndex == shape.Section.Index))); }
private static bool InvalidBulletAgendaReferenceSlide(PowerPointSlide refSlide) { var contentHolder = refSlide.GetShape(AgendaShape.WithPurpose(ShapePurpose.ContentShape)); return(contentHolder == null || contentHolder.TextFrame2.TextRange.Paragraphs.Count < 3); }