From f070e77f35434a91d96c5e0a545d94dadd1d4f5d Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Mon, 7 Feb 2022 12:54:08 -0500 Subject: [PATCH] refactored settings parser into separate file to be merged into UWT proper --- .../DataFormats/UEPackage/SettingsParser.cs | 291 ++++++++++++++++++ .../UEPackage/SettingsXMLSchema.cs | 35 +++ .../UEPackage/UEPackageXMLDataFormat.cs | 18 +- .../UniversalEditor.Essential.csproj | 2 + 4 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsParser.cs create mode 100644 Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsXMLSchema.cs diff --git a/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsParser.cs b/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsParser.cs new file mode 100644 index 00000000..0320322b --- /dev/null +++ b/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsParser.cs @@ -0,0 +1,291 @@ +// +// SettingsParser.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2022 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Linq; +using MBS.Framework; +using MBS.Framework.Settings; +using UniversalEditor.ObjectModels.Markup; + +namespace UniversalEditor.DataFormats.UEPackage +{ + /// + /// Provides utility functions for parsing objects from + /// XML definitions. + /// + public class SettingsParser + { + /// + /// Converts an XML settings path definition to a + /// array. + /// + /// The array containing the path information. + /// The containing the XML to parse. + public static string[] ParsePath(MarkupTagElement tag) + { + if (tag == null) return null; + if (tag.FullName != "Path") return null; + + List path = new List(); + foreach (MarkupElement el in tag.Elements) + { + MarkupTagElement tag2 = (el as MarkupTagElement); + if (tag2 == null) continue; + if (tag2.FullName != "Part") continue; + + path.Add(tag2.Value); + } + return path.ToArray(); + } + + /// + /// Converts an XML settings definition into a + /// object of the appropriate type. + /// + /// The parsed setting. + /// The containing the XML to parse. + public static Setting ParseSetting(MarkupTagElement tag) + { + if (tag == null) return null; + + MarkupAttribute attSettingID = tag.Attributes["ID"]; + MarkupAttribute attSettingName = tag.Attributes["Name"]; + MarkupAttribute attSettingTitle = tag.Attributes["Title"]; + MarkupAttribute attSettingDescription = tag.Attributes["Description"]; + + MarkupAttribute attDefaultValue = tag.Attributes["DefaultValue"]; + + Setting s = null; + switch (tag.FullName) + { + case SettingsXMLSchema.BooleanSetting: + { + s = new BooleanSetting(attSettingName?.Value, attSettingTitle?.Value); + if (attDefaultValue != null) + s.DefaultValue = bool.Parse(attDefaultValue.Value); + break; + } + case SettingsXMLSchema.CustomSetting: + { + MarkupAttribute attSettingTypeName = tag.Attributes["TypeName"]; + s = new CustomSetting(attSettingName?.Value, attSettingTitle?.Value, attSettingTypeName?.Value); + break; + } + case SettingsXMLSchema.TextSetting: + { + s = new TextSetting(attSettingName?.Value, attSettingTitle?.Value); + if (attDefaultValue != null) + s.DefaultValue = attDefaultValue.Value; + break; + } + case SettingsXMLSchema.FileSetting: + { + s = new FileSetting(attSettingName?.Value, attSettingTitle?.Value); + + MarkupAttribute attType = tag.Attributes["Type"]; + if (attType != null) + { + if (attType.Value.ToLower() == "folder") + { + ((FileSetting)s).Mode = FileSettingMode.SelectFolder; + } + else + { + } + } + + ((FileSetting)s).FileNameFilter = tag.Attributes["FileNameFilter"]?.Value; + if (attDefaultValue != null) + s.DefaultValue = attDefaultValue.Value; + break; + } + case SettingsXMLSchema.CommandSetting: + { + MarkupAttribute attCommandID = tag.Attributes["CommandID"]; + MarkupAttribute attStylePreset = tag.Attributes["StylePreset"]; + s = new CommandSetting(attSettingName?.Value, attSettingTitle?.Value, attCommandID?.Value); + if (attStylePreset != null) + { + ((CommandSetting)s).StylePreset = (CommandStylePreset)Enum.Parse(typeof(CommandStylePreset), attStylePreset.Value); + } + break; + } + case SettingsXMLSchema.RangeSetting: + { + s = new RangeSetting(attSettingName?.Value, attSettingTitle?.Value); + MarkupAttribute attMinimumValue = tag.Attributes["MinimumValue"]; + if (attMinimumValue != null) + ((RangeSetting)s).MinimumValue = decimal.Parse(attMinimumValue.Value); + + MarkupAttribute attMaximumValue = tag.Attributes["MaximumValue"]; + if (attMaximumValue != null) + ((RangeSetting)s).MaximumValue = decimal.Parse(attMaximumValue.Value); + + if (attDefaultValue != null) + ((RangeSetting)s).DefaultValue = decimal.Parse(attDefaultValue.Value); + break; + } + case SettingsXMLSchema.ChoiceSetting: + { + s = new ChoiceSetting(attSettingName?.Value, attSettingTitle?.Value); + MarkupTagElement tagChoices = tag.Elements["Choices"] as MarkupTagElement; + if (tagChoices != null) + { + foreach (MarkupTagElement tagChoice in tagChoices.Elements.OfType()) + { + ChoiceSetting.ChoiceSettingValue value = ParseChoiceValue(tagChoice); + ((ChoiceSetting)s).ValidValues.Add(value); + } + } + if (attDefaultValue != null) + ((ChoiceSetting)s).DefaultValue = decimal.Parse(attDefaultValue.Value); + break; + } + case SettingsXMLSchema.GroupSetting: + { + s = new GroupSetting(attSettingName?.Value, attSettingTitle?.Value); + MarkupTagElement tagSettings = tag.Elements["Settings"] as MarkupTagElement; + if (tagSettings != null) + { + foreach (MarkupElement el in tagSettings.Elements) + { + Setting s2 = ParseSetting(el as MarkupTagElement); + if (s2 != null) + { + (s as GroupSetting).Options.Add(s2); + } + } + } + MarkupTagElement tagHeaderSettings = tag.Elements["HeaderSettings"] as MarkupTagElement; + if (tagHeaderSettings != null) + { + foreach (MarkupElement el in tagHeaderSettings.Elements) + { + Setting s2 = ParseSetting(el as MarkupTagElement); + if (s2 != null) + { + (s as GroupSetting).HeaderSettings.Add(s2); + } + } + } + break; + } + } + + if (s != null) + { + s.ID = new Guid(attSettingID.Value); + if (attSettingDescription != null) + s.Description = attSettingDescription.Value; + } + return s; + } + + private static ChoiceSetting.ChoiceSettingValue ParseChoiceValue(MarkupTagElement tag) + { + Contract.Assert(tag != null, String.Format("{0} must not be null", nameof(tag))); + Contract.Assert(tag.FullName == "Choice", String.Format("{0} must be a 'Choice' tag", nameof(tag))); + + MarkupAttribute attID = tag.Attributes["ID"]; + Contract.Assert(attID?.Value != null, String.Format("{0} must be non-null and have a Value", nameof(attID))); + + Guid id = new Guid(attID.Value); + MarkupAttribute attName = tag.Attributes["Name"]; + MarkupAttribute attTitle = tag.Attributes["Title"]; + MarkupAttribute attValue = tag.Attributes["Value"]; + return new ChoiceSetting.ChoiceSettingValue(attName?.Value, attTitle?.Value, attValue?.Value) { ID = id }; + } + + /// + /// Loads a settings provider from the given XML tag definition into a caller-initialized + /// . The caller of this method MUST initialize the value passed + /// into the parameter. + /// + /// The containing the settings provider definition. + /// The to initialize. + public static void ParseSettingsProvider(MarkupTagElement tag, ref SettingsProvider sp) + { + if (sp == null) + throw new ArgumentNullException(nameof(sp)); + + if (tag == null) + { + sp = null; + return; + } + if (tag.FullName != "SettingsProvider" && tag.FullName != "Settings") + { + sp = null; + return; + } + + if (tag.FullName == "SettingsProvider") + { + // expect an ID for settings provider; no ID for just "settings" + MarkupAttribute attID = tag.Attributes["ID"]; + if (attID == null) + { + sp = null; + return; + } + + sp.ID = new Guid(attID.Value); + } + + foreach (MarkupElement el in tag.Elements) + { + MarkupTagElement tag2 = (el as MarkupTagElement); + if (tag2 == null) continue; + if (tag2.FullName == "SettingsGroup") + { + Guid id2 = new Guid(tag2.Attributes["ID"].Value); + + if (sp.SettingsGroups.Contains(id2)) + { + continue; + } + + SettingsGroup sg = new SettingsGroup(); + sg.ID = id2; + sg.Path = SettingsParser.ParsePath(tag2.Elements["Path"] as MarkupTagElement); + + MarkupTagElement tagSettings = (tag2.Elements["Settings"] as MarkupTagElement); + if (tagSettings != null) + { + foreach (MarkupElement el2 in tagSettings.Elements) + { + Setting s = SettingsParser.ParseSetting(el2 as MarkupTagElement); + if (s != null) + { + if (sg.Settings.Contains(s.ID)) + continue; + + sg.Settings.Add(s); + } + } + } + sp.SettingsGroups.Add(sg); + } + } + } + } +} diff --git a/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsXMLSchema.cs b/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsXMLSchema.cs new file mode 100644 index 00000000..f1aefdb7 --- /dev/null +++ b/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/SettingsXMLSchema.cs @@ -0,0 +1,35 @@ +// +// SettingsXMLSchema.cs +// +// Author: +// Michael Becker +// +// Copyright (c) 2022 Mike Becker's Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace UniversalEditor.DataFormats.UEPackage +{ + public static class SettingsXMLSchema + { + public const string BooleanSetting = "BooleanSetting"; + public const string CustomSetting = "CustomSetting"; + public const string TextSetting = "TextSetting"; + public const string ChoiceSetting = "ChoiceSetting"; + public const string RangeSetting = "RangeSetting"; + public const string GroupSetting = "GroupSetting"; + public const string FileSetting = "FileSetting"; + public const string CommandSetting = "CommandSetting"; + } +} diff --git a/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/UEPackageXMLDataFormat.cs b/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/UEPackageXMLDataFormat.cs index b68631f6..fb68b304 100644 --- a/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/UEPackageXMLDataFormat.cs +++ b/Libraries/UniversalEditor.Essential/DataFormats/UEPackage/UEPackageXMLDataFormat.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using MBS.Framework; using MBS.Framework.Logic; using MBS.Framework.Settings; @@ -365,6 +366,22 @@ namespace UniversalEditor.DataFormats.UEPackage } } } + #region Settings + { + MarkupTagElement tagSettings = tagProjectType.Elements["Settings"] as MarkupTagElement; + if (tagSettings != null) + { + SettingsProvider csp = new CustomSettingsProvider(); + SettingsParser.ParseSettingsProvider(tagSettings, ref csp); + + if (csp != null) + { + projtype.SettingsProvider = csp; + } + + } + } + #endregion #region ItemShortcuts { MarkupTagElement tagItemShortcuts = (tagProjectType.Elements["ItemShortcuts"] as MarkupTagElement); @@ -500,7 +517,6 @@ namespace UniversalEditor.DataFormats.UEPackage } } #endregion - package.ProjectTypes.Add(projtype); } } diff --git a/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj b/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj index f572d74e..55017cbe 100644 --- a/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj +++ b/Libraries/UniversalEditor.Essential/UniversalEditor.Essential.csproj @@ -221,6 +221,8 @@ + +