mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-04 20:47:22 +00:00
Added PowerPoint templates to the Slide Assistant (#1055)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
8c5cfa78b6
commit
6eb23ebbcb
136 files changed
+16535
-522
No files matched your search
@@ -0,0 +1,78 @@
|
||||
using DocumentFormat.OpenXml;
|
||||
|
||||
using A = DocumentFormat.OpenXml.Drawing;
|
||||
using P = DocumentFormat.OpenXml.Presentation;
|
||||
|
||||
namespace AIStudio.Tools.PowerPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Which shapes of a slide fill which slots of its layout.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Reading a template and editing one of its slides ask the same question, so they share the answer:
|
||||
/// what the model is told a slot holds is what a new content replaces.
|
||||
/// </remarks>
|
||||
internal static class TemplateSlideShapes
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds the shapes of a slide which fill the slots of its layout.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A placeholder fills the slot of its type and index; of two placeholders for one slot, the
|
||||
/// first counts, while the second may be read as a copy of the slot, as a text box copied from
|
||||
/// the placeholder is. A table slot whose placeholder holds no table, or which the slide leaves out,
|
||||
/// takes a table which is no placeholder at all: an author who pastes a table onto the slide,
|
||||
/// or whose table lost the link to its placeholder on the way, still means it as the table of
|
||||
/// the slide. Such tables fill these table slots in the order of the slide.
|
||||
/// </remarks>
|
||||
/// <param name="shapeTree">The shape tree of the slide.</param>
|
||||
/// <param name="layout">The layout the slide is based on.</param>
|
||||
/// <returns>The top-level shape filling each slot; slots the slide leaves out are missing.</returns>
|
||||
public static Dictionary<TemplateSlot, OpenXmlElement> SlotShapesOf(P.ShapeTree? shapeTree, TemplateLayout layout)
|
||||
{
|
||||
var elements = shapeTree?.Elements().ToList() ?? [];
|
||||
var shapesBySlot = new Dictionary<TemplateSlot, OpenXmlElement>();
|
||||
foreach (var element in elements)
|
||||
{
|
||||
if (PlaceholderOf(element) is { } placeholder && layout.SlotOf(placeholder.Type?.InnerText ?? "obj", placeholder.Index?.Value) is { } slot)
|
||||
shapesBySlot.TryAdd(slot, element);
|
||||
}
|
||||
|
||||
var freeTables = new Queue<OpenXmlElement>(elements.Where(element => PlaceholderOf(element) is null && HoldsTable(element)));
|
||||
foreach (var slot in layout.Slots.Where(slot => slot.Role is PlaceholderRole.TABLE && !(shapesBySlot.GetValueOrDefault(slot) is { } shape && HoldsTable(shape))))
|
||||
{
|
||||
if (!freeTables.TryDequeue(out var table))
|
||||
break;
|
||||
|
||||
shapesBySlot[slot] = table;
|
||||
}
|
||||
|
||||
return shapesBySlot;
|
||||
}
|
||||
|
||||
private static bool HoldsTable(OpenXmlElement element) => element is P.GraphicFrame frame && frame.Graphic?.GraphicData?.GetFirstChild<A.Table>() is not null;
|
||||
|
||||
/// <summary>
|
||||
/// The ID of a top-level element of a slide: a shape, a picture, a graphic frame, a group, a
|
||||
/// connector, or something wrapped for newer versions of PowerPoint.
|
||||
/// </summary>
|
||||
/// <returns>The ID, or null for anything else, e.g., the properties of the shape tree itself.</returns>
|
||||
public static uint? ShapeIdOf(OpenXmlElement element) => element switch
|
||||
{
|
||||
P.Shape or P.Picture or P.GraphicFrame or P.GroupShape or P.ConnectionShape or AlternateContent => element.Descendants<P.NonVisualDrawingProperties>().FirstOrDefault()?.Id?.Value,
|
||||
|
||||
_ => null,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The placeholder a shape, a picture or a table of a slide fills; null for anything else.
|
||||
/// </summary>
|
||||
public static P.PlaceholderShape? PlaceholderOf(OpenXmlElement element) => element switch
|
||||
{
|
||||
P.Shape shape => shape.NonVisualShapeProperties?.ApplicationNonVisualDrawingProperties?.PlaceholderShape,
|
||||
P.Picture picture => picture.NonVisualPictureProperties?.ApplicationNonVisualDrawingProperties?.PlaceholderShape,
|
||||
P.GraphicFrame frame => frame.NonVisualGraphicFrameProperties?.ApplicationNonVisualDrawingProperties?.PlaceholderShape,
|
||||
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user