203 lines
8.6 KiB
C#
203 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Printing;
|
|
using Config.Entities;
|
|
|
|
namespace Results.Output.Printers
|
|
{
|
|
public enum TableLines
|
|
{
|
|
None,
|
|
FirstAndLast,
|
|
FirstSecondAndLast,
|
|
All,
|
|
}
|
|
|
|
public class TableStyle
|
|
{
|
|
public float MarginX;
|
|
public float MarginY;
|
|
public Font Font;
|
|
public Font HeaderFont;
|
|
public int TopHeadersCount;
|
|
public int LeftHeadersCount;
|
|
public float LineWidth;
|
|
public TableLines HorizLines;
|
|
public TableLines VertLines;
|
|
}
|
|
|
|
public class Table
|
|
{
|
|
public readonly int ColumnsCount;
|
|
public int RowsCount { get { return Rows.Count; } }
|
|
|
|
public readonly IList<string[]> Rows;
|
|
public readonly IList<Alignment[]> HorizAlignments;
|
|
public readonly IList<VertAlignment[]> VertAlignments;
|
|
public TableStyle Style;
|
|
|
|
|
|
public Table(int columnsCount)
|
|
{
|
|
ColumnsCount = columnsCount;
|
|
|
|
Rows = new List<string[]>();
|
|
HorizAlignments = new List<Alignment[]>();
|
|
VertAlignments = new List<VertAlignment[]>();
|
|
Style = new TableStyle();
|
|
}
|
|
|
|
|
|
public void AddRow(string[] texts, Alignment[] horizAlignment, VertAlignment[] vertAlignemnt)
|
|
{
|
|
Rows.Add(texts);
|
|
HorizAlignments.Add(horizAlignment);
|
|
VertAlignments.Add(vertAlignemnt);
|
|
}
|
|
|
|
|
|
public SizeF Measure(System.Drawing.Printing.PrintPageEventArgs e)
|
|
{
|
|
SizeF retVal = new SizeF(0, 0);
|
|
if (RowsCount == 0) return retVal;
|
|
|
|
float[] columnWidth = new float[ColumnsCount];
|
|
float[] rowHeight = new float[RowsCount];
|
|
|
|
///
|
|
/// Measure table column widths and header height
|
|
///
|
|
for (int colIx = 0; colIx < ColumnsCount; colIx++)
|
|
{
|
|
for (int rowIx = 0; rowIx < RowsCount; rowIx++)
|
|
{
|
|
bool isHeader = (colIx < Style.LeftHeadersCount) || (rowIx < Style.TopHeadersCount);
|
|
SizeF size = PrintersCommon.Measure(e, Rows[rowIx][colIx], isHeader ? Style.HeaderFont : Style.Font);
|
|
if (size.Width > columnWidth[colIx]) columnWidth[colIx] = size.Width;
|
|
if (size.Height > rowHeight[rowIx]) rowHeight[rowIx] = size.Height;
|
|
}
|
|
|
|
bool hasLineToTheLeft = (Style.VertLines == TableLines.All)
|
|
|| ((Style.VertLines == TableLines.FirstAndLast) && (colIx == 0))
|
|
|| ((Style.VertLines == TableLines.FirstSecondAndLast) && (colIx <= 1));
|
|
|
|
retVal.Width += columnWidth[colIx] + (hasLineToTheLeft ? (Style.LineWidth + Style.MarginX) : 0) + Style.MarginX;
|
|
}
|
|
for (int rowIx = 0; rowIx < RowsCount; rowIx++)
|
|
{
|
|
bool hasLineAbove = (Style.HorizLines == TableLines.All)
|
|
|| ((Style.HorizLines == TableLines.FirstAndLast) && (rowIx == 0))
|
|
|| ((Style.HorizLines == TableLines.FirstSecondAndLast) && (rowIx <= 1));
|
|
|
|
retVal.Height += rowHeight[rowIx] + (hasLineAbove ? (Style.LineWidth + Style.MarginY) : 0) + Style.MarginY;
|
|
}
|
|
|
|
if (Style.VertLines == TableLines.None) retVal.Width -= Style.MarginX;
|
|
if (Style.HorizLines == TableLines.None) retVal.Height -= Style.MarginY;
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
public float Draw(System.Drawing.Printing.PrintPageEventArgs e, float left, float top)
|
|
{
|
|
if (RowsCount == 0) return top;
|
|
|
|
int tblColumnsCount = Rows[0].Length;
|
|
|
|
float[] columnWidth = new float[tblColumnsCount];
|
|
float[] columnPos = new float[tblColumnsCount];
|
|
float[] vertLinePos = new float[tblColumnsCount + 1];
|
|
|
|
float[] rowHeight = new float[RowsCount];
|
|
float[] rowPos = new float[RowsCount];
|
|
float[] horizLinePos = new float[RowsCount + 1];
|
|
|
|
///
|
|
/// Measure table column widths and header height
|
|
///
|
|
vertLinePos[0] = left;
|
|
horizLinePos[0] = top;
|
|
for (int colIx = 0; colIx < tblColumnsCount; colIx++)
|
|
{
|
|
for (int rowIx = 0; rowIx < RowsCount; rowIx++)
|
|
{
|
|
bool isHeader = (colIx < Style.LeftHeadersCount) || (rowIx < Style.TopHeadersCount);
|
|
SizeF size = PrintersCommon.Measure(e, Rows[rowIx][colIx], isHeader ? Style.HeaderFont : Style.Font);
|
|
if (size.Width > columnWidth[colIx]) columnWidth[colIx] = size.Width;
|
|
if (size.Height > rowHeight[rowIx]) rowHeight[rowIx] = size.Height;
|
|
}
|
|
|
|
bool hasLineToTheLeft = (Style.VertLines == TableLines.All)
|
|
|| ((Style.VertLines == TableLines.FirstAndLast) && (colIx == 0))
|
|
|| ((Style.VertLines == TableLines.FirstSecondAndLast) && (colIx <= 1));
|
|
|
|
columnPos[colIx] = vertLinePos[colIx] + (hasLineToTheLeft ? (Style.LineWidth + Style.MarginX) : 0);
|
|
vertLinePos[colIx + 1] = columnPos[colIx] + columnWidth[colIx] + Style.MarginX;
|
|
}
|
|
for (int rowIx = 0; rowIx < RowsCount; rowIx++)
|
|
{
|
|
bool hasLineAbove = (Style.HorizLines == TableLines.All)
|
|
|| ((Style.HorizLines == TableLines.FirstAndLast) && (rowIx == 0))
|
|
|| ((Style.HorizLines == TableLines.FirstSecondAndLast) && (rowIx <= 1));
|
|
|
|
rowPos[rowIx] = horizLinePos[rowIx] + (hasLineAbove ? Style.MarginY : 0);
|
|
horizLinePos[rowIx + 1] = rowPos[rowIx] + rowHeight[rowIx] + Style.LineWidth + Style.MarginY;
|
|
}
|
|
|
|
/// Horizontal lines
|
|
float tableLeftX = left;
|
|
float tableRightX = vertLinePos[tblColumnsCount] + Style.LineWidth;
|
|
if (Style.HorizLines != TableLines.None)
|
|
{
|
|
for (int rowIx = 0; rowIx <= RowsCount; rowIx++)
|
|
{
|
|
if (Style.HorizLines == TableLines.All || rowIx == 0 || rowIx == RowsCount || (Style.HorizLines == TableLines.FirstSecondAndLast && rowIx == 1))
|
|
{
|
|
e.Graphics.DrawLine(new Pen(Color.Black, Style.LineWidth), new PointF(tableLeftX, horizLinePos[rowIx] + Style.LineWidth / 2), new PointF(tableRightX, horizLinePos[rowIx] + Style.LineWidth / 2));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Vertical lines
|
|
float tableTopY = top;
|
|
float tableBottomY = horizLinePos[RowsCount] + Style.LineWidth;
|
|
if (Style.VertLines != TableLines.None)
|
|
{
|
|
for (int colIx = 0; colIx <= tblColumnsCount; colIx++)
|
|
{
|
|
if (Style.VertLines == TableLines.All || colIx == 0 || colIx == RowsCount || (Style.VertLines == TableLines.FirstSecondAndLast && colIx == 1))
|
|
{
|
|
e.Graphics.DrawLine(new Pen(Color.Black, Style.LineWidth), new PointF(vertLinePos[colIx] + Style.LineWidth / 2, tableTopY), new PointF(vertLinePos[colIx] + Style.LineWidth / 2, tableBottomY));
|
|
}
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Draw table body
|
|
///
|
|
for (int rowIndex = 0; rowIndex < RowsCount; rowIndex++)
|
|
{
|
|
string[] oneTableRow = Rows[rowIndex];
|
|
Alignment[] horizAlignment = HorizAlignments[(RowsCount > rowIndex) ? rowIndex : 0];
|
|
VertAlignment[] vertAlignment = VertAlignments[(RowsCount > rowIndex) ? rowIndex : 0];
|
|
for (int colIndex = 0; colIndex < tblColumnsCount; colIndex++)
|
|
{
|
|
bool isHeader = (colIndex < Style.LeftHeadersCount) || (rowIndex < Style.TopHeadersCount);
|
|
PrintersCommon.PrintAt(e, oneTableRow[colIndex],
|
|
isHeader ? Style.HeaderFont : Style.Font,
|
|
columnPos[colIndex],
|
|
rowPos[rowIndex],
|
|
columnWidth[colIndex],
|
|
rowHeight[rowIndex],
|
|
horizAlignment[colIndex],
|
|
vertAlignment[colIndex]);
|
|
}
|
|
}
|
|
|
|
return tableBottomY;
|
|
}
|
|
}
|
|
}
|