Rich c1d863e1ac Changed VlnBorders so that XML is not saved twice
Changed MyBorderDetailString so that XML is saved once
Adjust the vertical location of the Grid to match 16 bit.
2011-04-12 13:49:01 +00:00

480 lines
13 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 string ConvertToString()
{
return GenericSerializer<VlnBorders>.StringSerialize(this);
}
public override string ToString()
{
return "Volian Custom Borders";
}
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 int LineWidth0(GridLinePattern linePattern)
{
switch (linePattern)
{
case GridLinePattern.None:
return 0;
case GridLinePattern.Double:
case GridLinePattern.Thick:
return 3;
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;
if (rSrc > Rows - 1) rSrc = Rows - 1;
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
}
}