using System; using System.Collections.Generic; using FastReport.Table; namespace FastReport.AdvMatrix { internal class HeaderDataList : List { private ValueComparer comparer; private HeaderData compareItem; public HeaderData Parent { get; private set; } public HeaderDescriptor Descriptor { get; private set; } public bool Visible { get; set; } private AdvMatrixObject Matrix { get { return Descriptor.Matrix; } } public int Find(object value) { if (Count == 0) return -1; compareItem.Value = value; if (Descriptor.Sort == SortOrder.None) { for (int i = 0; i < Count; i++) { if (comparer.Compare(compareItem, this[i]) == 0) return i; } return ~Count; } else { return BinarySearch(compareItem, comparer); } } public List GetSortedList(bool useInteractiveSort = true) { InteractiveSortInfo info = Descriptor.Matrix.Data.InteractiveSort; if (Descriptor.InteractiveSort && useInteractiveSort && ((Descriptor.IsColumn && info.Row.Sort != SortOrder.None) || (!Descriptor.IsColumn && info.Column.Sort != SortOrder.None))) return SortByInteractiveInfo(); else if (!String.IsNullOrEmpty(Descriptor.SortToggledBy) && useInteractiveSort) return SortByToggleButton(); else if (Descriptor.SortAggregate != null) return SortByAggregateValue(); else return this; } private List SortByToggleButton() { List list = new List(); list.AddRange(this); MatrixSortButton btn = Matrix.Report.FindObject(Descriptor.SortToggledBy) as MatrixSortButton; if (btn != null) list.Sort(new ValueComparer(btn.Sort)); return list; } private List SortByAggregateValue() { List list = new List(); list.AddRange(this); list.Sort(new AggregateValueComparer(Descriptor)); return list; } private List SortByInteractiveInfo() { List list = new List(); list.AddRange(this); InteractiveSortInfo.SortInfo info; TableCell cell; if (Descriptor.IsColumn) { info = Matrix.Data.InteractiveSort.Row; cell = Matrix[Descriptor.TemplateColumn.Index, info.Descriptor.TemplateRow.Index]; } else { info = Matrix.Data.InteractiveSort.Column; cell = Matrix[info.Descriptor.TemplateColumn.Index, Descriptor.TemplateRow.Index]; } AggregateExpressionPair aggr = Descriptor.InteractiveSortAggregate; if (aggr == null) { // no aggregate was set - use the first aggregate in a cell CellDescriptor cellDescriptor = cell.GetDescriptor(); if (cellDescriptor.Aggregates.Count > 0) aggr = cellDescriptor.Aggregates[0]; } if (aggr != null) list.Sort(new InteractiveComparer(aggr, info)); return list; } public HeaderDataList(HeaderData parent, HeaderDescriptor descr) { Parent = parent; Descriptor = descr; Visible = descr.Visible; comparer = new ValueComparer(descr.Sort); compareItem = new HeaderData(null, null); } private class ValueComparer : IComparer { private SortOrder sort; public int Compare(HeaderData x, HeaderData y) { int result = 0; IComparable i1 = x.Value as IComparable; IComparable i2 = y.Value as IComparable; if (i1 != null) result = i1.CompareTo(i2); else if (i2 != null) result = -1; if (sort == SortOrder.Descending) result = -result; return result; } public ValueComparer(SortOrder sort) { this.sort = sort; } } private class AggregateValueComparer : IComparer { private HeaderDescriptor descriptor; private AggregateExpressionPair aggr; public int Compare(HeaderData x, HeaderData y) { int result = 0; IComparable i1 = aggr.GetValue(x.Index, 0) as IComparable; IComparable i2 = aggr.GetValue(y.Index, 0) as IComparable; if (i1 != null) result = i1.CompareTo(i2); else if (i2 != null) result = -1; if (descriptor.Sort == SortOrder.Descending) result = -result; return result; } public AggregateValueComparer(HeaderDescriptor descriptor) { this.descriptor = descriptor; aggr = descriptor.SortAggregate; } } private class InteractiveComparer : IComparer { private AggregateExpressionPair aggr; private InteractiveSortInfo.SortInfo info; private object GetValue(HeaderData data) { if (info.IsColumn) return aggr.GetValue(info.Index, data.Index); else return aggr.GetValue(data.Index, info.Index); } public int Compare(HeaderData x, HeaderData y) { int result = 0; IComparable i1 = GetValue(x) as IComparable; IComparable i2 = GetValue(y) as IComparable; if (i1 != null) result = i1.CompareTo(i2); else if (i2 != null) result = -1; if (info.Sort == SortOrder.Descending) result = -result; return result; } public InteractiveComparer(AggregateExpressionPair aggr, InteractiveSortInfo.SortInfo info) { this.aggr = aggr; this.info = info; } } } }