HeaderDataList.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using System;
  2. using System.Collections.Generic;
  3. using FastReport.Table;
  4. namespace FastReport.AdvMatrix
  5. {
  6. internal class HeaderDataList : List<HeaderData>
  7. {
  8. private ValueComparer comparer;
  9. private HeaderData compareItem;
  10. public HeaderData Parent { get; private set; }
  11. public HeaderDescriptor Descriptor { get; private set; }
  12. public bool Visible { get; set; }
  13. private AdvMatrixObject Matrix { get { return Descriptor.Matrix; } }
  14. public int Find(object value)
  15. {
  16. if (Count == 0)
  17. return -1;
  18. compareItem.Value = value;
  19. if (Descriptor.Sort == SortOrder.None)
  20. {
  21. for (int i = 0; i < Count; i++)
  22. {
  23. if (comparer.Compare(compareItem, this[i]) == 0)
  24. return i;
  25. }
  26. return ~Count;
  27. }
  28. else
  29. {
  30. return BinarySearch(compareItem, comparer);
  31. }
  32. }
  33. public List<HeaderData> GetSortedList(bool useInteractiveSort = true)
  34. {
  35. InteractiveSortInfo info = Descriptor.Matrix.Data.InteractiveSort;
  36. if (Descriptor.InteractiveSort && useInteractiveSort &&
  37. ((Descriptor.IsColumn && info.Row.Sort != SortOrder.None) ||
  38. (!Descriptor.IsColumn && info.Column.Sort != SortOrder.None)))
  39. return SortByInteractiveInfo();
  40. else if (!String.IsNullOrEmpty(Descriptor.SortToggledBy) && useInteractiveSort)
  41. return SortByToggleButton();
  42. else if (Descriptor.SortAggregate != null)
  43. return SortByAggregateValue();
  44. else
  45. return this;
  46. }
  47. private List<HeaderData> SortByToggleButton()
  48. {
  49. List<HeaderData> list = new List<HeaderData>();
  50. list.AddRange(this);
  51. MatrixSortButton btn = Matrix.Report.FindObject(Descriptor.SortToggledBy) as MatrixSortButton;
  52. if (btn != null)
  53. list.Sort(new ValueComparer(btn.Sort));
  54. return list;
  55. }
  56. private List<HeaderData> SortByAggregateValue()
  57. {
  58. List<HeaderData> list = new List<HeaderData>();
  59. list.AddRange(this);
  60. list.Sort(new AggregateValueComparer(Descriptor));
  61. return list;
  62. }
  63. private List<HeaderData> SortByInteractiveInfo()
  64. {
  65. List<HeaderData> list = new List<HeaderData>();
  66. list.AddRange(this);
  67. InteractiveSortInfo.SortInfo info;
  68. TableCell cell;
  69. if (Descriptor.IsColumn)
  70. {
  71. info = Matrix.Data.InteractiveSort.Row;
  72. cell = Matrix[Descriptor.TemplateColumn.Index, info.Descriptor.TemplateRow.Index];
  73. }
  74. else
  75. {
  76. info = Matrix.Data.InteractiveSort.Column;
  77. cell = Matrix[info.Descriptor.TemplateColumn.Index, Descriptor.TemplateRow.Index];
  78. }
  79. AggregateExpressionPair aggr = Descriptor.InteractiveSortAggregate;
  80. if (aggr == null)
  81. {
  82. // no aggregate was set - use the first aggregate in a cell
  83. CellDescriptor cellDescriptor = cell.GetDescriptor();
  84. if (cellDescriptor.Aggregates.Count > 0)
  85. aggr = cellDescriptor.Aggregates[0];
  86. }
  87. if (aggr != null)
  88. list.Sort(new InteractiveComparer(aggr, info));
  89. return list;
  90. }
  91. public HeaderDataList(HeaderData parent, HeaderDescriptor descr)
  92. {
  93. Parent = parent;
  94. Descriptor = descr;
  95. Visible = descr.Visible;
  96. comparer = new ValueComparer(descr.Sort);
  97. compareItem = new HeaderData(null, null);
  98. }
  99. private class ValueComparer : IComparer<HeaderData>
  100. {
  101. private SortOrder sort;
  102. public int Compare(HeaderData x, HeaderData y)
  103. {
  104. int result = 0;
  105. IComparable i1 = x.Value as IComparable;
  106. IComparable i2 = y.Value as IComparable;
  107. if (i1 != null)
  108. result = i1.CompareTo(i2);
  109. else if (i2 != null)
  110. result = -1;
  111. if (sort == SortOrder.Descending)
  112. result = -result;
  113. return result;
  114. }
  115. public ValueComparer(SortOrder sort)
  116. {
  117. this.sort = sort;
  118. }
  119. }
  120. private class AggregateValueComparer : IComparer<HeaderData>
  121. {
  122. private HeaderDescriptor descriptor;
  123. private AggregateExpressionPair aggr;
  124. public int Compare(HeaderData x, HeaderData y)
  125. {
  126. int result = 0;
  127. IComparable i1 = aggr.GetValue(x.Index, 0) as IComparable;
  128. IComparable i2 = aggr.GetValue(y.Index, 0) as IComparable;
  129. if (i1 != null)
  130. result = i1.CompareTo(i2);
  131. else if (i2 != null)
  132. result = -1;
  133. if (descriptor.Sort == SortOrder.Descending)
  134. result = -result;
  135. return result;
  136. }
  137. public AggregateValueComparer(HeaderDescriptor descriptor)
  138. {
  139. this.descriptor = descriptor;
  140. aggr = descriptor.SortAggregate;
  141. }
  142. }
  143. private class InteractiveComparer : IComparer<HeaderData>
  144. {
  145. private AggregateExpressionPair aggr;
  146. private InteractiveSortInfo.SortInfo info;
  147. private object GetValue(HeaderData data)
  148. {
  149. if (info.IsColumn)
  150. return aggr.GetValue(info.Index, data.Index);
  151. else
  152. return aggr.GetValue(data.Index, info.Index);
  153. }
  154. public int Compare(HeaderData x, HeaderData y)
  155. {
  156. int result = 0;
  157. IComparable i1 = GetValue(x) as IComparable;
  158. IComparable i2 = GetValue(y) as IComparable;
  159. if (i1 != null)
  160. result = i1.CompareTo(i2);
  161. else if (i2 != null)
  162. result = -1;
  163. if (info.Sort == SortOrder.Descending)
  164. result = -result;
  165. return result;
  166. }
  167. public InteractiveComparer(AggregateExpressionPair aggr, InteractiveSortInfo.SortInfo info)
  168. {
  169. this.aggr = aggr;
  170. this.info = info;
  171. }
  172. }
  173. }
  174. }