123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- using System;
- using FastReport.Data;
- using FastReport.Table;
- namespace FastReport.AdvMatrix
- {
- internal static class TemplateBuilder
- {
- public static int EnumColumnDescriptors(HeaderDescriptor root, int columnIndex, int rowIndex, Action<HeaderDescriptor, int, int, bool> func)
- {
- foreach (HeaderDescriptor d in root.Items)
- {
- func(d, columnIndex, rowIndex, true);
- if (d.Items.Count > 0)
- {
- if (d.Stepped)
- columnIndex = EnumColumnDescriptors(d, columnIndex + 1, rowIndex, func);
- else
- columnIndex = EnumColumnDescriptors(d, columnIndex, rowIndex + 1, func);
- }
- columnIndex++;
- }
- return columnIndex - 1;
- }
- public static int EnumRowDescriptors(HeaderDescriptor root, int columnIndex, int rowIndex, Action<HeaderDescriptor, int, int, bool> func)
- {
- foreach (HeaderDescriptor d in root.Items)
- {
- func(d, columnIndex, rowIndex, false);
- if (d.Items.Count > 0)
- {
- if (d.Stepped)
- rowIndex = EnumRowDescriptors(d, columnIndex, rowIndex + 1, func);
- else
- rowIndex = EnumRowDescriptors(d, columnIndex + 1, rowIndex, func);
- }
- rowIndex++;
- }
- return rowIndex - 1;
- }
- private static void CopyFromResultTable(AdvMatrixObject matrix, TableResult resultTable)
- {
- matrix.ColumnCount = resultTable.ColumnCount;
- matrix.RowCount = resultTable.RowCount;
- matrix.CreateUniqueNames();
- for (int x = 0; x < matrix.Columns.Count; x++)
- {
- matrix.Columns[x].Assign(resultTable.Columns[x]);
- }
- for (int y = 0; y < matrix.Rows.Count; y++)
- {
- matrix.Rows[y].Assign(resultTable.Rows[y]);
- }
- for (int x = 0; x < matrix.Columns.Count; x++)
- {
- for (int y = 0; y < matrix.Rows.Count; y++)
- {
- TableCell cell = matrix[x, y];
- // call AssignAll with assignName parameter to preserve names of objects contained in a cell
- resultTable[x, y].Name = cell.Name;
- cell.AssignAll(resultTable[x, y], true);
- cell.SetFlags(Flags.CanEdit, true);
- }
- }
- }
- private static TableCell CreateHeaderCell(AdvMatrixObject matrix, HeaderDescriptor descr)
- {
- TableCell cell = new TableCell();
- cell.HorzAlign = HorzAlign.Center;
- cell.VertAlign = VertAlign.Center;
- ApplyStyle(matrix, cell, "Header");
- if (descr != null)
- {
- if (descr.IsGroup)
- cell.Text = descr.Expression;
- else
- cell.Text = descr.DisplayText;
- }
- return cell;
- }
- private static TableCell CreateCell(AdvMatrixObject matrix)
- {
- TableCell cell = new TableCell();
- cell.HorzAlign = HorzAlign.Right;
- cell.VertAlign = VertAlign.Center;
- ApplyStyle(matrix, cell, "Body");
- return cell;
- }
- private static void ApplyStyle(AdvMatrixObject matrix, TableCell cell, string styleName)
- {
- Style style = null;
- int styleIndex = matrix.StyleSheet.IndexOf(matrix.Style);
- if (styleIndex != -1)
- {
- StyleCollection styles = matrix.StyleSheet[styleIndex];
- style = styles[styles.IndexOf(styleName)];
- }
- if (style != null)
- cell.ApplyStyle(style);
- }
- public static void UpdateStyle(AdvMatrixObject matrix)
- {
- int cornerWidth = matrix.Data.Rows.Size;
- int cornerHeight = matrix.Data.Columns.Size;
- for (int y = 0; y < matrix.RowCount; y++)
- {
- for (int x = 0; x < matrix.ColumnCount; x++)
- {
- string style = x < cornerWidth || y < cornerHeight ? "Header" : "Body";
- ApplyStyle(matrix, matrix[x, y], style);
- }
- }
- }
- public static void UpdateDescriptors(AdvMatrixObject matrix)
- {
- int cornerWidth = matrix.Data.Rows.Size;
- int cornerHeight = matrix.Data.Columns.Size;
- // update header descriptors
- Action<HeaderDescriptor, int, int, bool> func = (d, columnIndex, rowIndex, isColumn) =>
- {
- d.Matrix = matrix;
- d.IsColumn = isColumn;
- d.TemplateColumn = matrix.Columns[columnIndex];
- d.TemplateRow = matrix.Rows[rowIndex];
- d.TemplateCell = matrix[columnIndex, rowIndex];
- if (d.IsGroup)
- d.TemplateCell.AllowExpressions = false;
- if (!d.IsGroup && String.IsNullOrEmpty(d.DisplayText))
- d.DisplayText = d.TemplateCell.Text;
- };
- EnumColumnDescriptors(matrix.Data.Columns.Descriptor, cornerWidth, 0, func);
- EnumRowDescriptors(matrix.Data.Rows.Descriptor, 0, cornerHeight, func);
- // create cell descriptors
- matrix.Data.CellData.InitDescriptors();
- }
- public static void BuildTemplate(AdvMatrixObject matrix)
- {
- TableResult resultTable = new TableResult();
- int cornerWidth = matrix.Data.Rows.Size;
- int cornerHeight = matrix.Data.Columns.Size;
- TableColumn[] cornerColumns = new TableColumn[cornerWidth];
- TableRow[] cornerRows = new TableRow[cornerHeight];
- Action<HeaderDescriptor, int, int, bool> func = (d, columnIndex, rowIndex, isColumn) =>
- {
- // create resultTable columns and rows. Assign properties from existing template columns/rows
- while (columnIndex >= resultTable.Columns.Count)
- resultTable.Columns.Add(new TableColumn());
- while (rowIndex >= resultTable.Rows.Count)
- resultTable.Rows.Add(new TableRow());
- // the same assignment may occur several times, but it's a cheap operation so it's ok
- if (d.TemplateColumn != null)
- {
- resultTable.Columns[columnIndex].Assign(d.TemplateColumn);
- if (columnIndex < cornerWidth)
- cornerColumns[columnIndex] = d.TemplateColumn;
- }
- if (d.TemplateRow != null)
- {
- resultTable.Rows[rowIndex].Assign(d.TemplateRow);
- if (rowIndex < cornerHeight)
- cornerRows[rowIndex] = d.TemplateRow;
- }
- };
- EnumColumnDescriptors(matrix.Data.Columns.Descriptor, cornerWidth, 0, func);
- EnumRowDescriptors(matrix.Data.Rows.Descriptor, 0, cornerHeight, func);
- // header cells
- Action<HeaderDescriptor, int, int, bool> func1 = (d, columnIndex, rowIndex, isColumn) =>
- {
- TableCellData resultCell = resultTable.GetCellData(columnIndex, rowIndex);
- if (d.TemplateCell != null)
- resultCell.RunTimeAssign(d.TemplateCell, true);
- else
- resultCell.RunTimeAssign(CreateHeaderCell(matrix, d), true);
- if (d.IsGroup)
- resultCell.Text = d.Expression;
- if (!d.IsGroup && !String.IsNullOrEmpty(d.DisplayText))
- resultCell.Text = d.DisplayText;
- if (isColumn)
- {
- resultCell.ColSpan = d.Span;
- if (d.Items.Count == 0 || d.Stepped)
- resultCell.RowSpan = cornerHeight - rowIndex;
- }
- else
- {
- resultCell.RowSpan = d.Span;
- if (d.Items.Count == 0 || d.Stepped)
- resultCell.ColSpan = cornerWidth - columnIndex;
- }
- };
- EnumColumnDescriptors(matrix.Data.Columns.Descriptor, cornerWidth, 0, func1);
- EnumRowDescriptors(matrix.Data.Rows.Descriptor, 0, cornerHeight, func1);
- // corner
- int left, top;
- for (left = 0; left < cornerWidth; left++)
- {
- for (top = 0; top < cornerHeight; top++)
- {
- TableCellData resultCell = resultTable.GetCellData(left, top);
- if (cornerColumns[left] != null && cornerRows[top] != null)
- {
- TableCell templateCell = matrix[cornerColumns[left].Index, cornerRows[top].Index];
- resultCell.RunTimeAssign(templateCell, true);
- // do not allow spans to go outside corner area
- resultCell.ColSpan = Math.Min(templateCell.ColSpan, cornerWidth - left);
- resultCell.RowSpan = Math.Min(templateCell.RowSpan, cornerHeight - top);
- }
- else
- {
- resultCell.RunTimeAssign(CreateHeaderCell(matrix, null), true);
- }
- }
- }
- // cells
- left = cornerWidth;
- foreach (HeaderDescriptor columnItem in matrix.Data.Columns.Descriptor.TerminalItems)
- {
- top = cornerHeight;
- foreach (HeaderDescriptor rowItem in matrix.Data.Rows.Descriptor.TerminalItems)
- {
- TableCellData resultCell = resultTable.GetCellData(left, top);
- if (columnItem.TemplateColumn != null && rowItem.TemplateRow != null)
- {
- TableCell templateCell = matrix[columnItem.TemplateColumn.Index, rowItem.TemplateRow.Index];
- resultCell.RunTimeAssign(templateCell, true);
- resultCell.ColSpan = templateCell.ColSpan;
- resultCell.RowSpan = templateCell.RowSpan;
- }
- else
- {
- resultCell.RunTimeAssign(CreateCell(matrix), true);
- }
- top++;
- }
- left++;
- }
- // copy resultTable to matrix
- CopyFromResultTable(matrix, resultTable);
- UpdateDescriptors(matrix);
- resultTable.Dispose();
- }
- }
- }
|