using System;
using System.Xml;
using System.Windows.Forms;
using System.Drawing;
namespace OGCLib
{
///////////////////////////////////////////////////////////////////////////////////
// Class Configurator -
// responsible for reading from/writing to control's XML config. file
///////////////////////////////////////////////////////////////////////////////////
public class Configurator
{
// CONST
// Minimal height of control caption. If actual caption height is less then this value
// then caption is not drawn and control is not dockable.
private const int captionHeightMin = 12;
// Name of XML file containing error messages templates
private const string errMsgFileName = "OGCErrorMessages.xml";
// VARIABLES
protected OGControl ogControl = null;
private XmlDocument xmlDoc = null;
private string resourceDir;
private IElement currentElement = null;
private bool operationLoad = true;
// CONSTRUCTOR
public Configurator(OGControl ogControl, string xmlConfFileName,
bool operationLoad)
{
if (null != ogControl)
{
this.ogControl = ogControl;
this.operationLoad = operationLoad;
// Using XML DOM...
xmlDoc = new XmlDocument();
// Load error message templates
if (operationLoad)
LoadErrorMessages();
// Load other parameters
LoadSaveParameters(xmlConfFileName);
}
}
// METHODS
// Load error message templates from "errMsgFileName" file
private void LoadErrorMessages()
{
try
{
xmlDoc.Load(errMsgFileName);
}
catch
{
string errorMessage = "Loading file '" + errMsgFileName + "' failed";
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Warning, errorMessage));
}
try
{
ProcessNode(xmlDoc.DocumentElement);
}
catch
{
ErrorType errorType = ErrorType.ErrorMessages;
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Warning,
ogControl.GetErrorMessage((int)errorType)));
}
}
// Load parameters from/Save to XML config. file
private void LoadSaveParameters(string xmlConfFileName)
{
try
{
xmlDoc.Load(xmlConfFileName);
}
catch
{
ErrorType errorType = ErrorType.LoadConfigFile;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), xmlConfFileName);
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
try
{
// Recursive nodes processing
ProcessNode(xmlDoc.DocumentElement);
}
catch
{
ErrorType errorType = ErrorType.ProcessNode;
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error,
ogControl.GetErrorMessage((int)errorType)));
}
try
{
if (!operationLoad)
xmlDoc.Save(xmlConfFileName);
}
catch
{
ErrorType errorType = ErrorType.LoadConfigFile;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), xmlConfFileName);
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
}
// Recursive method for XML nodes processing
private void ProcessNode(XmlNode node)
{
if (null != node)
{
Filter(node);
XmlNodeList nodeList = node.ChildNodes;
int length = node.ChildNodes.Count;
XmlNode childNode = null;
int index = 0;
do
{
childNode = nodeList.Item(index++);
ProcessNode(childNode);
} while (null != childNode);
}
}
// State machine for XML processing
protected virtual void Filter(XmlNode node)
{
if (null != node && null != ogControl)
{
if (!operationLoad)
{
// Save parameters
switch (node.Name)
{
case "OGControl":
try
{
Write(node, "DockStyle", ogControl.Dock);
}
catch
{
ErrorType errorType = ErrorType.WritingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "TagOGControl");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Warning, errorMessage));
}
break;
case "InitControlState":
try
{
Write(node, "Value", ogControl.CurrentState);
}
catch
{
ErrorType errorType = ErrorType.WritingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "InitControlState");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
break;
}
return;
}
// Load parameters
switch (node.Name)
{
case "ErrorMessages":
int i=0;
while (null != ogControl.GetErrorTag(i))
ogControl.AddErrorMessage(GetString(node, ogControl.GetErrorTag(i++)));
break;
case "OGControl":
try
{
ogControl.Name = ReadStr(node, "Name");
ogControl.InitDock = DockStyleFromString(node, "InitDockStyle");
ogControl.Dock = DockStyleFromString(node, "DockStyle");
ogControl.Size = GetSize(node);
resourceDir = ReadStr(node, "ResourcePath");
ogControl.ActiveCursorFileName = resourceDir + ReadStr(node, "ActiveCursor");
ogControl.Rotate = GetYesNo(node, "Rotate");
ogControl.BackColor = Color.FromName(ReadStr(node, "BackColor"));
}
catch
{
ErrorType errorType = ErrorType.ReadingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "TagOGControl");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
break;
case "CaptionStyle":
try
{
GetCaptionStyle(node);
ogControl.CaptionTextSize = ReadInt(node, "TextSize");
}
catch
{
ErrorType errorType = ErrorType.ReadingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "CaptionStyle");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Warning, errorMessage));
}
break;
case "Element":
try
{
string type = ReadStr(node, "Type");
currentElement = ogControl.AddElement(type, ReadStr(node, "Name"),
GetPosition(node, Orientation.Horizontal),
GetPosition(node, Orientation.Vertical),
GetElementSize(node));
}
catch
{
ErrorType errorType = ErrorType.ReadingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "Element");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
break;
case "State":
try
{
if (null != currentElement)
{
string fileName = "";
string fileExt = "";
if (currentElement.HasImage())
{
fileName = resourceDir + ReadStr(node, "FileName");
fileExt = ReadStr(node, "FileExt");
}
currentElement.AddState(ReadStr(node, "Name"), fileName, fileExt);
}
}
catch
{
ErrorType errorType = ErrorType.TagState;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType),
"State", currentElement.GetName());
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
break;
case "MaxControlStates":
try
{
ogControl.ControlStatesMax = ReadInt(node, "Value");
if (0 >= ogControl.ControlStatesMax)
throw(new Exception());
}
catch
{
ErrorType errorType = ErrorType.ReadingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "MaxControlStates");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
break;
case "InitControlState":
try
{
ogControl.CurrentState = ReadInt(node, "Value");
if (0 > ogControl.CurrentState ||
ogControl.ControlStatesMax <= ogControl.CurrentState)
throw(new Exception());
}
catch
{
ErrorType errorType = ErrorType.ReadingTag;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), "InitControlState");
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
break;
case "StateTransition":
if (null != currentElement)
for (int ctrlState=0; ctrlState<ogControl.ControlStatesMax; ctrlState++)
for (int elemState=0; elemState<currentElement.GetNextStatesNum(); elemState++)
{
string valName = (1 < currentElement.GetNextStatesNum())
? "m"+ctrlState.ToString()+"_"+elemState.ToString()
: "v"+ctrlState.ToString();
int newCtrlState = -1;
try
{
newCtrlState = ReadInt(node, valName);
}
catch
{
}
if (-1 <= newCtrlState &&
ogControl.ControlStatesMax > newCtrlState)
currentElement.SetControlStateTransitionElement(
ctrlState, elemState, newCtrlState);
else
{
ErrorType errorType = ErrorType.StateTransition;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType),
currentElement.GetName(), ctrlState, elemState, newCtrlState);
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
}
break;
case "ControlStatesMatrixElement":
SetMatrixElement(node, "ControlState");
break;
}
}
}
// Methods for simple objects Reading from/Writing to XML config. file file
private string ReadStr(XmlNode node, string name)
{
return (string)node.Attributes.GetNamedItem(name).Value;
}
private int ReadInt(XmlNode node, string name)
{
return Int32.Parse(ReadStr(node, name));
}
private void Write(XmlNode node, string name, object obj)
{
node.Attributes.GetNamedItem(name).Value = obj.ToString();
}
// Helper methods
private DockStyle DockStyleFromString(XmlNode node, string itemName)
{
switch (ReadStr(node, itemName))
{
case "Top": return DockStyle.Top;
case "Bottom": return DockStyle.Bottom;
case "Left": return DockStyle.Left;
case "Right": return DockStyle.Right;
case "Fill": return DockStyle.Fill;
}
return DockStyle.None;
}
private Size GetSize(XmlNode node)
{
Size size = new Size();
size.Width = ReadInt(node, "Width");
size.Height = ReadInt(node, "Height");
int captionHeight = ReadInt(node, "CaptionHeight");
captionHeight = (captionHeightMin <= captionHeight) ? captionHeight : 0;
size.Height += captionHeight;
ogControl.CaptionHeight = captionHeight;
return size;
}
private Point GetPosition(XmlNode node, Orientation orientation)
{
string strX = "";
string strY = "";
switch (orientation)
{
case Orientation.Horizontal:
strX = "HorizX";
strY = "HorizY";
break;
case Orientation.Vertical:
strX = "VertX";
strY = "VertY";
break;
}
return new Point(ReadInt(node, strX), ReadInt(node, strY));
}
private Size GetElementSize(XmlNode node)
{
Size size;
try
{
size = new Size(ReadInt(node, "Width"), ReadInt(node, "Height"));
}
catch
{
size = new Size(0, 0);
}
return size;
}
private void SetMatrixElement(XmlNode node, string toggle)
{
int i = 0, j = 0, val = -1;
try
{
i = ReadInt(node, "ControlState");
j = ReadInt(node, "Element");
val = ReadInt(node, "Value");
}
catch
{
return;
}
if (-1 <= val && ogControl.ControlStatesMax > val)
ogControl.SetMatrixElement(i, j, val);
else
{
ErrorType errorType = ErrorType.ControlStatesMatrix;
string errorMessage = string.Format(
ogControl.GetErrorMessage((int)errorType), i, j, val);
ogControl.OnError(new ErrorEventArgs(ErrorSeverity.Error, errorMessage));
}
}
private string GetString(XmlNode node, string key)
{
string value;
try
{
value = ReadStr(node, key);
}
catch
{
value = null;
}
return value;
}
private bool GetYesNo(XmlNode node, string key)
{
bool br = false;
try
{
string str = ReadStr(node, key);
br = IsYes(str);
}
catch
{
br = false;
}
return br;
}
private void GetCaptionStyle(XmlNode node)
{
Color backColor, textColor;
string bold = "", italic = "";
FontStyle fontStyle = FontStyle.Regular;
try
{
backColor = Color.FromName(ReadStr(node, "BackColor"));
textColor = Color.FromName(ReadStr(node, "TextColor"));
bold = ReadStr(node, "Bold");
italic = ReadStr(node, "Italic");
if (IsYes(bold))
fontStyle |= FontStyle.Bold;
if (IsYes(italic))
fontStyle |= FontStyle.Italic;
}
catch
{
backColor = Color.Navy;
textColor = Color.White;
fontStyle = FontStyle.Regular;
}
ogControl.CaptionStyle(backColor, textColor, fontStyle);
}
private bool IsYes(string str)
{
return "Yes" == str || "yes" == str || "Y" == str || "y" == str;
}
}
}