using System; using System.Windows.Forms; using FastReport.Table; using FastReport.Data; using FastReport.Controls; using FastReport.Utils; namespace FastReport.AdvMatrix { internal enum MatrixElement { None, Corner, Column, Row, Cell } // cell extension methods internal static partial class CellExt { internal static readonly string[] PercentNames = { "None", "PercentOfColumnTotal", "PercentOfRowTotal", "PercentOfGrandTotal", "PercentOfPreviousColumn", "PercentOfPreviousRow" }; private static AdvMatrixObject Matrix(this TableCell cell) { return cell.Table as AdvMatrixObject; } internal static MatrixElement GetMatrixElement(this TableCell cell) { AdvMatrixObject matrix = cell.Matrix(); int cornerWidth = matrix.Data.Rows.Size; int cornerHeight = matrix.Data.Columns.Size; if (cornerWidth == 0 && cornerHeight == 0) return MatrixElement.None; if (cell.Address.X < cornerWidth && cell.Address.Y < cornerHeight) return MatrixElement.Corner; if (cell.Address.X >= cornerWidth && cell.Address.Y < cornerHeight) return MatrixElement.Column; if (cell.Address.X < cornerWidth && cell.Address.Y >= cornerHeight) return MatrixElement.Row; return MatrixElement.Cell; } internal static HeaderDescriptor GetHeaderDescriptor(this TableCell cell) { AdvMatrixObject matrix = cell.Table as AdvMatrixObject; foreach (HeaderDescriptor d in matrix.Data.Columns.Descriptor.AllItems) { if (d.TemplateCell == cell) return d; } foreach (HeaderDescriptor d in matrix.Data.Rows.Descriptor.AllItems) { if (d.TemplateCell == cell) return d; } return null; } private static Column GetColumn(Report report, string text) { if (text.StartsWith("[") && text.EndsWith("]")) text = text.Substring(1, text.Length - 2); return DataHelper.GetColumn(report.Dictionary, text); } private static string GetCaption(Report report, string text) { Column c = GetColumn(report, text); if (c != null) return c.Alias; if (text.StartsWith("[") && text.EndsWith("]")) return text.Substring(1, text.Length - 2); return text; } internal static string GetDisplayText(this TableCell cell, string defaultText) { if (!cell.IsDesigning) return defaultText; MatrixElement el = cell.GetMatrixElement(); if (el == MatrixElement.Cell) { CellDescriptor descr = cell.GetDescriptor(); if (descr != null && descr.Aggregates.Count > 0) { string text = cell.Text; foreach (AggregateExpressionPair ag in descr.Aggregates) { Column c = GetColumn(cell.Report, ag.Expression); if (c != null) { while (text.Contains(ag.Expression)) { text = text.Replace(ag.Expression, c.Alias); } } } return text; } } else if (el == MatrixElement.Column || el == MatrixElement.Row) { HeaderDescriptor descr = cell.GetHeaderDescriptor(); if (descr != null) { Column c = GetColumn(cell.Report, descr.Expression); if (c != null) return "[" + c.Alias + "]"; if (descr.IsGroup && !descr.Expression.StartsWith("[")) return "[" + descr.Expression + "]"; } } return defaultText; } private static TreeNode AddNode(string text, int imageIndex) { TreeNode node = new TreeNode(text); node.ImageIndex = imageIndex; node.SelectedImageIndex = imageIndex; return node; } internal static void ProvideMatrixItems(this TableCell cell, DataTreeView tree) { string name = cell.Table.Name; TreeNode matrixNode = AddNode(name, 142); tree.Nodes.Add(matrixNode); MatrixElement el = cell.GetMatrixElement(); if (el == MatrixElement.Column || el == MatrixElement.Row) { TreeNode propertiesNode = AddNode(Res.Get("ComponentMenu,AdvMatrixCell,Properties"), 233); matrixNode.Nodes.Add(propertiesNode); propertiesNode.Nodes.Add(AddNode(name + ".RowNo", 224)); propertiesNode.Nodes.Add(AddNode(name + ".ItemCount", 224)); } else if (el == MatrixElement.Cell) { MyRes res = new MyRes("ComponentMenu,AdvMatrixCell"); TreeNode aggregatesNode = AddNode(res.Get("AggregateFunctions"), 132); TreeNode specialFunctionsNode = AddNode(res.Get("SpecialFunctions"), 52); TreeNode propertiesNode = AddNode(res.Get("Properties"), 233); matrixNode.Nodes.Add(aggregatesNode); matrixNode.Nodes.Add(specialFunctionsNode); matrixNode.Nodes.Add(propertiesNode); foreach (string s in Aggregates.Names) { aggregatesNode.Nodes.Add(AddNode(s + "()", 132)); } foreach (string s in ExpressionParser.SpecialFunctionNames) { specialFunctionsNode.Nodes.Add(AddNode(s + "()", 52)); } propertiesNode.Nodes.Add(AddNode(name + ".ColumnIndex", 224)); propertiesNode.Nodes.Add(AddNode(name + ".RowIndex", 224)); propertiesNode.Nodes.Add(AddNode(name + ".ColumnValues[]", 233)); propertiesNode.Nodes.Add(AddNode(name + ".RowValues[]", 233)); } } public static void AddCollapseButton(this TableCell cell) { MatrixCollapseButton btn = new MatrixCollapseButton(); btn.Parent = cell; btn.Width = 16; btn.SymbolSize = 5; btn.Dock = DockStyle.Left; btn.CreateUniqueName(); cell.Padding = new Padding(16, 1, cell.GetSortButton() != null ? 16 : 2, 1); HeaderDescriptor descr = cell.GetHeaderDescriptor(); if (descr != null) { if (descr.Items.Count == 0) descr = descr.Parent; foreach (HeaderDescriptor child in descr.Items) { if (child.IsGroup) child.VisibleToggledBy = btn.Name; } } } public static void AddSortButton(this TableCell cell) { MatrixSortButton btn = new MatrixSortButton(); btn.Parent = cell; btn.Width = 16; btn.SymbolSize = 7; btn.Dock = DockStyle.Right; btn.CreateUniqueName(); cell.Padding = new Padding(cell.GetCollapseButton() != null ? 16 : 2, 1, 16, 1); } public static void ChangeExpression(this TableCell cell, string expression) { CellDescriptor cellDescr = cell.GetDescriptor(); if (expression == "") cell.Text = ""; else if (cellDescr.Aggregates.Count == 1) { AggregateExpressionPair ag = cellDescr.Aggregates[0]; if (ag.Expression != expression) { while (cell.Text.Contains(ag.Expression)) { cell.Text = cell.Text.Replace(ag.Expression, expression); } } } else { cell.Text = "[Sum(" + expression + ")]"; } } public static void ChangeAggregateFunction(this TableCell cell, string func) { CellDescriptor descr = cell.GetDescriptor(); if (descr.Aggregates.Count == 1) { AggregateExpressionPair ag = descr.Aggregates[0]; string oldFunc = ag.AggregateName + "(" + ag.Expression + ")"; string newFunc = func + "(" + ag.Expression + ")"; if (oldFunc != newFunc) { while (cell.Text.Contains(oldFunc)) { cell.Text = cell.Text.Replace(oldFunc, newFunc); } } } } public static void ChangePercentFunction(this TableCell cell, string func) { CellDescriptor descr = cell.GetDescriptor(); if (descr.ContentType == CellContentType.Aggregate) { AggregateExpressionPair ag = descr.Aggregates[0]; if (func != "None") cell.Text = "[" + func + "(" + ag.AggregateName + "(" + ag.Expression + "))]"; } else if (descr.ContentType == CellContentType.SingleExpression) { string text = cell.Text.Substring(1, cell.Text.Length - 2); foreach (string name in PercentNames) { if (text.StartsWith(name)) { if (func == "None") cell.Text = "[" + text.Substring(name.Length + 1, text.Length - name.Length - 2) + "]"; else cell.Text = "[" + func + text.Substring(name.Length) + "]"; break; } } } } private static HeaderDescriptor CreateSimpleHeader(TableCell cell, HeaderDescriptor d) { HeaderDescriptor descr = d.InsertChild(new HeaderDescriptor()); CellDescriptor cellDescr = cell.GetDescriptor(); if (cellDescr.Aggregates.Count > 0) descr.DisplayText = GetCaption(cell.Report, cellDescr.Aggregates[0].Expression); return descr; } private static HeaderDescriptor GetColumnDescriptor(TableCell cell) { AdvMatrixObject matrix = cell.Table as AdvMatrixObject; TableColumn column = matrix.Columns[cell.Address.X]; foreach (HeaderDescriptor d in matrix.Data.Columns.Descriptor.TerminalItems) { if (d.TemplateColumn == column) { if (d.IsGroup) return CreateSimpleHeader(cell, d); return d; } } return null; } private static HeaderDescriptor GetRowDescriptor(TableCell cell) { AdvMatrixObject matrix = cell.Table as AdvMatrixObject; TableRow row = matrix.Rows[cell.Address.Y]; foreach (HeaderDescriptor d in matrix.Data.Rows.Descriptor.TerminalItems) { if (d.TemplateRow == row) { if (d.IsGroup) return CreateSimpleHeader(cell, d); return d; } } return null; } private static void UpdateColumnCells(AdvMatrixObject matrix, HeaderDescriptor descr, TextObject text) { descr.DisplayText = GetCaption(matrix.Report, text.Text); matrix.BuildTemplate(); foreach (HeaderDescriptor d in matrix.Data.Rows.Descriptor.TerminalItems) { matrix[descr.TemplateColumn.Index, d.TemplateRow.Index].Text = "[Sum(" + text.Text + ")]"; matrix[descr.TemplateColumn.Index, d.TemplateRow.Index].Format = text.Format; } matrix.UpdateDescriptors(true); } private static void UpdateRowCells(AdvMatrixObject matrix, HeaderDescriptor descr, TextObject text) { descr.DisplayText = GetCaption(matrix.Report, text.Text); matrix.BuildTemplate(); foreach (HeaderDescriptor d in matrix.Data.Columns.Descriptor.TerminalItems) { matrix[d.TemplateColumn.Index, descr.TemplateRow.Index].Text = "[Sum(" + text.Text + ")]"; matrix[d.TemplateColumn.Index, descr.TemplateRow.Index].Format = text.Format; } matrix.UpdateDescriptors(true); } public static void InsertAfter(this TableCell cell, TextObject text) { HeaderDescriptor colDescr = GetColumnDescriptor(cell); if (colDescr != null) { HeaderDescriptor descr = colDescr.InsertAfter(new HeaderDescriptor()); UpdateColumnCells(cell.Matrix(), descr, text); } } public static void InsertBefore(this TableCell cell, TextObject text) { HeaderDescriptor colDescr = GetColumnDescriptor(cell); if (colDescr != null) { HeaderDescriptor descr = colDescr.InsertBefore(new HeaderDescriptor()); UpdateColumnCells(cell.Matrix(), descr, text); } } public static void InsertAbove(this TableCell cell, TextObject text) { HeaderDescriptor rowDescr = GetRowDescriptor(cell); if (rowDescr != null) { HeaderDescriptor descr = rowDescr.InsertBefore(new HeaderDescriptor()); UpdateRowCells(cell.Matrix(), descr, text); } } public static void InsertBelow(this TableCell cell, TextObject text) { HeaderDescriptor rowDescr = GetRowDescriptor(cell); if (rowDescr != null) { HeaderDescriptor descr = rowDescr.InsertAfter(new HeaderDescriptor()); UpdateRowCells(cell.Matrix(), descr, text); } } public static void InsertInside(this TableCell cell, TextObject text) { AdvMatrixObject matrix = cell.Matrix(); if (matrix.Data.Columns.Descriptor.Items.Count > 0) { HeaderDescriptor descr = matrix.Data.Columns.Descriptor.Items[0]; cell.Text = "[Sum(" + text.Text + ")]"; cell.Format = text.Format; if (descr.IsEmpty()) { descr.DisplayText = GetCaption(matrix.Report, text.Text); } matrix.BuildTemplate(); } } } }