mirror of https://github.com/PCSX2/pcsx2.git
217 lines
8.1 KiB
C#
217 lines
8.1 KiB
C#
|
/*
|
|||
|
* Copyright (C) 2009-2019 PCSX2 Dev Team
|
|||
|
*
|
|||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
* of this software and associated documentation files (the "Software"), to deal
|
|||
|
* in the Software without restriction, including without limitation the rights
|
|||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
|
* copies of the Software, and to permit persons to whom the Software is
|
|||
|
* furnished to do so, subject to the following conditions:
|
|||
|
*
|
|||
|
* The above copyright notice and this permission notice shall be included in
|
|||
|
* all copies or substantial portions of the Software.
|
|||
|
*
|
|||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
|
* THE SOFTWARE.
|
|||
|
*/
|
|||
|
|
|||
|
using System;
|
|||
|
using System.Collections.Specialized;
|
|||
|
using System.Configuration;
|
|||
|
using System.IO;
|
|||
|
using System.Xml;
|
|||
|
using System.Xml.Linq;
|
|||
|
|
|||
|
namespace GSDumpGUI.Forms.SettingsProvider
|
|||
|
{
|
|||
|
public sealed class PortableXmlSettingsProvider : System.Configuration.SettingsProvider, IApplicationSettingsProvider
|
|||
|
{
|
|||
|
private const string RootNode = "configuration";
|
|||
|
private static string SettingsDirectory => AppDomain.CurrentDomain.BaseDirectory;
|
|||
|
public override string Name => nameof(PortableXmlSettingsProvider);
|
|||
|
private static string ApplicationSettingsFile => Path.Combine(SettingsDirectory, "portable.config");
|
|||
|
|
|||
|
public static void ApplyProvider(params ApplicationSettingsBase[] settingsList)
|
|||
|
=> ApplyProvider(new PortableXmlSettingsProvider(), settingsList);
|
|||
|
|
|||
|
public override string ApplicationName
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return nameof(GSDumpGUI);
|
|||
|
}
|
|||
|
set { }
|
|||
|
}
|
|||
|
|
|||
|
private static XDocument GetOrCreateXmlDocument()
|
|||
|
{
|
|||
|
if (!File.Exists(ApplicationSettingsFile))
|
|||
|
return CreateNewDocument();
|
|||
|
try
|
|||
|
{
|
|||
|
return XDocument.Load(ApplicationSettingsFile);
|
|||
|
}
|
|||
|
catch
|
|||
|
{
|
|||
|
return CreateNewDocument();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void ApplyProvider(PortableXmlSettingsProvider provider, params ApplicationSettingsBase[] settingsList)
|
|||
|
{
|
|||
|
foreach (ApplicationSettingsBase settings in settingsList)
|
|||
|
{
|
|||
|
settings.Providers.Clear();
|
|||
|
settings.Providers.Add(provider);
|
|||
|
foreach (SettingsProperty property in settings.Properties)
|
|||
|
property.Provider = provider;
|
|||
|
settings.Reload();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public override void Initialize(string name, NameValueCollection config)
|
|||
|
{
|
|||
|
if (String.IsNullOrEmpty(name))
|
|||
|
name = Name;
|
|||
|
base.Initialize(name, config);
|
|||
|
}
|
|||
|
|
|||
|
public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property)
|
|||
|
{
|
|||
|
throw new NotImplementedException();
|
|||
|
}
|
|||
|
|
|||
|
public void Reset(SettingsContext context)
|
|||
|
{
|
|||
|
if (!File.Exists(ApplicationSettingsFile))
|
|||
|
return;
|
|||
|
File.Delete(ApplicationSettingsFile);
|
|||
|
}
|
|||
|
|
|||
|
public void Upgrade(SettingsContext context, SettingsPropertyCollection properties) { }
|
|||
|
|
|||
|
private static XDocument CreateNewDocument()
|
|||
|
{
|
|||
|
return new XDocument(new XElement(RootNode));
|
|||
|
}
|
|||
|
|
|||
|
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
|
|||
|
{
|
|||
|
var xmlDoc = GetOrCreateXmlDocument();
|
|||
|
var propertyValueCollection = new SettingsPropertyValueCollection();
|
|||
|
foreach (SettingsProperty settingsProperty in collection)
|
|||
|
{
|
|||
|
propertyValueCollection.Add(new SettingsPropertyValue(settingsProperty)
|
|||
|
{
|
|||
|
IsDirty = false,
|
|||
|
SerializedValue = GetValue(xmlDoc, settingsProperty)
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
return propertyValueCollection;
|
|||
|
}
|
|||
|
|
|||
|
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
|
|||
|
{
|
|||
|
var xmlDoc = GetOrCreateXmlDocument();
|
|||
|
foreach (SettingsPropertyValue settingsPropertyValue in collection)
|
|||
|
SetValue(xmlDoc, settingsPropertyValue);
|
|||
|
try
|
|||
|
{
|
|||
|
using (var writer = CreateWellFormattedXmlWriter(ApplicationSettingsFile))
|
|||
|
{
|
|||
|
xmlDoc.Save(writer);
|
|||
|
}
|
|||
|
}
|
|||
|
catch { }
|
|||
|
}
|
|||
|
|
|||
|
private static XmlWriter CreateWellFormattedXmlWriter(string outputFileName)
|
|||
|
{
|
|||
|
var settings = new XmlWriterSettings
|
|||
|
{
|
|||
|
NewLineHandling = NewLineHandling.Entitize,
|
|||
|
Indent = true
|
|||
|
};
|
|||
|
return XmlWriter.Create(outputFileName, settings);
|
|||
|
}
|
|||
|
|
|||
|
private static object GetValue(XContainer xmlDoc, SettingsProperty prop)
|
|||
|
{
|
|||
|
if (xmlDoc == null)
|
|||
|
return prop.DefaultValue;
|
|||
|
|
|||
|
var rootNode = xmlDoc.Element(RootNode);
|
|||
|
if (rootNode == null)
|
|||
|
return prop.DefaultValue;
|
|||
|
|
|||
|
var settingNode = rootNode.Element(prop.Name);
|
|||
|
if (settingNode == null)
|
|||
|
return prop.DefaultValue;
|
|||
|
|
|||
|
return DeserializeSettingValueFromXmlNode(settingNode, prop);
|
|||
|
}
|
|||
|
|
|||
|
private static void SetValue(XContainer xmlDoc, SettingsPropertyValue value)
|
|||
|
{
|
|||
|
if (xmlDoc == null)
|
|||
|
throw new ArgumentNullException(nameof(xmlDoc));
|
|||
|
|
|||
|
var rootNode = xmlDoc.Element(RootNode);
|
|||
|
if (rootNode == null)
|
|||
|
throw new ArgumentNullException(nameof(rootNode));
|
|||
|
|
|||
|
var settingNode = rootNode.Element(value.Name);
|
|||
|
|
|||
|
var settingValueNode = SerializeSettingValueToXmlNode(value);
|
|||
|
if (settingNode == null)
|
|||
|
rootNode.Add(new XElement(value.Name, settingValueNode));
|
|||
|
else
|
|||
|
settingNode.ReplaceAll(settingValueNode);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private static XNode SerializeSettingValueToXmlNode(SettingsPropertyValue value)
|
|||
|
{
|
|||
|
if (value.SerializedValue == null)
|
|||
|
return new XText("");
|
|||
|
switch (value.Property.SerializeAs)
|
|||
|
{
|
|||
|
case SettingsSerializeAs.String:
|
|||
|
return new XText((string) value.SerializedValue);
|
|||
|
case SettingsSerializeAs.Xml:
|
|||
|
case SettingsSerializeAs.Binary:
|
|||
|
case SettingsSerializeAs.ProviderSpecific:
|
|||
|
throw new NotImplementedException($"I don't know how to handle serialization of settings that should be serialized as {value.Property.SerializeAs}");
|
|||
|
default:
|
|||
|
throw new ArgumentOutOfRangeException();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static object DeserializeSettingValueFromXmlNode(XNode node, SettingsProperty prop)
|
|||
|
{
|
|||
|
using (var reader = node.CreateReader())
|
|||
|
{
|
|||
|
reader.MoveToContent();
|
|||
|
switch (prop.SerializeAs)
|
|||
|
{
|
|||
|
case SettingsSerializeAs.Xml:
|
|||
|
case SettingsSerializeAs.Binary:
|
|||
|
case SettingsSerializeAs.ProviderSpecific:
|
|||
|
throw new NotImplementedException($"I don't know how to handle deserialization of settings that should be deserialized as {prop.SerializeAs}");
|
|||
|
|
|||
|
case SettingsSerializeAs.String:
|
|||
|
return reader.ReadElementContentAsString();
|
|||
|
default:
|
|||
|
throw new ArgumentOutOfRangeException();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|