using System; using System.Collections.Generic; using FastReport.Code; using FastReport.Utils; namespace FastReport.AdvMatrix { /// /// Represents the storage of header descriptors and its values. /// public class MatrixHeader : IFRSerializable { private AdvMatrixObject matrix; private string name; private int runningIndex; /// /// Gets the root header descriptor. /// public HeaderDescriptor Descriptor { get; private set; } /// /// Gets the size of this header. /// public int Size { get { return GetSize(Descriptor); } } internal HeaderData Data { get; private set; } internal int NextIndex { get { runningIndex++; return runningIndex; } } private void FillData(HeaderDescriptor descr, HeaderData data, List activeItems) { foreach (HeaderDescriptor d in descr.Items) { if (!String.IsNullOrEmpty(d.Filter)) { if ((dynamic)matrix.Report.Calc(d.Filter) == false) continue; } if (!String.IsNullOrEmpty(d.VisibleExpression)) { d.Visible = (dynamic)matrix.Report.Calc(d.VisibleExpression); } HeaderData dataItem = data.Add(d); activeItems.Add(dataItem); if (matrix.DataSource != null) dataItem.DataRowNo = matrix.DataSource.CurrentRowNo; // set index for the newly added items if (dataItem.Index == 0) dataItem.Index = NextIndex; if (d.SortAggregate != null) d.SortAggregate.ProcessDataRow(dataItem.Index, 0, matrix.Report.Calc(d.SortAggregate.Expression)); FillData(d, dataItem, activeItems); } } private int GetSize(HeaderDescriptor root) { int maxSize = -1; foreach (HeaderDescriptor d in root.Items) { int size = GetSize(d); if (size > maxSize) maxSize = size; } return maxSize + (root.Stepped && root.Items.Count > 0 ? 0 : 1); } private void GetExpressions(HeaderDescriptor root, List expressions) { foreach (HeaderDescriptor d in root.Items) { if (!String.IsNullOrEmpty(d.Expression)) expressions.Add(d.Expression); if (!String.IsNullOrEmpty(d.DisplayText)) expressions.AddRange(CodeUtils.GetExpressions(d.DisplayText, "[", "]")); if (!String.IsNullOrEmpty(d.Filter)) expressions.Add(d.Filter); if (!String.IsNullOrEmpty(d.VisibleExpression)) expressions.Add(d.VisibleExpression); if (d.SortAggregate != null) expressions.Add(d.SortAggregate.Expression); // we don't need to add InteractiveSortAggregate expression because it's a reference to existing cell aggregate GetExpressions(d, expressions); } } private void InitAggregates(HeaderDescriptor root) { root.InitAggregates(); foreach (HeaderDescriptor d in root.Items) { InitAggregates(d); } } internal void GetExpressions(List expressions) { InitAggregates(Descriptor); GetExpressions(Descriptor, expressions); } internal void Init() { runningIndex = 0; Data.Clear(); } internal List ProcessDataRow() { List activeItems = new List(); FillData(Descriptor, Data, activeItems); return activeItems; } /// public void Serialize(FRWriter writer) { writer.ItemName = name; // do not write root item foreach (HeaderDescriptor d in Descriptor.Items) writer.Write(d); } /// public void Deserialize(FRReader reader) { reader.Read(Descriptor); } internal void Assign(MatrixHeader src) { Descriptor = src.Descriptor; } /// /// Initializes a new instance of the class. /// public MatrixHeader(AdvMatrixObject matrix, string name) { this.matrix = matrix; this.name = name; Descriptor = new HeaderDescriptor(); Data = new HeaderData(null, null); } } }