419 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			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
 | 
						|
	}
 | 
						|
}
 |