using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.Runtime.InteropServices;
// Part of RJConfig V1.3
// Classes for the different value types for a ConfigVariable.
namespace RJConfig {
// The built in config value type classes derived from CfgValueType<T>.
//------------------------ Int type -----------------------------------------------------------------------------
/// <remarks>
/// The value class for a basic Int variable.
/// </remarks>
public class CfgValueTypeNum : CfgValueType<int> {
/// <summary>
/// Function to parse a string to the int value.
/// </summary>
/// <param name="str">The string to be parsed as an int.</param>
public override void ParseString(string str)
{
try {
mData = int.Parse(str);
} catch {
mData = 0;
}
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The int value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals (int other)
{
return other == mData;
}
/// <summary>
/// Function to make a string from the int value. The string must be able to be parsed back
/// to an int with the ParseString function.
/// </summary>
/// <returns>The int value as a string.</returns>
public override string MakeString()
{
return mData.ToString();
}
}
/// <remarks>
/// The CfgVarNum class is a config variable class for a numeric (int) variables.
/// The sole purpose of this class is to simplify varaible creation with new() in classes that
/// are going to use this config variable. This removes the need to type the generic type definition.
/// Sort of a C++ typedef.
/// </remarks>
public class CfgVarNum : CfgVar<CfgValueTypeNum, int> {
/// <summary>
/// Public constructor.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if it the variable
/// isn't found in the associated config file.</param>
public CfgVarNum(Config c, string SectionName, string ItemName, string VariableName, int Def)
: base(c, SectionName, ItemName, VariableName, Def)
{
}
}
// ------------------------------ bool type ----------------------------------------------------------------------
/// <remarks>
/// The value class for a bool type variable.
/// </remarks>
public class CfgValueTypeBool : CfgValueType<bool> {
/// <summary>
/// Function to parse a string to the bool value.
/// </summary>
/// <param name="str">The string to be parsed as a bool.</param>
public override void ParseString(string str)
{
mData = ((string.Compare(str, "1") == 0) || (string.Compare(str, "TRUE", true) == 0) || (string.Compare(str, "ON", true) == 0));
}
/// <summary>
/// Function to make a string from the bool value. The string must be able to be parsed back
/// to a bool with the ParseString function.
/// </summary>
/// <returns>The bool value as a string.</returns>
public override string MakeString()
{
return string.Format("{0}", mData ? "true" : "false");
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The bool value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals (bool other)
{
return other == mData;
}
}
/// <remarks>
/// The Bool variable config class.
/// <seealso cref="CfgVarNum"/>
/// </remarks>
public class CfgVarBool : CfgVar<CfgValueTypeBool, bool> {
/// <summary>
/// Public constructor for the bool variable config class.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if it the variable
/// isn't found in the associated config file.</param>
public CfgVarBool(Config c, string SectionName, string ItemName, string VariableName, bool Def)
: base(c, SectionName, ItemName, VariableName, Def)
{
}
}
// ------------------------------ string type --------------------------------------------------------------------
/// <remarks>
/// The value class for a string type variable.
/// </remarks>
public class CfgValueTypeString : CfgValueType<string>{
/// <summary>
/// Nothing needs to be parsed since the value is already a string.
/// </summary>
/// <param name="str">The string value.</param>
public override void ParseString(string str)
{
mData = str;
}
/// <summary>
/// Nothing needs to be parsed since the value is already a string.
/// </summary>
/// <returns>The string value</returns>
public override string MakeString()
{
return mData;
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The string value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals (string other)
{
return other == mData;
}
}
/// <remarks>
/// The string variable config class.
/// <seealso cref="CfgVarNum"/>
/// </remarks>
public class CfgVarString : CfgVar<CfgValueTypeString, string> {
/// <summary>
/// Public constructor for the string variable config class.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if it the variable
/// isn't found in the associated config file.</param>
public CfgVarString (Config c, string SectionName, string ItemName, string VariableName, string Def)
: base(c, SectionName, ItemName, VariableName, Def)
{
}
}
// ------------------------------- int with limits ---------------------------------------------------------------
/// <remarks>
/// The value type for an Int variable with lower and upper limits.
/// </remarks>
public class CfgValueTypeNumLimit : CfgValueType<int> {
/// <summary>
/// The internal member for the lower limit of this value
/// </summary>
protected int mLowerLimit=int.MinValue;
/// <summary>
/// The internal member for the upper limit of this value.
/// </summary>
protected int mUpperLimit=int.MaxValue;
/// <summary>
/// Public property for the lower limit of the int value.
/// </summary>
public int LowerLimit
{
get
{
return mLowerLimit;
}
set
{
mLowerLimit = value;
}
}
/// <summary>
/// Public property for the upper limit of the int value.
/// </summary>
public int UpperLimit
{
get
{
return mUpperLimit;
}
set
{
mUpperLimit = value;
}
}
/// <summary>
/// Override for the Data property. The set function also verifies and limits
/// the value to be witin upper and lower limits.
/// </summary>
public override int Data
{
get
{
return mData;
}
set
{
mData = value;
TrimData();
}
}
/// <summary>
/// Function that parses the string value to the int value. The limits of
/// the value is also checked.
/// </summary>
/// <param name="str">The string representation of the int value.</param>
public override void ParseString(string str)
{
try {
mData = int.Parse(str);
} catch {
mData = 0;
}
TrimData();
}
/// <summary>
/// Function to convert the int value to a string.
/// </summary>
/// <returns>The string value of the int.</returns>
public override string MakeString()
{
return mData.ToString();
}
/// <summary>
/// Function to make sure that the int value is within upper and lower limits.
/// </summary>
public void TrimData()
{
if (mData < mLowerLimit) mData = mLowerLimit;
if (mData > mUpperLimit) mData = mUpperLimit;
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The int value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals (int other)
{
return other == mData;
}
}
/// <remarks>
/// The limited int value config class.
/// </remarks>
public class CfgVarNumLimit : CfgVar<CfgValueTypeNumLimit, int> {
/// <summary>
/// Public constructor for the limited int variable config class.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if it the variable
/// isn't found in the associated config file.</param>
/// <param name="LowerLimit">The minimum value for this variable.</param>
/// <param name="UpperLimit">The maximum value for this variable.</param>
public CfgVarNumLimit(Config c, string SectionName, string ItemName, string VariableName, int Def,int LowerLimit,int UpperLimit)
:base(c,SectionName,ItemName,VariableName,Def)
{
cfgValueType.LowerLimit = LowerLimit;
cfgValueType.UpperLimit = UpperLimit;
cfgValueType.TrimData(); // Data has to be trimmed since upper and lower limits have changed.
}
}
// ------------------------------------ Enum type ---------------------------------------------------------------
/// <remarks>
/// The value type for an enumerator variable.
/// </remarks>
public class CfgValueTypeEnum : CfgValueType<Enum>{
/// <summary>
/// The parse string function for the enumerator type.
/// </summary>
/// <param name="str">The enumerator type in string format.</param>
public override void ParseString(string str)
{
int index=0;
foreach (string s in Enum.GetNames(mData.GetType()))
{
if (string.Compare(str, s, true)==0)
{
mData =(Enum) Enum.GetValues(mData.GetType()).GetValue(index);
return;
}
index++;
}
mData = (Enum)Enum.GetValues(mData.GetType()).GetValue(0); //Default if no match is found.
// Perhaps better to have an exception here?
}
/// <summary>
/// Function to convert the enum value to a string.
/// </summary>
/// <returns>The converted enum value to string</returns>
public override string MakeString()
{
return mData.ToString();
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The Enum value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals (Enum other)
{
return other == mData;
}
}
/// <remarks>
/// The enumerator value config class.
/// </remarks>
public class CfgVarEnum : CfgVar<CfgValueTypeEnum, Enum>{
/// <summary>
/// Public constructor for the XmlDocument type variable config class.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if it the variable
/// isn't found in the associated config file.</param>
public CfgVarEnum (Config c, string SectionName, string ItemName, string VariableName, Enum Def)
: base(c, SectionName, ItemName, VariableName, Def)
{
}
}
// ------------------------------------ Double type --------------------------------------------------------
/// <remarks>
/// The value type for an floating point Double variable.
/// </remarks>
public class CfgValueTypeDouble : CfgValueType<Double> {
/// <summary>
/// The parse string function for the Double type.
/// </summary>
/// <param name="str">The Double in string format.</param>
public override void ParseString(string str)
{
mData = Double.Parse(str);
}
/// <summary>
/// Function to convert the Double to a string.
/// </summary>
/// <returns>The Double in string format.</returns>
public override string MakeString()
{
return mData.ToString();
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The Double value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals(Double other)
{
return (mData == other);
}
}
/// <remarks>
/// The Double value type config class.
/// </remarks>
public class CfgVarDouble : CfgVar<CfgValueTypeDouble, Double> {
/// <summary>
/// Public constructor for the Double type variable config class.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if it the variable
/// isn't found in the associated config file.</param>
public CfgVarDouble(Config c, string SectionName, string ItemName, string VariableName, Double Def)
: base(c, SectionName, ItemName, VariableName, Def)
{
}
}
// ------------------------------------ XmlDocument type --------------------------------------------------------
/// <remarks>
/// The value type for an XmlDocument variable. The root node is the <value> element
/// </remarks>
public class CfgValueTypeXmlDoc : CfgValueType<XmlDocument> {
/// <summary>
/// The parse string function for XmlDocument type.
/// </summary>
/// <param name="str">The XmlDocument in string format inside the <Value> node. The <Value> level
/// is handled by the Variable.</param>
public override void ParseString(string str)
{
if (mData == null) {
mData = new XmlDocument();
}
mData.LoadXml("<Value>"+str+"</Value>");
}
/// <summary>
/// Function to convert the XmlDocument to a string.
/// </summary>
/// <returns>The inner xml text below the <Value> root node</returns>
public override string MakeString()
{
if (mData == null) {
return "";
} else {
XmlNode valueNode = mData.SelectSingleNode("Value");
if (valueNode != null) {
return valueNode.InnerXml;
} else {
return "";
}
}
}
/// <summary>
/// The equality function for the IEquateable interface
/// </summary>
/// <param name="other">The XmlDocument value to compare for equality with this value type.</param>
/// <returns>true if other is equal to the type for this value.</returns>
public override bool Equals(XmlDocument other)
{
if ((mData == null) && (other == null))
return true;
if ((mData == null) || (other == null))
return false;
return (mData.InnerText.CompareTo(other.InnerText)==0);
}
}
/// <remarks>
/// The XmlDocument type variable config class.
/// </remarks>
public class CfgVarXmlDoc : CfgVar<CfgValueTypeXmlDoc, XmlDocument> {
/// <summary>
/// Public constructor for the XmlDocument type variable config class.
/// </summary>
/// <param name="c">The Config object where this variable is going to be created.</param>
/// <param name="SectionName">The section name for this variable.</param>
/// <param name="ItemName">The item name for this variable.</param>
/// <param name="VariableName">The name for this variable.</param>
/// <param name="Def">The default value for this variable that will be used if the variable
/// isn't found in the associated config file. Note that the Def is saved as a reference which means that
/// the default value will change if the original object used as the default, is changed.
/// A valid default XmlDocument can be null. If it has elements, the DocumentElement should be named "Value"</param>
public CfgVarXmlDoc(Config c, string SectionName, string ItemName, string VariableName, XmlDocument Def)
: base(c, SectionName, ItemName, VariableName, Def)
{
}
}
// =================================== Combined types ==============================================================
// ----------------------------------- Dialog window position and visibility ---------------------------------------
/// <remarks>
/// Class that holds position and visible state for a modeless dialog form. Meant to live and be handled by the
/// DlgPosSave class.
/// <seealso cref="DlgPosSave"/>
/// </remarks>
public class CfgVarDlgWindowPos{
/// <summary>
/// Int type Config variable for the x-position of the dialog.
/// </summary>
public CfgVarNum xpos;
/// <summary>
/// Int type Config variable for the y-position of the dialog.
/// </summary>
public CfgVarNum ypos;
/// <summary>
/// Bool type Config variable for the visible state.
/// </summary>
public CfgVarBool visible;
/// <summary>
/// Public constructor.
/// Creates xpos, ypos and visible variables and either loads them with saved values from the config file or
/// initiates the config file and sets the variables to default values.
/// The config file should normally be the variables file (Config.AppVarInst).
/// </summary>
/// <param name="c">The Config object for these variables. Normally the Config.AppVarInst (variables).</param>
/// <param name="SectionName">Name of the Section where the dialog pos and state are to be kept.
/// This section can be used for other Items and variables for the modeless dialog. The Item for the
/// variables are set to DialogWindowPos.</param>
public CfgVarDlgWindowPos(Config c, string SectionName)
{
xpos = new CfgVarNum(c, SectionName, "DialogWindowPos", "XPos", 10);
ypos = new CfgVarNum(c, SectionName, "DialogWindowPos", "YPos", 10);
visible = new CfgVarBool(c, SectionName, "DialogWindowPos", "Visible", false); // Default is invisible.
}
/// <summary>
/// Public constructor that also moves the dialog to the saved (or default) postion and sets the
/// visible state.
/// </summary>
/// <param name="c">Config object for the variables.<seealso cref="CfgVarDlgWindowPos(Config,string)"/></param>
/// <param name="SectionName">Section name for the variables.<seealso cref="CfgVarDlgWindowPos(Config,string)"/></param>
/// <param name="f">The windows Forms class for the dialog.</param>
public CfgVarDlgWindowPos(Config c,string SectionName,Form f)
:this(c,SectionName)
{
GetCfg(f);
}
/// <summary>
/// Sets the dialog position and state to the values saved in the config file.
/// Normally called when the dialog is created.
/// </summary>
/// <param name="f">The windows Forms object for the dialog.</param>
public void GetCfg(Form f)
{
f.StartPosition = FormStartPosition.Manual;
f.Left = xpos.CfgData;
f.Top = ypos.CfgData;
f.Visible = visible.CfgData;
}
/// <summary>
/// Sets the config variables values to the position and state of the Form. Normally called when
/// the dialog is destroyed.
/// </summary>
/// <param name="f">The windows Forms object for the dialog.</param>
public void SetCfg(Form f)
{
xpos.CfgData = f.Left;
ypos.CfgData = f.Top;
visible.CfgData = f.Visible;
}
}
// -------------------------------- Form window position, size and state ------------------------------------------
/// <remarks>
/// Class that holds position and state for a windows Forms form. Meant to live and be handled by the
/// FormPosSave class.
/// <seealso cref="FormPosSave"/>
/// </remarks>
public class CfgVarWindowPos {
/// <summary>
/// Structure needed for the GetWindowPlacement WIN32 API function
/// </summary>
internal struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
public struct RECT
{
public RECT(int l, int t, int r, int b)
{
Left = l;
Top = t;
Right = r;
Bottom = b;
}
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public struct POINT
{
public POINT(int x, int y)
{
X = x;
Y = y;
}
public int X;
public int Y;
}
}
// The Win32 API methods
[DllImport("user32")]
internal static extern int GetWindowPlacement(IntPtr hwnd, ref WINDOWPLACEMENT lpwndpl);
/// <summary>
/// The config variable for window x position.
/// </summary>
public CfgVarNum xpos;
/// <summary>
/// The config variable for window y position.
/// </summary>
public CfgVarNum ypos;
/// <summary>
/// The config variable for window width.
/// </summary>
public CfgVarNum width;
/// <summary>
/// The config variable for window height.
/// </summary>
public CfgVarNum height;
/// <summary>
/// The config variable for window state (maximized, normal, minimized).
/// </summary>
public CfgVarEnum state;
/// <summary>
/// Public constructor that initializes config variables.
/// </summary>
/// <param name="c">The Config object for these variables. Normally the Config.AppVarInst (variables).</param>
/// <param name="SectionName">Name of the Section where the window form pos and state are to be kept.
/// This section can be used for other Items and variables for the form. The Item for the
/// variables are set to WindowPos.</param>
public CfgVarWindowPos(Config c, string SectionName)
{
xpos = new CfgVarNum(c, SectionName, "WindowPos", "XPos", 10);
ypos = new CfgVarNum(c, SectionName, "WindowPos", "YPos", 10);
width = new CfgVarNum(c, SectionName, "WindowPos", "Width", 200);
height = new CfgVarNum(c, SectionName, "WindowPos", "Height", 200);
state = new CfgVarEnum(c, SectionName, "WindowPos", "State", FormWindowState.Normal);
}
/// <summary>
/// Public constructor that also moves the form to the saved (or default) postion and sets the
/// window state.
/// </summary>
/// <param name="c">Config object for the variables.<seealso cref="CfgVarWindowPos(Config,string)"/></param>
/// <param name="SectionName">Section name for the variables.<seealso cref="CfgVarWindowPos(Config,string)"/></param>
/// <param name="f">The windows Forms object for the form.</param>
public CfgVarWindowPos(Config c, string SectionName, Form f)
:this(c, SectionName)
{
GetCfg(f);
}
/// <summary>
/// Sets the form position and state to the values saved in the config file. Normally called
/// when the form is created.
/// </summary>
/// <param name="f">The windows Forms object for the form.</param>
public void GetCfg(Form f)
{
f.StartPosition = FormStartPosition.Manual;
f.Left = xpos.CfgData;
f.Top = ypos.CfgData;
f.Width = width.CfgData;
f.Height = height.CfgData;
f.WindowState = (FormWindowState)state.CfgData;
}
/// <summary>
/// Saves the current form position and state to the config varables. Normally called just before the
/// form is destroyed.
/// </summary>
/// <param name="f"></param>
public void SetCfg(Form f)
{
if (!f.IsDisposed) {
state.CfgData = (f.WindowState == FormWindowState.Maximized) ? FormWindowState.Maximized : FormWindowState.Normal;
WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
GetWindowPlacement(f.Handle, ref wp);
xpos.CfgData = wp.rcNormalPosition.Left;
ypos.CfgData = wp.rcNormalPosition.Top;
width.CfgData = wp.rcNormalPosition.Right - wp.rcNormalPosition.Left;
height.CfgData = wp.rcNormalPosition.Bottom - wp.rcNormalPosition.Top;
}
}
}
}