2011-03-23 15:01:19 +00:00

458 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Drawing;
namespace Volian.Controls.Library
{
[Serializable]
[XmlRoot("VlnBorders")]
public class VlnBorders
{
#region Properties
private int _Rows;
[XmlAttribute("Rows")]
public int Rows
{
get { return _Rows; }
set { _Rows = value; }
}
private int _Columns;
[XmlAttribute("Columns")]
public int Columns
{
get { return _Columns; }
set { _Columns = value; }
}
private LinePatternArray _VerticalLines;
public LinePatternArray VerticalLines
{
get { return _VerticalLines; }
set { _VerticalLines = value; }
}
private LinePatternArray _HorizontalLines;
public LinePatternArray HorizontalLines
{
get { return _HorizontalLines; }
set { _HorizontalLines = value; }
}
#endregion
#region ctor
public VlnBorders() { ;}
public VlnBorders(GridLinePattern defaultLinePattern, int rows, int columns)
{
Rows = rows;
Columns = columns;
HorizontalLines = new LinePatternArray(defaultLinePattern, Rows + 1, Columns);
VerticalLines = new LinePatternArray(defaultLinePattern, Rows, Columns + 1);
}
#endregion
#region SetRange - Set the border styles over a range of cells
public void SetRange(int r1, int c1, int r2, int c2,
GridLinePattern top, GridLinePattern middle, GridLinePattern bottom,
GridLinePattern left, GridLinePattern center, GridLinePattern right)
{
for (int c = c1; c <= c2; c++)
{
if (top != GridLinePattern.Mixed) HorizontalLines[r1, c] = top;
for (int r = r1 + 1; r <= r2; r++)
if (middle != GridLinePattern.Mixed) HorizontalLines[r, c] = middle;
if (bottom != GridLinePattern.Mixed) HorizontalLines[r2 + 1, c] = bottom;
}
for (int r = r1; r <= r2; r++)
{
if (left != GridLinePattern.Mixed) VerticalLines[r, c1] = left;
for (int c = c1 + 1; c <= c2; c++)
if (center != GridLinePattern.Mixed) VerticalLines[r, c] = center;
if (right != GridLinePattern.Mixed) VerticalLines[r, c2 + 1] = right;
}
}
#endregion
#region Get Borders over a Range - Return Mixed if multiple values are found.
public GridLinePattern RangeTopBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = HorizontalLines[r1, c1];
for (int c = c1; c <= c2; c++)
if (linePattern != HorizontalLines[r1, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeHorizontalBorder(int r1, int c1, int r2, int c2)
{
if (r1 == r2) return GridLinePattern.None;
GridLinePattern linePattern = HorizontalLines[r1 + 1, c1];
for (int r = r1 + 1; r <= r2; r++)
for (int c = c1; c <= c2; c++)
if (linePattern != HorizontalLines[r, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeBottomBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = HorizontalLines[r2 + 1, c1];
for (int c = c1; c <= c2; c++)
if (linePattern != HorizontalLines[r2 + 1, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeLeftBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = VerticalLines[r1, c1];
for (int r = r1; r <= r2; r++)
if (linePattern != VerticalLines[r, c1]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeVerticalBorder(int r1, int c1, int r2, int c2)
{
if (c1 == c2) return GridLinePattern.None;
GridLinePattern linePattern = VerticalLines[r1, c1 + 1];
for (int c = c1 + 1; c <= c2; c++)
for (int r = r1 + 1; r <= r2; r++)
if (linePattern != VerticalLines[r, c]) return GridLinePattern.Mixed;
return linePattern;
}
public GridLinePattern RangeRightBorder(int r1, int c1, int r2, int c2)
{
GridLinePattern linePattern = VerticalLines[r1, c2 + 1];
for (int r = r1; r <= r2; r++)
if (linePattern != VerticalLines[r, c2 + 1]) return GridLinePattern.Mixed;
return linePattern;
}
#endregion
#region Insert and Remove Rows and Columns
public void InsertRow(int row)
{
HorizontalLines.InsertRow(row);
VerticalLines.InsertRow(row);
}
public void InsertRows(int row, int count)
{
HorizontalLines.InsertRows(row, count);
VerticalLines.InsertRows(row, count);
}
public void DeleteRow(int row)
{
HorizontalLines.DeleteRow(row);
VerticalLines.DeleteRow(row);
}
public void DeleteRows(int row, int count)
{
HorizontalLines.DeleteRows(row, count);
VerticalLines.DeleteRows(row, count);
}
public void InsertColumn(int column)
{
HorizontalLines.InsertColumn(column);
VerticalLines.InsertColumn(column);
}
public void InsertColumns(int column, int count)
{
HorizontalLines.InsertColumns(column, count);
VerticalLines.InsertColumns(column, count);
}
public void DeleteColumn(int column)
{
HorizontalLines.DeleteColumn(column);
VerticalLines.DeleteColumn(column);
}
public void DeleteColumns(int column, int count)
{
HorizontalLines.DeleteColumns(column, count);
VerticalLines.DeleteColumns(column, count);
}
#endregion
#region Serialize
public override string ToString()
{
return GenericSerializer<VlnBorders>.StringSerialize(this);
}
public static VlnBorders Get(string xml)
{
return GenericSerializer<VlnBorders>.StringDeserialize(xml);
}
#endregion
#region Line Pattern Static Methods
public static int LineWidth(GridLinePattern linePattern)
{
switch (linePattern)
{
case GridLinePattern.Double:
case GridLinePattern.Thick:
return 3;
case GridLinePattern.None:
case GridLinePattern.Single:
case GridLinePattern.Dotted:
case GridLinePattern.Dashed:
case GridLinePattern.Mixed:
default:
return 1;
}
}
public static Pen LinePen(GridLinePattern linePattern, Color foreColor)
{
Pen pn = new Pen(foreColor, 1);
switch (linePattern)
{
case GridLinePattern.None:
pn.Width = 0;
break;
case GridLinePattern.Thick:
pn.Width = 3;
break;
case GridLinePattern.Dotted:
pn.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
float[] patternDot = { 1, 2 };
pn.DashPattern = patternDot;
break;
case GridLinePattern.Dashed:
pn.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
float[] patternDash = { 6, 6 };
pn.DashPattern = patternDash;
break;
case GridLinePattern.Mixed:
pn.Color = Color.LightGray;
break;
case GridLinePattern.Double:
case GridLinePattern.Single:
default:
break;
}
return pn;
}
#endregion
}
[Serializable]
public class LinePatternArray
{
#region Properties
protected static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private int _Rows;
[XmlAttribute("Rows")]
public int Rows
{
get { return _Rows; }
set { _Rows = value; }
}
private int _Columns;
[XmlAttribute("Columns")]
public int Columns
{
get { return _Columns; }
set { _Columns = value; }
}
private GridLinePattern[] _Lines;
public GridLinePattern[] Lines
{
get { return _Lines; }
set { _Lines = value; }
}
#endregion
#region ctor
public LinePatternArray() { ;}
public LinePatternArray(GridLinePattern defaultLinePattern, int rows, int columns)
{
Rows = rows;
Columns = columns;
Lines = new GridLinePattern[rows * columns];
for (int r = 0; r < Rows; r++)
for (int c = 0; c < Columns; c++)
Lines[r * Columns + c] = defaultLinePattern;
}
#endregion
#region Array Access
public GridLinePattern this[int r, int c]
{
get
{
int indx = r * Columns + c;
if (indx < Lines.Length) return Lines[r * Columns + c];
_MyLog.WarnFormat("GridLinePattern: Lines Array Access out-of-bounds ({0}, {1}) within ({2}, {3})", r, c, Rows, Columns);
return GridLinePattern.Single;
}
set { Lines[r * Columns + c] = value; }
}
#endregion
#region Insert and Delete Rows and Columns
public void InsertRow(int row)
{
InsertRows(row, 1);
}
public void InsertRows(int row, int count)
{
// Create a new Array of the correct size
GridLinePattern[] newLines = new GridLinePattern[(Rows + count) * Columns];
int newRows = Rows + count;
for (int r = 0; r < newRows; r++)
{
int rSrc = r < row ? r : r > row + count ? r - count : row;
for (int c = 0; c < Columns; c++)
{
newLines[r * Columns + c] = Lines[rSrc * Columns + c];
}
}
Lines = newLines;
Rows = newRows;
}
public void DeleteRow(int row)
{
DeleteRows(row, 1);
}
public void DeleteRows(int row, int count)
{
GridLinePattern[] newLines = new GridLinePattern[(Rows - count) * Columns];
int newRows = Rows - count;
for (int r = 0; r < newRows; r++)
{
int rSrc = r < row ? r : r + count;
for (int c = 0; c < Columns; c++)
{
newLines[r * Columns + c] = Lines[rSrc * Columns + c];
}
}
Lines = newLines;
Rows = newRows;
}
public void InsertColumn(int column)
{
InsertColumns(column, 1);
}
public void InsertColumns(int column, int count)
{
// Create a new Array of the correct size
GridLinePattern[] newLines = new GridLinePattern[Rows * (Columns + count)];
int newColumns = Columns + count;
for (int r = 0; r < Rows; r++)
{
for (int c = 0; c < newColumns; c++)
{
int cSrc = c < column ? c : c > column + count ? c - count : column;
newLines[r * newColumns + c] = Lines[r * Columns + cSrc];
}
}
Lines = newLines;
Columns = newColumns;
}
public void DeleteColumn(int column)
{
DeleteColumns(column, 1);
}
public void DeleteColumns(int column, int count)
{
GridLinePattern[] newLines = new GridLinePattern[Rows * (Columns - count)];
int newColumns = Columns - count;
for (int r = 0; r < Rows; r++)
{
for (int c = 0; c < newColumns; c++)
{
int cSrc = c < column ? c : c + count;
newLines[r * newColumns + c] = Lines[r * Columns + cSrc];
}
}
Lines = newLines;
Columns = newColumns;
}
#endregion
}
public static class GenericSerializer<T> where T : class
{
public static string StringSerialize(T t)
{
string strOutput = string.Empty;
XmlSerializer xs = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
xs.Serialize(new NonXsiTextWriter(ms, Encoding.UTF8), t);
//xs.Serialize(ms, t);
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
strOutput = sr.ReadToEnd();
ms.Close();
}
return strOutput;
}
public static T StringDeserialize(string s)
{
T t;
XmlSerializer xs = new XmlSerializer(typeof(T));
UTF8Encoding enc = new UTF8Encoding();
Byte[] arrBytData = enc.GetBytes(s);
using (MemoryStream ms = new MemoryStream(arrBytData))
{
t = (T)xs.Deserialize(ms);
}
return t;
}
//public static void WriteFile(T t, string fileName)
//{
// string strOutput = string.Empty;
// XmlSerializer xs = new XmlSerializer(typeof(T));
// using (FileStream fs = new FileStream(fileName, FileMode.Create))
// {
// xs.Serialize(new NonXsiTextWriter(fs, Encoding.UTF8), t);
// fs.Close();
// }
//}
//public static T ReadFile(string fileName)
//{
// T t;
// XmlSerializer xs = new XmlSerializer(typeof(T));
// using (FileStream fs = new FileStream(fileName, FileMode.Open))
// {
// t = (T)xs.Deserialize(fs);
// }
// return t;
//}
}
public class NonXsiTextWriter : XmlTextWriter
{
public NonXsiTextWriter(TextWriter w) : base(w) { }
public NonXsiTextWriter(Stream w, Encoding encoding)
: base(w, encoding)
{
this.Formatting = Formatting.Indented;
}
public NonXsiTextWriter(string filename, Encoding encoding) : base(filename, encoding) { }
bool _skip = false;
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
if ((prefix == "xmlns" && (localName == "xsd" || localName == "xsi")) || // Omits XSD and XSI declarations.
ns == XmlSchema.InstanceNamespace) // Omits all XSI attributes.
{
_skip = true;
return;
}
if (localName == "xlink_href")
base.WriteStartAttribute(prefix, "xlink:href", ns);
else
base.WriteStartAttribute(prefix, localName, ns);
}
public override void WriteString(string text)
{
if (_skip) return;
base.WriteString(text);
}
public override void WriteEndAttribute()
{
if (_skip)
{ // Reset the flag, so we keep writing.
_skip = false;
return;
}
base.WriteEndAttribute();
}
}
public enum GridLinePattern : int
{
Unknown = -1,
None = 0,
Single = 1,
Double = 2,
Thick = 3,
Dotted = 4,
Dashed = 5,
Mixed = 6
}
}