419 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;
using Volian.Base.Library;
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
#region checkborderarrays
// C2018-031 Adjust the Horizontal and Vertical cell border arrays if needed
public void CheckAndFixBorderArraySize(int grdRows, int grdCols, GridLinePattern defaultLinePattern)
{
if (HorizontalLines.Columns != grdCols || HorizontalLines.Rows != grdRows + 1)
HorizontalLines = new LinePatternArray(defaultLinePattern, grdRows + 1, grdCols, HorizontalLines.Lines);
if (VerticalLines.Columns != grdCols + 1 || VerticalLines.Rows != grdRows)
VerticalLines = new LinePatternArray(defaultLinePattern, grdRows, grdCols + 1, VerticalLines.Lines);
}
#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;
}
// C2018-031 used to automatically adjust the cell border arrays
public LinePatternArray(GridLinePattern defaultLinePattern, int rows, int columns, GridLinePattern[] lnsAry)
{
Rows = rows;
Columns = columns;
Lines = new GridLinePattern[rows * columns];
for (int r = 0; r < Rows; r++)
for (int c = 0; c < Columns; c++)
{
int idx = r * Columns + c;
if (idx < lnsAry.Length)
Lines[idx] = lnsAry[idx];
else
Lines[idx] = 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 enum GridLinePattern : int
{
Unknown = -1,
None = 0,
Single = 1,
Double = 2,
Thick = 3,
Dotted = 4,
Dashed = 5,
Mixed = 6
}
}