CellExt.DesignExt.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. using System;
  2. using System.Windows.Forms;
  3. using FastReport.Table;
  4. using FastReport.Data;
  5. using FastReport.Controls;
  6. using FastReport.Utils;
  7. namespace FastReport.AdvMatrix
  8. {
  9. internal enum MatrixElement
  10. {
  11. None,
  12. Corner,
  13. Column,
  14. Row,
  15. Cell
  16. }
  17. // cell extension methods
  18. internal static partial class CellExt
  19. {
  20. internal static readonly string[] PercentNames = { "None", "PercentOfColumnTotal", "PercentOfRowTotal", "PercentOfGrandTotal", "PercentOfPreviousColumn", "PercentOfPreviousRow" };
  21. private static AdvMatrixObject Matrix(this TableCell cell)
  22. {
  23. return cell.Table as AdvMatrixObject;
  24. }
  25. internal static MatrixElement GetMatrixElement(this TableCell cell)
  26. {
  27. AdvMatrixObject matrix = cell.Matrix();
  28. int cornerWidth = matrix.Data.Rows.Size;
  29. int cornerHeight = matrix.Data.Columns.Size;
  30. if (cornerWidth == 0 && cornerHeight == 0)
  31. return MatrixElement.None;
  32. if (cell.Address.X < cornerWidth && cell.Address.Y < cornerHeight)
  33. return MatrixElement.Corner;
  34. if (cell.Address.X >= cornerWidth && cell.Address.Y < cornerHeight)
  35. return MatrixElement.Column;
  36. if (cell.Address.X < cornerWidth && cell.Address.Y >= cornerHeight)
  37. return MatrixElement.Row;
  38. return MatrixElement.Cell;
  39. }
  40. internal static HeaderDescriptor GetHeaderDescriptor(this TableCell cell)
  41. {
  42. AdvMatrixObject matrix = cell.Table as AdvMatrixObject;
  43. foreach (HeaderDescriptor d in matrix.Data.Columns.Descriptor.AllItems)
  44. {
  45. if (d.TemplateCell == cell)
  46. return d;
  47. }
  48. foreach (HeaderDescriptor d in matrix.Data.Rows.Descriptor.AllItems)
  49. {
  50. if (d.TemplateCell == cell)
  51. return d;
  52. }
  53. return null;
  54. }
  55. private static Column GetColumn(Report report, string text)
  56. {
  57. if (text.StartsWith("[") && text.EndsWith("]"))
  58. text = text.Substring(1, text.Length - 2);
  59. return DataHelper.GetColumn(report.Dictionary, text);
  60. }
  61. private static string GetCaption(Report report, string text)
  62. {
  63. Column c = GetColumn(report, text);
  64. if (c != null)
  65. return c.Alias;
  66. if (text.StartsWith("[") && text.EndsWith("]"))
  67. return text.Substring(1, text.Length - 2);
  68. return text;
  69. }
  70. internal static string GetDisplayText(this TableCell cell, string defaultText)
  71. {
  72. if (!cell.IsDesigning)
  73. return defaultText;
  74. MatrixElement el = cell.GetMatrixElement();
  75. if (el == MatrixElement.Cell)
  76. {
  77. CellDescriptor descr = cell.GetDescriptor();
  78. if (descr != null && descr.Aggregates.Count > 0)
  79. {
  80. string text = cell.Text;
  81. foreach (AggregateExpressionPair ag in descr.Aggregates)
  82. {
  83. Column c = GetColumn(cell.Report, ag.Expression);
  84. if (c != null)
  85. {
  86. while (text.Contains(ag.Expression))
  87. {
  88. text = text.Replace(ag.Expression, c.Alias);
  89. }
  90. }
  91. }
  92. return text;
  93. }
  94. }
  95. else if (el == MatrixElement.Column || el == MatrixElement.Row)
  96. {
  97. HeaderDescriptor descr = cell.GetHeaderDescriptor();
  98. if (descr != null)
  99. {
  100. Column c = GetColumn(cell.Report, descr.Expression);
  101. if (c != null)
  102. return "[" + c.Alias + "]";
  103. if (descr.IsGroup && !descr.Expression.StartsWith("["))
  104. return "[" + descr.Expression + "]";
  105. }
  106. }
  107. return defaultText;
  108. }
  109. private static TreeNode AddNode(string text, int imageIndex)
  110. {
  111. TreeNode node = new TreeNode(text);
  112. node.ImageIndex = imageIndex;
  113. node.SelectedImageIndex = imageIndex;
  114. return node;
  115. }
  116. internal static void ProvideMatrixItems(this TableCell cell, DataTreeView tree)
  117. {
  118. string name = cell.Table.Name;
  119. TreeNode matrixNode = AddNode(name, 142);
  120. tree.Nodes.Add(matrixNode);
  121. MatrixElement el = cell.GetMatrixElement();
  122. if (el == MatrixElement.Column || el == MatrixElement.Row)
  123. {
  124. TreeNode propertiesNode = AddNode(Res.Get("ComponentMenu,AdvMatrixCell,Properties"), 233);
  125. matrixNode.Nodes.Add(propertiesNode);
  126. propertiesNode.Nodes.Add(AddNode(name + ".RowNo", 224));
  127. propertiesNode.Nodes.Add(AddNode(name + ".ItemCount", 224));
  128. }
  129. else if (el == MatrixElement.Cell)
  130. {
  131. MyRes res = new MyRes("ComponentMenu,AdvMatrixCell");
  132. TreeNode aggregatesNode = AddNode(res.Get("AggregateFunctions"), 132);
  133. TreeNode specialFunctionsNode = AddNode(res.Get("SpecialFunctions"), 52);
  134. TreeNode propertiesNode = AddNode(res.Get("Properties"), 233);
  135. matrixNode.Nodes.Add(aggregatesNode);
  136. matrixNode.Nodes.Add(specialFunctionsNode);
  137. matrixNode.Nodes.Add(propertiesNode);
  138. foreach (string s in Aggregates.Names)
  139. {
  140. aggregatesNode.Nodes.Add(AddNode(s + "()", 132));
  141. }
  142. foreach (string s in ExpressionParser.SpecialFunctionNames)
  143. {
  144. specialFunctionsNode.Nodes.Add(AddNode(s + "()", 52));
  145. }
  146. propertiesNode.Nodes.Add(AddNode(name + ".ColumnIndex", 224));
  147. propertiesNode.Nodes.Add(AddNode(name + ".RowIndex", 224));
  148. propertiesNode.Nodes.Add(AddNode(name + ".ColumnValues[]", 233));
  149. propertiesNode.Nodes.Add(AddNode(name + ".RowValues[]", 233));
  150. }
  151. }
  152. public static void AddCollapseButton(this TableCell cell)
  153. {
  154. MatrixCollapseButton btn = new MatrixCollapseButton();
  155. btn.Parent = cell;
  156. btn.Width = 16;
  157. btn.SymbolSize = 5;
  158. btn.Dock = DockStyle.Left;
  159. btn.CreateUniqueName();
  160. cell.Padding = new Padding(16, 1, cell.GetSortButton() != null ? 16 : 2, 1);
  161. HeaderDescriptor descr = cell.GetHeaderDescriptor();
  162. if (descr != null)
  163. {
  164. if (descr.Items.Count == 0)
  165. descr = descr.Parent;
  166. foreach (HeaderDescriptor child in descr.Items)
  167. {
  168. if (child.IsGroup)
  169. child.VisibleToggledBy = btn.Name;
  170. }
  171. }
  172. }
  173. public static void AddSortButton(this TableCell cell)
  174. {
  175. MatrixSortButton btn = new MatrixSortButton();
  176. btn.Parent = cell;
  177. btn.Width = 16;
  178. btn.SymbolSize = 7;
  179. btn.Dock = DockStyle.Right;
  180. btn.CreateUniqueName();
  181. cell.Padding = new Padding(cell.GetCollapseButton() != null ? 16 : 2, 1, 16, 1);
  182. }
  183. public static void ChangeExpression(this TableCell cell, string expression)
  184. {
  185. CellDescriptor cellDescr = cell.GetDescriptor();
  186. if (expression == "")
  187. cell.Text = "";
  188. else if (cellDescr.Aggregates.Count == 1)
  189. {
  190. AggregateExpressionPair ag = cellDescr.Aggregates[0];
  191. if (ag.Expression != expression)
  192. {
  193. while (cell.Text.Contains(ag.Expression))
  194. {
  195. cell.Text = cell.Text.Replace(ag.Expression, expression);
  196. }
  197. }
  198. }
  199. else
  200. {
  201. cell.Text = "[Sum(" + expression + ")]";
  202. }
  203. }
  204. public static void ChangeAggregateFunction(this TableCell cell, string func)
  205. {
  206. CellDescriptor descr = cell.GetDescriptor();
  207. if (descr.Aggregates.Count == 1)
  208. {
  209. AggregateExpressionPair ag = descr.Aggregates[0];
  210. string oldFunc = ag.AggregateName + "(" + ag.Expression + ")";
  211. string newFunc = func + "(" + ag.Expression + ")";
  212. if (oldFunc != newFunc)
  213. {
  214. while (cell.Text.Contains(oldFunc))
  215. {
  216. cell.Text = cell.Text.Replace(oldFunc, newFunc);
  217. }
  218. }
  219. }
  220. }
  221. public static void ChangePercentFunction(this TableCell cell, string func)
  222. {
  223. CellDescriptor descr = cell.GetDescriptor();
  224. if (descr.ContentType == CellContentType.Aggregate)
  225. {
  226. AggregateExpressionPair ag = descr.Aggregates[0];
  227. if (func != "None")
  228. cell.Text = "[" + func + "(" + ag.AggregateName + "(" + ag.Expression + "))]";
  229. }
  230. else if (descr.ContentType == CellContentType.SingleExpression)
  231. {
  232. string text = cell.Text.Substring(1, cell.Text.Length - 2);
  233. foreach (string name in PercentNames)
  234. {
  235. if (text.StartsWith(name))
  236. {
  237. if (func == "None")
  238. cell.Text = "[" + text.Substring(name.Length + 1, text.Length - name.Length - 2) + "]";
  239. else
  240. cell.Text = "[" + func + text.Substring(name.Length) + "]";
  241. break;
  242. }
  243. }
  244. }
  245. }
  246. private static HeaderDescriptor CreateSimpleHeader(TableCell cell, HeaderDescriptor d)
  247. {
  248. HeaderDescriptor descr = d.InsertChild(new HeaderDescriptor());
  249. CellDescriptor cellDescr = cell.GetDescriptor();
  250. if (cellDescr.Aggregates.Count > 0)
  251. descr.DisplayText = GetCaption(cell.Report, cellDescr.Aggregates[0].Expression);
  252. return descr;
  253. }
  254. private static HeaderDescriptor GetColumnDescriptor(TableCell cell)
  255. {
  256. AdvMatrixObject matrix = cell.Table as AdvMatrixObject;
  257. TableColumn column = matrix.Columns[cell.Address.X];
  258. foreach (HeaderDescriptor d in matrix.Data.Columns.Descriptor.TerminalItems)
  259. {
  260. if (d.TemplateColumn == column)
  261. {
  262. if (d.IsGroup)
  263. return CreateSimpleHeader(cell, d);
  264. return d;
  265. }
  266. }
  267. return null;
  268. }
  269. private static HeaderDescriptor GetRowDescriptor(TableCell cell)
  270. {
  271. AdvMatrixObject matrix = cell.Table as AdvMatrixObject;
  272. TableRow row = matrix.Rows[cell.Address.Y];
  273. foreach (HeaderDescriptor d in matrix.Data.Rows.Descriptor.TerminalItems)
  274. {
  275. if (d.TemplateRow == row)
  276. {
  277. if (d.IsGroup)
  278. return CreateSimpleHeader(cell, d);
  279. return d;
  280. }
  281. }
  282. return null;
  283. }
  284. private static void UpdateColumnCells(AdvMatrixObject matrix, HeaderDescriptor descr, TextObject text)
  285. {
  286. descr.DisplayText = GetCaption(matrix.Report, text.Text);
  287. matrix.BuildTemplate();
  288. foreach (HeaderDescriptor d in matrix.Data.Rows.Descriptor.TerminalItems)
  289. {
  290. matrix[descr.TemplateColumn.Index, d.TemplateRow.Index].Text = "[Sum(" + text.Text + ")]";
  291. matrix[descr.TemplateColumn.Index, d.TemplateRow.Index].Format = text.Format;
  292. }
  293. matrix.UpdateDescriptors(true);
  294. }
  295. private static void UpdateRowCells(AdvMatrixObject matrix, HeaderDescriptor descr, TextObject text)
  296. {
  297. descr.DisplayText = GetCaption(matrix.Report, text.Text);
  298. matrix.BuildTemplate();
  299. foreach (HeaderDescriptor d in matrix.Data.Columns.Descriptor.TerminalItems)
  300. {
  301. matrix[d.TemplateColumn.Index, descr.TemplateRow.Index].Text = "[Sum(" + text.Text + ")]";
  302. matrix[d.TemplateColumn.Index, descr.TemplateRow.Index].Format = text.Format;
  303. }
  304. matrix.UpdateDescriptors(true);
  305. }
  306. public static void InsertAfter(this TableCell cell, TextObject text)
  307. {
  308. HeaderDescriptor colDescr = GetColumnDescriptor(cell);
  309. if (colDescr != null)
  310. {
  311. HeaderDescriptor descr = colDescr.InsertAfter(new HeaderDescriptor());
  312. UpdateColumnCells(cell.Matrix(), descr, text);
  313. }
  314. }
  315. public static void InsertBefore(this TableCell cell, TextObject text)
  316. {
  317. HeaderDescriptor colDescr = GetColumnDescriptor(cell);
  318. if (colDescr != null)
  319. {
  320. HeaderDescriptor descr = colDescr.InsertBefore(new HeaderDescriptor());
  321. UpdateColumnCells(cell.Matrix(), descr, text);
  322. }
  323. }
  324. public static void InsertAbove(this TableCell cell, TextObject text)
  325. {
  326. HeaderDescriptor rowDescr = GetRowDescriptor(cell);
  327. if (rowDescr != null)
  328. {
  329. HeaderDescriptor descr = rowDescr.InsertBefore(new HeaderDescriptor());
  330. UpdateRowCells(cell.Matrix(), descr, text);
  331. }
  332. }
  333. public static void InsertBelow(this TableCell cell, TextObject text)
  334. {
  335. HeaderDescriptor rowDescr = GetRowDescriptor(cell);
  336. if (rowDescr != null)
  337. {
  338. HeaderDescriptor descr = rowDescr.InsertAfter(new HeaderDescriptor());
  339. UpdateRowCells(cell.Matrix(), descr, text);
  340. }
  341. }
  342. public static void InsertInside(this TableCell cell, TextObject text)
  343. {
  344. AdvMatrixObject matrix = cell.Matrix();
  345. if (matrix.Data.Columns.Descriptor.Items.Count > 0)
  346. {
  347. HeaderDescriptor descr = matrix.Data.Columns.Descriptor.Items[0];
  348. cell.Text = "[Sum(" + text.Text + ")]";
  349. cell.Format = text.Format;
  350. if (descr.IsEmpty())
  351. {
  352. descr.DisplayText = GetCaption(matrix.Report, text.Text);
  353. }
  354. matrix.BuildTemplate();
  355. }
  356. }
  357. }
  358. }