Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiple features to enhance presentation production #15

Closed
IsakNaslundBh opened this issue Jun 14, 2024 · 2 comments · Fixed by #21
Closed

Add multiple features to enhance presentation production #15

IsakNaslundBh opened this issue Jun 14, 2024 · 2 comments · Fixed by #21
Assignees
Labels
type:feature New capability or enhancement

Comments

@IsakNaslundBh
Copy link
Contributor

Description:

  • MultilineTextUpdate
  • ShapeColourUpdate
  • MultiPolylineUpdate
  • ImageUpdateStream
  • Make it possible to control colours on charts
@Tom-Kingstone
Copy link
Contributor

Tom-Kingstone commented Jun 14, 2024

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

@IsakNaslundBh
Copy link
Contributor Author

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

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New capability or enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants