using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Xml; namespace Mag.Shared.Settings { static class SettingsFile { internal static readonly XmlDocument XmlDocument = new XmlDocument(); static string _documentPath; static string _rootNodeName = "Settings"; static SettingsFile() { ReloadXmlDocument(); } public static void Init(string filePath, string rootNode = "Settings") { _documentPath = filePath; _rootNodeName = rootNode; ReloadXmlDocument(); } public static void ReloadXmlDocument() { try { if (!String.IsNullOrEmpty(_documentPath) && File.Exists(_documentPath)) XmlDocument.Load(_documentPath); else XmlDocument.LoadXml("<" + _rootNodeName + ">"); } catch (Exception ex) { Debug.LogException(ex); XmlDocument.LoadXml("<" + _rootNodeName + ">"); } } public static void SaveXmlDocument() { XmlDocument.Save(_documentPath); } public static T GetSetting(string xPath, T defaultValue = default(T)) { XmlNode xmlNode = XmlDocument.SelectSingleNode(_rootNodeName + "/" + xPath); if (xmlNode != null) { TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); if (converter.CanConvertFrom(typeof(string))) return (T)converter.ConvertFromString(xmlNode.InnerText); } return defaultValue; } public static void PutSetting(string xPath, T value) { // Before we save a setting, we reload the document to make sure we don't overwrite settings saved from another session. ReloadXmlDocument(); XmlNode xmlNode = XmlDocument.SelectSingleNode(_rootNodeName + "/" + xPath); if (xmlNode == null) xmlNode = createMissingNode(_rootNodeName + "/" + xPath); TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); if (converter.CanConvertTo(typeof(string))) { string result = converter.ConvertToString(value); if (result != null) { xmlNode.InnerText = result; XmlDocument.Save(_documentPath); } } } static XmlNode createMissingNode(string xPath) { string[] xPathSections = xPath.Split('/'); string currentXPath = ""; XmlNode currentNode = XmlDocument.SelectSingleNode(_rootNodeName); foreach (string xPathSection in xPathSections) { currentXPath += xPathSection; XmlNode testNode = XmlDocument.SelectSingleNode(currentXPath); if (testNode == null) { if (currentNode != null) currentNode.InnerXml += "<" + xPathSection + ">"; } currentNode = XmlDocument.SelectSingleNode(currentXPath); currentXPath += "/"; } return currentNode; } public static IList GetChilderenInnerTexts(string xPath) { XmlNode xmlNode = XmlDocument.SelectSingleNode(_rootNodeName + "/" + xPath); Collection collection = new Collection(); if (xmlNode != null) { foreach (XmlNode childNode in xmlNode.ChildNodes) collection.Add(childNode.InnerText); } return collection; } public static void SetNodeChilderen(string xPath, string childNodeName, IList innerTexts) { // Before we save a setting, we reload the document to make sure we don't overwrite settings saved from another session. ReloadXmlDocument(); XmlNode parentNode = XmlDocument.SelectSingleNode(_rootNodeName + "/" + xPath); if (parentNode == null) { if (innerTexts.Count == 0) return; parentNode = createMissingNode(_rootNodeName + "/" + xPath); } parentNode.RemoveAll(); if (innerTexts.Count == 0) { XmlDocument.Save(_documentPath); return; } foreach (string innerText in innerTexts) { XmlNode childNode = parentNode.AppendChild(XmlDocument.CreateElement(childNodeName)); childNode.InnerText = innerText; } XmlDocument.Save(_documentPath); } public static XmlNode GetNode(string xPath, bool createIfNull = false) { var node = XmlDocument.SelectSingleNode(_rootNodeName + "/" + xPath); if (node == null && createIfNull) node = createMissingNode(_rootNodeName + "/" + xPath); return node; } public static void SetNodeChilderen(string xPath, string childNodeName, Collection> childNodeAttributes) { // Before we save a setting, we reload the document to make sure we don't overwrite settings saved from another session. ReloadXmlDocument(); XmlNode parentNode = XmlDocument.SelectSingleNode(_rootNodeName + "/" + xPath); if (parentNode == null) parentNode = createMissingNode(_rootNodeName + "/" + xPath); if (parentNode.HasChildNodes) parentNode.RemoveAll(); foreach (Dictionary dictionary in childNodeAttributes) { XmlNode childNode = parentNode.AppendChild(XmlDocument.CreateElement(childNodeName)); foreach (KeyValuePair pair in dictionary) { XmlAttribute attribute = XmlDocument.CreateAttribute(pair.Key); attribute.Value = pair.Value; if (childNode.Attributes != null) childNode.Attributes.Append(attribute); } } XmlDocument.Save(_documentPath); } } }