292 lines
9.2 KiB
C#
292 lines
9.2 KiB
C#
//
|
|
// SettingsParser.cs
|
|
//
|
|
// Author:
|
|
// Michael Becker <alcexhim@gmail.com>
|
|
//
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
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
|
|
{
|
|
/// <summary>
|
|
/// Provides utility functions for parsing <see cref="Setting" /> objects from
|
|
/// XML definitions.
|
|
/// </summary>
|
|
public class SettingsParser
|
|
{
|
|
/// <summary>
|
|
/// Converts an XML settings path definition to a <see cref="String" />
|
|
/// array.
|
|
/// </summary>
|
|
/// <returns>The <see cref="String" /> array containing the path information.</returns>
|
|
/// <param name="tag">The <see cref="MarkupTagElement" /> containing the XML to parse.</param>
|
|
public static string[] ParsePath(MarkupTagElement tag)
|
|
{
|
|
if (tag == null) return null;
|
|
if (tag.FullName != "Path") return null;
|
|
|
|
List<string> path = new List<string>();
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an XML settings definition into a <see cref="Setting" />
|
|
/// object of the appropriate type.
|
|
/// </summary>
|
|
/// <returns>The parsed setting.</returns>
|
|
/// <param name="tag">The <see cref="MarkupTagElement" /> containing the XML to parse.</param>
|
|
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<MarkupTagElement>())
|
|
{
|
|
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 };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads a settings provider from the given XML tag definition into a caller-initialized
|
|
/// <see cref="SettingsProvider" />. The caller of this method MUST initialize the value passed
|
|
/// into the <paramref name="sp" /> parameter.
|
|
/// </summary>
|
|
/// <param name="tag">The <see cref="MarkupTagElement" /> containing the settings provider definition.</param>
|
|
/// <param name="sp">The <see cref="SettingsProvider" /> to initialize.</param>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|