Closed IsakNaslundBh closed 1 week ago
I think it would also be valuable to be able to create a new slide from a slide master layout, and to be able to replace shapes with pictures as well (as picture placeholders are defined as Shape
in the ShapeTree
). I have a bit of code here that creates new slides from the master layout:
public static void CreateNewSlideFromLayout(PresentationPart presentationPart, SlideAddCommand command)
{
Slide slide = new Slide();
SlidePart slidePart = presentationPart.AddNewPart<SlidePart>();
slide.Save(slidePart);
SlideMasterPart slideMasterPart = presentationPart.SlideMasterParts.FirstOrDefault();
SlideLayoutPart slideLayoutPart = slideMasterPart.SlideLayoutParts.SingleOrDefault(sl => sl.SlideLayout.CommonSlideData.Name.Value.Equals(command.LayoutName, StringComparison.OrdinalIgnoreCase));
slidePart.AddPart(slideLayoutPart, slideMasterPart.GetIdOfPart(slideLayoutPart));
slidePart.Slide.CommonSlideData = (CommonSlideData)slideLayoutPart.SlideLayout.CommonSlideData.Clone();
string id = slideMasterPart.GetIdOfPart(slideLayoutPart);
slideMasterPart.AddPart(slideLayoutPart, id);
presentationPart.SetSlideID(slidePart, command.SlideNumber);
}
Where SetSlideID is the following:
private static void SetSlideID(this PresentationPart presentationPart, SlidePart slidePart, int position = -1)
{
SlideIdList slideIdList = presentationPart.Presentation.SlideIdList;
if (slideIdList == null)
{
slideIdList = new SlideIdList();
presentationPart.Presentation.SlideIdList = slideIdList;
}
if (position >= slideIdList.Count())
throw new InvalidOperationException($"Unable to set slide to position '{position}'. There are only '{slideIdList.Count()}' slides.");
uint newId = slideIdList.ChildElements.Count() == 0 ? 256 : slideIdList.GetMaxSlideId() + 1;
if (position < 0)
{
var newSlideId = slideIdList.AppendChild(new SlideId());
newSlideId.Id = newId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart);
}
else if (slideIdList.Count() == 0)
{
var newSlideId = slideIdList.AppendChild(new SlideId());
newSlideId.Id = newId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart);
}
else
{
SlideId nextSlideId = (SlideId)slideIdList.ChildElements[position];
var newSlideId = slideIdList.InsertBefore(new SlideId(), nextSlideId);
newSlideId.Id = newId;
newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart);
}
}
private static uint GetMaxSlideId(this SlideIdList slideIdList)
{
uint maxSlideId = 0;
if (slideIdList.ChildElements.Count() > 0)
maxSlideId = slideIdList.ChildElements
.Cast<SlideId>()
.Max(x => x.Id.Value);
return maxSlideId;
}
It needs a bit of tidying up (I think setting slide ID could be done better), but it's a good start
I think it would also be valuable to be able to create a new slide from a slide master layout, and to be able to replace shapes with pictures as well (as picture placeholders are defined as
Shape
in theShapeTree
). I have a bit of code here that creates new slides from the master layout:public static void CreateNewSlideFromLayout(PresentationPart presentationPart, SlideAddCommand command) { Slide slide = new Slide(); SlidePart slidePart = presentationPart.AddNewPart<SlidePart>(); slide.Save(slidePart); SlideMasterPart slideMasterPart = presentationPart.SlideMasterParts.FirstOrDefault(); SlideLayoutPart slideLayoutPart = slideMasterPart.SlideLayoutParts.SingleOrDefault(sl => sl.SlideLayout.CommonSlideData.Name.Value.Equals(command.LayoutName, StringComparison.OrdinalIgnoreCase)); slidePart.AddPart(slideLayoutPart, slideMasterPart.GetIdOfPart(slideLayoutPart)); slidePart.Slide.CommonSlideData = (CommonSlideData)slideLayoutPart.SlideLayout.CommonSlideData.Clone(); string id = slideMasterPart.GetIdOfPart(slideLayoutPart); slideMasterPart.AddPart(slideLayoutPart, id); presentationPart.SetSlideID(slidePart, command.SlideNumber); }
Where SetSlideID is the following:
private static void SetSlideID(this PresentationPart presentationPart, SlidePart slidePart, int position = -1) { SlideIdList slideIdList = presentationPart.Presentation.SlideIdList; if (slideIdList == null) { slideIdList = new SlideIdList(); presentationPart.Presentation.SlideIdList = slideIdList; } if (position >= slideIdList.Count()) throw new InvalidOperationException($"Unable to set slide to position '{position}'. There are only '{slideIdList.Count()}' slides."); uint newId = slideIdList.ChildElements.Count() == 0 ? 256 : slideIdList.GetMaxSlideId() + 1; if (position < 0) { var newSlideId = slideIdList.AppendChild(new SlideId()); newSlideId.Id = newId; newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart); } else if (slideIdList.Count() == 0) { var newSlideId = slideIdList.AppendChild(new SlideId()); newSlideId.Id = newId; newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart); } else { SlideId nextSlideId = (SlideId)slideIdList.ChildElements[position]; var newSlideId = slideIdList.InsertBefore(new SlideId(), nextSlideId); newSlideId.Id = newId; newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePart); } } private static uint GetMaxSlideId(this SlideIdList slideIdList) { uint maxSlideId = 0; if (slideIdList.ChildElements.Count() > 0) maxSlideId = slideIdList.ChildElements .Cast<SlideId>() .Max(x => x.Id.Value); return maxSlideId; }
It needs a bit of tidying up (I think setting slide ID could be done better), but it's a good start
Sounds like a really good idea @Tom-Kingstone . Not sure I will have time to fix in the current push I am doing though, so please, if you dont mid, think great if you can raise a separate issue for this :)
Description: