mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-04 21:27:21 +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
@@ -63,21 +63,9 @@
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(this.revisedLua))
|
||||
{
|
||||
<MudExpansionPanels Dense="true" Elevation="0">
|
||||
<MudExpansionPanel Dense="true" Class="border-solid border rounded pt-n4" Style="border-color: #BDBDBD">
|
||||
<TitleContent>
|
||||
<div class="d-flex align-center">
|
||||
<MudIcon Icon="@Icons.Material.Filled.Code" Class="mr-3" Color="Color.Primary" />
|
||||
<MudText Typo="Typo.button">
|
||||
@T("Revised Lua plugin")
|
||||
</MudText>
|
||||
</div>
|
||||
</TitleContent>
|
||||
<ChildContent>
|
||||
<MudTextField T="string" Text="@this.revisedLua" ReadOnly="true" Variant="Variant.Outlined" Lines="18" Class="mt-2" Style="font-family: monospace" />
|
||||
</ChildContent>
|
||||
</MudExpansionPanel>
|
||||
</MudExpansionPanels>
|
||||
<CompactExpansionPanel HeaderText="@T("Revised Lua plugin")" HeaderIcon="@Icons.Material.Filled.Code" IconColor="Color.Primary">
|
||||
<MudTextField T="string" Text="@this.revisedLua" ReadOnly="true" Variant="Variant.Outlined" Lines="18" Class="mt-2" Style="font-family: monospace" />
|
||||
</CompactExpansionPanel>
|
||||
}
|
||||
|
||||
@if (this.isApplying || this.isAuditing)
|
||||
|
||||
@@ -38,21 +38,9 @@
|
||||
|
||||
@* The panel content is only built while it is open, so the plugin is written just
|
||||
for users who want to look at it. *@
|
||||
<MudExpansionPanels Dense="@true" Elevation="0">
|
||||
<MudExpansionPanel Dense="@true" Class="border-solid border rounded pt-n4" Style="border-color: #BDBDBD">
|
||||
<TitleContent>
|
||||
<div class="d-flex align-center">
|
||||
<MudIcon Icon="@Icons.Material.Filled.Code" Class="mr-3" Color="Color.Primary"/>
|
||||
<MudText Typo="Typo.button">
|
||||
@T("Resulting Lua plugin")
|
||||
</MudText>
|
||||
</div>
|
||||
</TitleContent>
|
||||
<ChildContent>
|
||||
<MudTextField T="string" Text="@this.BuildLua()" ReadOnly="@true" Variant="Variant.Outlined" Lines="18" Class="mt-2" Style="font-family: monospace"/>
|
||||
</ChildContent>
|
||||
</MudExpansionPanel>
|
||||
</MudExpansionPanels>
|
||||
<CompactExpansionPanel HeaderText="@T("Resulting Lua plugin")" HeaderIcon="@Icons.Material.Filled.Code" IconColor="Color.Primary">
|
||||
<MudTextField T="string" Text="@this.BuildLua()" ReadOnly="@true" Variant="Variant.Outlined" Lines="18" Class="mt-2" Style="font-family: monospace"/>
|
||||
</CompactExpansionPanel>
|
||||
|
||||
@if (this.IsBusy)
|
||||
{
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Assistants.SlideBuilder
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Tools.PowerPoint
|
||||
@using AIStudio.Tools.Rust
|
||||
@inherits SettingsDialogBase
|
||||
|
||||
<MudDialog>
|
||||
<TitleContent>
|
||||
<MudText Typo="Typo.h6" Class="d-flex align-center">
|
||||
<MudIcon Icon="@Icons.Material.Filled.Spellcheck" Class="mr-2" />
|
||||
@T("Assistant: Slide Planner Assistant Options")
|
||||
@T("Assistant: Slide Assistant Options")
|
||||
</MudText>
|
||||
</TitleContent>
|
||||
<DialogContent>
|
||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||
<ConfigurationOption OptionDescription="@T("Preselect Slide Planner Assistant options?")" LabelOn="@T("Slide Planner Assistant options are preselected")" LabelOff="@T("No Slide Planner Assistant options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect slide builder options. This is might be useful when you prefer a specific language or LLM model.")"/>
|
||||
<ConfigurationOption OptionDescription="@T("Preselect Slide Assistant options?")" LabelOn="@T("Slide Assistant options are preselected")" LabelOff="@T("No Slide Assistant options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect options of the Slide Assistant. This might be useful when you prefer a specific language or LLM model.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectOptions, out var meta) && meta.IsLocked"/>
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mb-3">@T("Content and audience")</MudText>
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@T("Preselect what the assistant starts with for each presentation: the aspects to emphasize, the language, the audience, and the occasion. You can still change them in the assistant.")
|
||||
</MudJustifiedText>
|
||||
<ConfigurationText OptionDescription="@T("Preselect important aspects")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" Text="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedImportantAspects)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedImportantAspects = updatedText)" NumLines="2" OptionHelp="@T("Preselect aspects for the LLM to focus on when generating slides, such as bullet points or specific topics to emphasize.")" Icon="@Icons.Material.Filled.List"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect the language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedTargetLanguage = selectedValue)" OptionHelp="@T("Which language should be preselected?")"/>
|
||||
@if (this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||
@@ -21,6 +29,74 @@
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect the audience age group")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedAudienceAgeGroup)" Data="@ConfigurationSelectDataFactory.GetSlideBuilderAudienceAgeGroupData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedAudienceAgeGroup = selectedValue)" OptionHelp="@T("Which audience age group should be preselected?")"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect the audience organizational level")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedAudienceOrganizationalLevel)" Data="@ConfigurationSelectDataFactory.GetSlideBuilderAudienceOrganizationalLevelData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedAudienceOrganizationalLevel = selectedValue)" OptionHelp="@T("Which audience organizational level should be preselected?")"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect the audience expertise")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedAudienceExpertise)" Data="@ConfigurationSelectDataFactory.GetSlideBuilderAudienceExpertiseData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedAudienceExpertise = selectedValue)" OptionHelp="@T("Which audience expertise should be preselected?")"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect the occasion")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedOccasion)" Data="@ConfigurationSelectDataFactory.GetSlideBuilderOccasionData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedOccasion = selectedValue)" OptionHelp="@T("Which occasion of the presentation should be preselected?")"/>
|
||||
@if (this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedOccasion is PresentationOccasion.OTHER)
|
||||
{
|
||||
<ConfigurationText OptionDescription="@T("Preselect another occasion")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" Icon="@Icons.Material.Filled.Event" Text="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedOtherOccasion)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedOtherOccasion = updatedText)"/>
|
||||
}
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mb-3 mt-6">@T("PowerPoint template")</MudText>
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@SlideAssistantTexts.WhatTheLLMKnowsOfLayouts
|
||||
</MudJustifiedText>
|
||||
<ConfigurationFile OptionDescription="@T("Preselect a PowerPoint template")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" Icon="@Icons.Material.Filled.Slideshow" Text="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.TemplatePath)" TextUpdate="@this.SetTemplatePath" FileDialogTitle="@T("Select a PowerPoint template")" Filter="@([FileTypes.POWER_POINT_TEMPLATE])" OptionHelp="@T("The slides use the layouts of this PowerPoint presentation or template (.pptx, .potx), and you can create a PowerPoint file (.pptx) from the result. OpenDocument presentations (.odp, .otp) cannot serve as a template yet. Leave it empty to plan an outline only.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.TemplatePath, out var meta) && meta.IsLocked"/>
|
||||
<ConfigurationText OptionDescription="@T("Preselect the footer text")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" Icon="@Icons.Material.Filled.ShortText" Text="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedFooterText)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedFooterText = updatedText)" OptionHelp="@T("Shown on every slide whose layout has a footer, e.g., your name, organization, and date. Leave it empty for no footer.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectedFooterText, out var meta) && meta.IsLocked"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect the maximum number of bullet points per slide")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedMaxBulletPointsPerSlide)" Data="@this.BulletPointMaximumOptions" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedMaxBulletPointsPerSlide = selectedValue)" OptionHelp="@T("A slide holds at most this many bullet points, in all of its text slots together. Match it to the room for text in the layouts of your template.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectedMaxBulletPointsPerSlide, out var meta) && meta.IsLocked"/>
|
||||
<ConfigurationOption OptionDescription="@T("Preselect keeping empty picture placeholders?")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" LabelOn="@T("Empty picture placeholders are kept")" LabelOff="@T("Empty picture placeholders are left out")" State="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedKeepEmptyPicturePlaceholders)" StateUpdate="@(value => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedKeepEmptyPicturePlaceholders = value)" OptionHelp="@SlideAssistantTexts.WhatKeepingEmptyPicturePlaceholdersDoes" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectedKeepEmptyPicturePlaceholders, out var meta) && meta.IsLocked"/>
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mb-3 mt-6">@T("Layouts for kinds of slides")</MudText>
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@if (this.layoutOptions.Count > 0)
|
||||
{
|
||||
@SlideAssistantTexts.WhatALayoutChoiceDoes
|
||||
}
|
||||
else
|
||||
{
|
||||
@T("Preselect a readable template above to choose its layouts for kinds of slides.")
|
||||
}
|
||||
</MudJustifiedText>
|
||||
@if (this.layoutOptions.Count > 0)
|
||||
{
|
||||
<LayoutChoicePanels IsChosen="@(purpose => this.PreselectedLayoutOf(purpose).Length > 0)">
|
||||
<ChoiceContent Context="purpose">
|
||||
<ConfigurationSelect OptionDescription="@purpose.Label()" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.PreselectedLayoutOf(purpose))" Data="@this.layoutOptions" SelectionUpdate="@(selectedValue => this.SetPreselectedLayout(purpose, selectedValue))" OptionHelp="@purpose.Help()" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectedLayouts, out var meta) && meta.IsLocked"/>
|
||||
</ChoiceContent>
|
||||
</LayoutChoicePanels>
|
||||
}
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mb-3 mt-6">@T("Slides of the template")</MudText>
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@if (this.template is { Slides.Count: > 0 })
|
||||
{
|
||||
@SlideAssistantTexts.WhatHappensToTemplateSlides
|
||||
}
|
||||
else if (this.template is not null)
|
||||
{
|
||||
@T("The preselected template contains no slides besides its layouts.")
|
||||
}
|
||||
else
|
||||
{
|
||||
@T("Preselect a readable template above to choose what the presentation does with its slides.")
|
||||
}
|
||||
</MudJustifiedText>
|
||||
@if (this.template is { } loadedTemplate)
|
||||
{
|
||||
@foreach (var templateSlide in loadedTemplate.Slides)
|
||||
{
|
||||
<ConfigurationSelect OptionDescription="@templateSlide.Label()" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.PreselectedUseOf(templateSlide))" Data="@UseOptionsOf(templateSlide)" SelectionUpdate="@(selectedValue => this.SetPreselectedUse(templateSlide.Number, selectedValue))" IsLocked="@AreTemplateSlideUsesLocked"/>
|
||||
}
|
||||
}
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mb-3 mt-6">@T("Visual elements")</MudText>
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@SlideAssistantTexts.WhatAPictureLibraryOffers
|
||||
</MudJustifiedText>
|
||||
<ConfigurationDirectory OptionDescription="@T("Preselect a picture library")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" Icon="@Icons.Material.Filled.PhotoLibrary" Text="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedPictureLibraryPath)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedPictureLibraryPath = updatedText)" DirectoryDialogTitle="@T("Select a picture library")" OptionHelp="@T("The LLM may choose pictures and icons for the slides from this folder. Leave it empty for no picture library.")" IsLocked="() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectedPictureLibraryPath, out var meta) && meta.IsLocked"/>
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mb-3 mt-6">@T("AI selection")</MudText>
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@T("Preselect which LLM plans the slides and which profile it gets. A profile can, e.g., name your organization, which the LLM may use for the imprint.")
|
||||
</MudJustifiedText>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.SLIDE_BUILDER_ASSISTANT" Data="@this.AvailableLLMProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationSelect OptionDescription="@T("Preselect a profile")" Disabled="@(() => !this.SettingsManager.ConfigurationData.SlideBuilder.PreselectOptions)" SelectedValue="@(() => ProfilePreselection.FromStoredValue(this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedProfile))" Data="@ConfigurationSelectDataFactory.GetComponentProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedProfile = selectedValue)" OptionHelp="@T("Choose whether the assistant should use the app default profile, no profile, or a specific profile.")"/>
|
||||
|
||||
@@ -1,3 +1,166 @@
|
||||
namespace AIStudio.Dialogs.Settings;
|
||||
using System.Globalization;
|
||||
|
||||
public partial class SettingsDialogSlideBuilder : SettingsDialogBase;
|
||||
using AIStudio.Assistants.SlideBuilder;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Settings.DataModel;
|
||||
using AIStudio.Tools.PowerPoint;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Dialogs.Settings;
|
||||
|
||||
public partial class SettingsDialogSlideBuilder : SettingsDialogBase
|
||||
{
|
||||
[Inject]
|
||||
private ILogger<SettingsDialogSlideBuilder> Logger { get; init; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// What the preselections of layouts offer: no preference, then the layouts of the preselected template.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Empty while no template is preselected or the template cannot be read; the dialog then says so
|
||||
/// instead of offering layouts.
|
||||
/// </remarks>
|
||||
private List<ConfigurationSelectData<string>> layoutOptions = [];
|
||||
|
||||
/// <summary>
|
||||
/// The preselected template, whose slides the dialog offers; null while none is preselected or it cannot be read.
|
||||
/// </summary>
|
||||
private PresentationTemplate? template;
|
||||
|
||||
/// <summary>
|
||||
/// The path the template and the layout options were read from; null before the first reading.
|
||||
/// </summary>
|
||||
private string? templatePathRead;
|
||||
|
||||
/// <summary>
|
||||
/// What the preselection of the maximum number of bullet points offers: no maximum, then 1 up to the most a slide may hold.
|
||||
/// </summary>
|
||||
private IEnumerable<ConfigurationSelectData<int>> BulletPointMaximumOptions => [new(T("No maximum"), 0), ..Enumerable.Range(1, DataSlideBuilder.MAX_BULLET_POINTS_PER_SLIDE).Select(count => new ConfigurationSelectData<int>(count.ToString(CultureInfo.InvariantCulture), count))];
|
||||
|
||||
#region Overrides of SettingsDialogBase
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.ReadTemplate();
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
{
|
||||
// The template may change in this dialog, or through a configuration plugin:
|
||||
if (triggeredEvent is Event.CONFIGURATION_CHANGED or Event.PLUGINS_RELOADED)
|
||||
this.ReadTemplate();
|
||||
|
||||
await base.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Reads the layouts and the slides of the preselected template, unless they were read from it already.
|
||||
/// </summary>
|
||||
private void ReadTemplate()
|
||||
{
|
||||
var templatePath = this.SettingsManager.ConfigurationData.SlideBuilder.TemplatePath;
|
||||
if (string.Equals(templatePath, this.templatePathRead, StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
this.templatePathRead = templatePath;
|
||||
this.template = null;
|
||||
this.layoutOptions = [];
|
||||
if (string.IsNullOrWhiteSpace(templatePath) || !File.Exists(templatePath))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
this.template = PresentationTemplate.ReadFile(templatePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logger.LogWarning(e, "The PowerPoint template '{TemplatePath}' cannot be read.", templatePath);
|
||||
return;
|
||||
}
|
||||
|
||||
this.layoutOptions = [new(LayoutPurposeExtensions.NoPreference, string.Empty), ..this.template.FamilyNames.Select(name => new ConfigurationSelectData<string>(name, name))];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Preselects a template, and forgets what was preselected for the slides of the previous one.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The choices number the slides of a template, so they mean nothing for another one. A lock of
|
||||
/// the organization keeps them, though: its template and its choices belong together.
|
||||
/// </remarks>
|
||||
private void SetTemplatePath(string path)
|
||||
{
|
||||
var settings = this.SettingsManager.ConfigurationData.SlideBuilder;
|
||||
if (string.Equals(settings.TemplatePath, path, StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
settings.TemplatePath = path;
|
||||
if (!AreTemplateSlideUsesLocked())
|
||||
settings.PreselectedTemplateSlideUses = new();
|
||||
}
|
||||
|
||||
private static bool AreTemplateSlideUsesLocked() => ManagedConfiguration.TryGet(x => x.SlideBuilder, x => x.PreselectedTemplateSlideUses, out var meta) && meta.IsLocked;
|
||||
|
||||
/// <summary>
|
||||
/// What the dialog offers for a slide of the template: editing only where the slide has placeholders for content.
|
||||
/// </summary>
|
||||
private static List<ConfigurationSelectData<TemplateSlideUse>> UseOptionsOf(TemplateSlide slide) => Enum.GetValues<TemplateSlideUse>()
|
||||
.Where(use => use is not TemplateSlideUse.EDIT || slide.IsEditable)
|
||||
.Select(use => new ConfigurationSelectData<TemplateSlideUse>(use.Name(), use))
|
||||
.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// What is preselected for a slide of the template, as the assistant applies it.
|
||||
/// </summary>
|
||||
/// <returns>The use; a slide which is missing is left out, and one which cannot be edited is kept unchanged instead.</returns>
|
||||
private TemplateSlideUse PreselectedUseOf(TemplateSlide slide) => this.template is null ? TemplateSlideUse.OMIT : this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedTemplateSlideUses.ToTemplateSlideUses(this.template).UseOf(slide.Number);
|
||||
|
||||
/// <summary>
|
||||
/// Preselects what the presentation does with a slide of the template.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Leaving a slide out is the default, so it is stored as no entry. The dictionary is replaced
|
||||
/// instead of changed, so that no other holder of it, such as the default of a configuration
|
||||
/// plugin, changes along.
|
||||
/// </remarks>
|
||||
private void SetPreselectedUse(int number, TemplateSlideUse use)
|
||||
{
|
||||
var uses = new Dictionary<int, TemplateSlideUse>(this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedTemplateSlideUses);
|
||||
if (use is TemplateSlideUse.OMIT)
|
||||
uses.Remove(number);
|
||||
else
|
||||
uses[number] = use;
|
||||
|
||||
this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedTemplateSlideUses = uses;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the layout preselected for a kind of slide, as the dialog shows it.
|
||||
/// </summary>
|
||||
/// <returns>The name, or empty when the LLM decides, which it also does when the template has no layout of this name.</returns>
|
||||
private string PreselectedLayoutOf(LayoutPurpose purpose) => this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedLayouts.TryGetValue(purpose, out var name) && this.layoutOptions.Any(option => string.Equals(option.Value, name, StringComparison.Ordinal)) ? name : string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselects a layout for a kind of slide, or no preference for an empty name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The dictionary is replaced instead of changed, so that no other holder of it, such as the
|
||||
/// default of a configuration plugin, changes along.
|
||||
/// </remarks>
|
||||
private void SetPreselectedLayout(LayoutPurpose purpose, string name)
|
||||
{
|
||||
var layouts = new Dictionary<LayoutPurpose, string>(this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedLayouts);
|
||||
if (name.Length == 0)
|
||||
layouts.Remove(purpose);
|
||||
else
|
||||
layouts[purpose] = name;
|
||||
|
||||
this.SettingsManager.ConfigurationData.SlideBuilder.PreselectedLayouts = layouts;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user