// -------------------------------------------------------
// PowerPointCreator by Elm�Soft
// www.netcult.ch/elmue
// -------------------------------------------------------
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Collections;
using System.Windows.Forms;
// x_XmlNode.RemoveAll(); also deletes attributes !!
// x_XmlNode.InnerXml = ""; does NOT delete attributes
namespace PowerPointCreator
{
public class XML
{
const string ROOT_NAME = "Root";
string ms_File;
XmlNode mx_Root;
bool mb_WriteBlocked = false;
public XmlNode Root
{
get { return mx_Root; }
}
/// <summary>
/// Creates an empty XML document
/// </summary>
public XML()
{
XmlDocument i_Doc = new XmlDocument();
i_Doc.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-16\"?><" +ROOT_NAME+ " />");
mx_Root = i_Doc.SelectSingleNode(ROOT_NAME);
}
/// <summary>
/// Loads an existing XML document from a file
/// </summary>
public XML(string s_File)
{
ms_File = s_File;
XmlDocument i_Doc = new XmlDocument();
try
{
string s_Xml = Functions.ReadFileIntoString(s_File, Encoding.Default);
i_Doc.LoadXml(HtmlParser.HtmlToXml(s_Xml));
mx_Root = i_Doc.SelectSingleNode(ROOT_NAME);
}
catch (Exception Ex)
{
throw new Exception("Error reading XML file:\n" + s_File + "\n" + Ex.Message);
}
if (mx_Root == null)
throw new Exception("The Xml file is invalid (no Root node):\n" + s_File);
}
/// <summary>
/// Save any changes back to disk
/// </summary>
public bool Save()
{
return Save(ms_File);
}
public bool Save(string s_File)
{
ms_File = s_File;
try
{
Functions.RemoveWriteProtection(s_File);
Root.OwnerDocument.Save(s_File);
}
catch (Exception Ex)
{
throw new Exception("Error saving XML file\n" + s_File + "\n" + Ex.Message);
}
return true;
}
// +++++++++++++++++++++++++++++++ Controls +++++++++++++++++++++++++++++++++++++
/// <summary>
/// Hashtable: Key = Ctrl, value ignored
/// s_Path = "Root/WindowPositions"
/// </summary>
public bool WriteCtrls(string s_Path, Hashtable i_Controls)
{
if (mb_WriteBlocked)
return true;
XmlNode i_Node = CreateSubNode(Root, s_Path);
if (i_Node == null)
return false;
foreach (Control i_Ctrl in i_Controls.Keys)
{
string s_Name = i_Ctrl.Name;
if (s_Name.StartsWith("txt")) s_Name = s_Name.Substring(3);
if (s_Name.StartsWith("check")) s_Name = s_Name.Substring(5);
if (s_Name.StartsWith("combo")) s_Name = s_Name.Substring(5);
if (i_Ctrl is CheckBox)
{
WriteSubNode(i_Node, s_Name, ((CheckBox)i_Ctrl).Checked);
}
else if (i_Ctrl is TextBox)
{
WriteSubNode(i_Node, s_Name, ((TextBox)i_Ctrl).Text);
}
else if (i_Ctrl is ComboBox)
{
WriteSubNode(i_Node, s_Name, ((ComboBox)i_Ctrl).Text);
}
else if (i_Ctrl is Form)
{
Form i_Form = (Form)i_Ctrl;
if (i_Form.WindowState == FormWindowState.Normal)
{
WriteSubNode(i_Node, i_Form.Name + "_Top", i_Form.Top);
WriteSubNode(i_Node, i_Form.Name + "_Left", i_Form.Left);
WriteSubNode(i_Node, i_Form.Name + "_Width", i_Form.Width);
WriteSubNode(i_Node, i_Form.Name + "_Height", i_Form.Height);
}
}
else if (i_Ctrl is Splitter)
{
WriteSubNode(i_Node, s_Name, ((Splitter)i_Ctrl).SplitPosition);
}
}
return true;
}
/// <summary>
/// Hashtable: Key = Ctrl, value = default value
/// s_Path = "Root/WindowPositions"
/// </summary>
public bool ReadCtrls(string s_Path, Hashtable i_Controls)
{
XmlNode i_Node = FindSubNode(Root, s_Path);
if (i_Node == null)
return false;
// avoid that events that are fired by the GUI (e.g. ComboBox Selection changed)
// write settings to the XML file before reading has finished
mb_WriteBlocked = true;
foreach (Control i_Ctrl in i_Controls.Keys)
{
string s_Name = i_Ctrl.Name;
if (s_Name.StartsWith("txt")) s_Name = s_Name.Substring(3);
if (s_Name.StartsWith("check")) s_Name = s_Name.Substring(5);
if (s_Name.StartsWith("combo")) s_Name = s_Name.Substring(5);
string s_Value = ReadSubNode(i_Node, s_Name, Functions.ToStr(i_Controls[i_Ctrl]));
if (i_Ctrl is CheckBox)
{
((CheckBox)i_Ctrl).Checked = (s_Value.ToUpper() == "TRUE");
}
else if (i_Ctrl is TextBox)
{
((TextBox)i_Ctrl).Text = s_Value;
}
else if (i_Ctrl is ComboBox)
{
ComboBox i_Combo = (ComboBox)i_Ctrl;
i_Combo.SelectedIndex = i_Combo.FindStringExact(s_Value);
}
else if (i_Ctrl is Form)
{
Form i_Form = (Form)i_Ctrl;
if (i_Form.WindowState == FormWindowState.Normal)
{
i_Form.Top = ReadSubNode(i_Node, i_Form.Name + "_Top", (Screen.PrimaryScreen.Bounds.Height - i_Form.Height)/2);
i_Form.Left = ReadSubNode(i_Node, i_Form.Name + "_Left", (Screen.PrimaryScreen.Bounds.Width - i_Form.Width) /2);
i_Form.Width = ReadSubNode(i_Node, i_Form.Name + "_Width", i_Form.Width);
i_Form.Height = ReadSubNode(i_Node, i_Form.Name + "_Height", i_Form.Height);
}
}
else if (i_Ctrl is Splitter)
{
((Splitter)i_Ctrl).SplitPosition = Functions.ToInt(s_Value);
}
}
mb_WriteBlocked = false;
return true;
}
// ++++++++++++++++++++++++++++++++++ Root ++++++++++++++++++++++++++++++++++++++
// s_Path = "Subnode" or "SubNode/SubSubNode"
public string Read(string s_Path, string s_Default)
{
return ReadSubNode(Root, s_Path, s_Default);
}
// s_Path = "Subnode" or "SubNode/SubSubNode"
public int Read(string s_Path, int s32_Default)
{
string s_Val = Read(s_Path, s32_Default.ToString());
try { return int.Parse(s_Val); }
catch { return s32_Default; }
}
// s_Path = "Subnode" or "SubNode/SubSubNode"
public bool Read(string s_Path, bool b_Default)
{
string s_Val = Read(s_Path, b_Default.ToString());
return s_Val.ToUpper() == "TRUE";
}
// s_Path = "Subnode" or "SubNode/SubSubNode"
public void Write(string s_Path, object o_Value)
{
if (!mb_WriteBlocked)
WriteSubNode(Root, s_Path, o_Value.ToString());
}
// ++++++++++++++++++++++++++++++ static Find / Create ++++++++++++++++++++++++++++++++++++
// s_Path = "Subnode" or "SubNode/SubSubNode"
public static XmlNode FindSubNode(XmlNode i_Node, string s_Path)
{
if (i_Node == null || s_Path.Length == 0)
return i_Node;
s_Path = s_Path.Replace(" ", "_");
return i_Node.SelectSingleNode(s_Path);
}
/// <summary>
/// s_Path = "Subnode" or "SubNode/SubSubNode"
/// returns the existing node if it already exists
/// </summary>
public static XmlNode CreateSubNode(XmlNode i_Node, string s_Path)
{
if (i_Node == null || s_Path.Length == 0)
return i_Node;
XmlDocument i_Doc = i_Node.OwnerDocument;
s_Path = s_Path.Replace(" ", "_");
string[] s_Parts = s_Path.Split('/');
foreach (string s_Part in s_Parts)
{
if (s_Part == "")
continue;
XmlNode i_Child = i_Node.SelectSingleNode(s_Part);
if (i_Child != null)
{
i_Node = i_Child;
continue;
}
i_Node = i_Node.AppendChild(i_Doc.CreateElement(s_Part));
}
return i_Node;
}
/// <summary>
/// Always create a new immediate childode even a node with identical name already exists
/// </summary>
public static XmlNode AppendChildNode(XmlNode i_Node, string s_Tag)
{
XmlDocument i_Doc = i_Node.OwnerDocument;
return i_Node.AppendChild(i_Doc.CreateElement(s_Tag));
}
// ++++++++++++++++++++++++++++++ static Read / Write ++++++++++++++++++++++++++++++++++++
// s_Path = "Subnode" or "SubNode/SubSubNode"
public static string ReadSubNode(XmlNode i_Node, string s_Path, string s_Default)
{
XmlNode i_SubNode = FindSubNode(i_Node, s_Path);
if (i_SubNode == null)
return s_Default;
return Functions.ToStr(i_SubNode.InnerText);
}
public static int ReadSubNode(XmlNode i_Node, string s_Path, int s32_Default)
{
XmlNode i_SubNode = FindSubNode(i_Node, s_Path);
if (i_SubNode == null)
return s32_Default;
try { return int.Parse(i_SubNode.InnerText); }
catch { return s32_Default; }
}
public static bool ReadSubNode(XmlNode i_Node, string s_Path, bool b_Default)
{
XmlNode i_SubNode = FindSubNode(i_Node, s_Path);
if (i_SubNode == null)
return b_Default;
return (i_SubNode.InnerText.ToUpper() == "TRUE");
}
// s_Path = "Subnode" or "SubNode/SubSubNode"
public static void WriteSubNode(XmlNode i_Node, string s_Path, object o_Value)
{
XmlNode i_SubNode = CreateSubNode(i_Node, s_Path);
if (i_SubNode != null)
i_SubNode.InnerText = Functions.ToStr(o_Value);
}
// +++++++++++++++++++++++++++++++ static Attribute +++++++++++++++++++++++++++++++++++++++++
/// <summary>
/// creates a new subnode <s_Tag Name="s_Name" ...> of i_Node
/// if it does not exist, otherwise returns the existing node
/// s_Name is not allowed to be ""
/// </summary>
public static XmlNode CreateSubNodeAttr(XmlNode i_Node, string s_Tag, string s_Name)
{
if (i_Node == null || s_Tag.Length == 0 || s_Name.Length == 0)
return null;
XmlNode i_Sub = FindSubNodeAttr(i_Node, s_Tag, s_Name);
if (i_Sub != null)
return i_Sub;
XmlDocument i_Doc = i_Node.OwnerDocument;
XmlElement i_Elem = i_Doc.CreateElement(s_Tag);
if (s_Name.Length > 0) i_Elem.SetAttribute("Name", s_Name);
// return a new <Category Name="xyz"></Category>
return i_Node.AppendChild(i_Elem);
}
/// <summary>
/// searches the subnode <s_Tag Name="s_Name" ...> of i_Node
/// and returns the node if it exists or null otherwise
/// s_Name is not allowed to be ""
/// </summary>
public static XmlNode FindSubNodeAttr(XmlNode i_Node, string s_Tag, string s_Name)
{
if (i_Node == null || s_Tag.Length == 0 || s_Name.Length == 0)
return null;
foreach (XmlNode i_Sub in i_Node)
{
if (string.Compare(i_Sub.Name, s_Tag, true) != 0)
continue;
if (CompareAttributeStr(i_Sub, "Name", s_Name))
return i_Sub;
}
return null;
}
/// <summary>
/// (string) returns an Attribute of a node or "" if the Attribute does not exist
/// </summary>
public static string GetAttributeStr(XmlNode i_Node, string s_AttrName)
{
if (i_Node == null)
return "";
XmlAttribute i_Attr = i_Node.Attributes[s_AttrName];
if (i_Attr == null)
return "";
return i_Attr.Value;
}
/// <summary>
/// (int) returns an Attribute of a node or 0 if the Attribute does not exist
/// </summary>
public static int GetAttributeInt(XmlNode i_Node, string s_AttrName)
{
return Functions.ToInt(GetAttributeStr(i_Node, s_AttrName));
}
/// <summary>
/// Checks if the Attribute's value is equal to s_Value (case insensitive)
/// </summary>
public static bool CompareAttributeStr(XmlNode i_Node, string s_AttrName, string s_Value)
{
if (i_Node == null)
return false;
string s_XmlAttr = GetAttributeStr(i_Node, s_AttrName);
if (s_XmlAttr.Length == 0) // Attribute not found
return false;
return string.Compare(s_XmlAttr, s_Value, true) == 0;
}
}
}