MatrixHelper.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using FastReport.Data;
  5. using FastReport.Table;
  6. using FastReport.Utils;
  7. using System.Drawing;
  8. using System.Collections;
  9. namespace FastReport.Matrix
  10. {
  11. internal class MatrixHelper
  12. {
  13. private MatrixObject matrix;
  14. private int headerWidth;
  15. private int headerHeight;
  16. private int bodyWidth;
  17. private int bodyHeight;
  18. private bool designTime;
  19. private TableResult resultTable;
  20. private MatrixDescriptor titleDescriptor;
  21. private MatrixDescriptor cellHeaderDescriptor;
  22. private MatrixHeaderDescriptor noColumnsDescriptor;
  23. private MatrixHeaderDescriptor noRowsDescriptor;
  24. private MatrixCellDescriptor noCellsDescriptor;
  25. private object[] cellValues;
  26. private int[] evenStyleIndices;
  27. private bool noColumns;
  28. private bool noRows;
  29. #region Properties
  30. public MatrixObject Matrix
  31. {
  32. get { return matrix; }
  33. }
  34. public Report Report
  35. {
  36. get { return Matrix.Report; }
  37. }
  38. public TableResult ResultTable
  39. {
  40. get { return designTime ? resultTable : Matrix.ResultTable; }
  41. }
  42. public int HeaderHeight
  43. {
  44. get { return headerHeight; }
  45. }
  46. public int HeaderWidth
  47. {
  48. get { return headerWidth; }
  49. }
  50. public int BodyWidth
  51. {
  52. get { return bodyWidth; }
  53. }
  54. public int BodyHeight
  55. {
  56. get { return bodyHeight; }
  57. }
  58. public object[] CellValues
  59. {
  60. get { return cellValues; }
  61. }
  62. #endregion
  63. #region Private Methods
  64. private string ExtractColumnName(string complexName)
  65. {
  66. if (complexName.StartsWith("[") && complexName.EndsWith("]"))
  67. complexName = complexName.Substring(1, complexName.Length - 2);
  68. if (Report == null)
  69. return complexName;
  70. Column column = DataHelper.GetColumn(Report.Dictionary, complexName);
  71. if (column == null)
  72. return complexName;
  73. return column.Alias;
  74. }
  75. /// <summary>
  76. /// Updates HeaderWidth, HeaderHeight, BodyWidth, BodyHeight properties.
  77. /// </summary>
  78. private void UpdateTemplateSizes()
  79. {
  80. headerWidth = Matrix.Data.Rows.Count;
  81. if (headerWidth == 0)
  82. headerWidth = 1;
  83. if (Matrix.Data.Cells.Count > 1 && !Matrix.CellsSideBySide)
  84. headerWidth++;
  85. headerHeight = Matrix.Data.Columns.Count;
  86. if (headerHeight == 0)
  87. headerHeight = 1;
  88. if (Matrix.Data.Cells.Count > 1 && Matrix.CellsSideBySide)
  89. headerHeight++;
  90. if (Matrix.ShowTitle)
  91. headerHeight++;
  92. bodyWidth = 1;
  93. foreach (MatrixHeaderDescriptor descr in Matrix.Data.Columns)
  94. {
  95. if (descr.Totals)
  96. bodyWidth++;
  97. }
  98. if (Matrix.CellsSideBySide && Matrix.Data.Cells.Count > 1)
  99. bodyWidth *= Matrix.Data.Cells.Count;
  100. bodyHeight = 1;
  101. foreach (MatrixHeaderDescriptor descr in Matrix.Data.Rows)
  102. {
  103. if (descr.Totals)
  104. bodyHeight++;
  105. }
  106. if (!Matrix.CellsSideBySide && Matrix.Data.Cells.Count > 1)
  107. bodyHeight *= Matrix.Data.Cells.Count;
  108. }
  109. private void UpdateColumnDescriptors()
  110. {
  111. int left = HeaderWidth;
  112. int top = 0;
  113. int width = BodyWidth;
  114. int dataWidth = 1;
  115. if (Matrix.Data.Cells.Count > 1 && Matrix.CellsSideBySide)
  116. dataWidth = Matrix.Data.Cells.Count;
  117. if (Matrix.ShowTitle)
  118. top++;
  119. foreach (MatrixHeaderDescriptor descr in Matrix.Data.Columns)
  120. {
  121. if (descr.Totals)
  122. {
  123. descr.TemplateTotalColumn = Matrix.Columns[left + width - dataWidth];
  124. descr.TemplateTotalRow = Matrix.Rows[top];
  125. descr.TemplateTotalCell = Matrix[left + width - dataWidth, top];
  126. width -= dataWidth;
  127. }
  128. else
  129. {
  130. descr.TemplateTotalColumn = null;
  131. descr.TemplateTotalRow = null;
  132. descr.TemplateTotalCell = null;
  133. }
  134. descr.TemplateColumn = Matrix.Columns[left];
  135. descr.TemplateRow = Matrix.Rows[top];
  136. descr.TemplateCell = Matrix[left, top];
  137. top++;
  138. }
  139. }
  140. private void UpdateRowDescriptors()
  141. {
  142. int left = 0;
  143. int top = HeaderHeight;
  144. int height = BodyHeight;
  145. int dataHeight = 1;
  146. if (Matrix.Data.Cells.Count > 1 && !Matrix.CellsSideBySide)
  147. dataHeight = Matrix.Data.Cells.Count;
  148. foreach (MatrixHeaderDescriptor descr in Matrix.Data.Rows)
  149. {
  150. if (descr.Totals)
  151. {
  152. descr.TemplateTotalColumn = Matrix.Columns[left];
  153. descr.TemplateTotalRow = Matrix.Rows[top + height - dataHeight];
  154. descr.TemplateTotalCell = Matrix[left, top + height - dataHeight];
  155. height -= dataHeight;
  156. }
  157. else
  158. {
  159. descr.TemplateTotalColumn = null;
  160. descr.TemplateTotalRow = null;
  161. descr.TemplateTotalCell = null;
  162. }
  163. descr.TemplateColumn = Matrix.Columns[left];
  164. descr.TemplateRow = Matrix.Rows[top];
  165. descr.TemplateCell = Matrix[left, top];
  166. left++;
  167. }
  168. }
  169. private void UpdateCellDescriptors()
  170. {
  171. int x = HeaderWidth;
  172. int y = HeaderHeight;
  173. foreach (MatrixCellDescriptor descr in Matrix.Data.Cells)
  174. {
  175. descr.TemplateColumn = Matrix.Columns[x];
  176. descr.TemplateRow = Matrix.Rows[y];
  177. descr.TemplateCell = Matrix[x, y];
  178. if (Matrix.CellsSideBySide)
  179. x++;
  180. else
  181. y++;
  182. }
  183. }
  184. private void UpdateOtherDescriptors()
  185. {
  186. titleDescriptor.TemplateColumn = null;
  187. titleDescriptor.TemplateRow = null;
  188. titleDescriptor.TemplateCell = null;
  189. if (Matrix.ShowTitle)
  190. {
  191. titleDescriptor.TemplateColumn = Matrix.Columns[HeaderWidth];
  192. titleDescriptor.TemplateRow = Matrix.Rows[0];
  193. titleDescriptor.TemplateCell = Matrix[HeaderWidth, 0];
  194. }
  195. cellHeaderDescriptor.TemplateColumn = null;
  196. cellHeaderDescriptor.TemplateRow = null;
  197. cellHeaderDescriptor.TemplateCell = null;
  198. if (Matrix.Data.Cells.Count > 1)
  199. {
  200. if (Matrix.CellsSideBySide)
  201. {
  202. cellHeaderDescriptor.TemplateColumn = Matrix.Columns[HeaderWidth];
  203. cellHeaderDescriptor.TemplateRow = Matrix.Rows[HeaderHeight - 1];
  204. }
  205. else
  206. {
  207. cellHeaderDescriptor.TemplateColumn = Matrix.Columns[HeaderWidth - 1];
  208. cellHeaderDescriptor.TemplateRow = Matrix.Rows[HeaderHeight];
  209. }
  210. }
  211. }
  212. private void ApplyStyle(TableCell cell, string styleName)
  213. {
  214. Style style = null;
  215. int styleIndex = Matrix.StyleSheet.IndexOf(Matrix.Style);
  216. if (styleIndex != -1)
  217. {
  218. StyleCollection styles = Matrix.StyleSheet[styleIndex];
  219. style = styles[styles.IndexOf(styleName)];
  220. }
  221. if (style != null)
  222. cell.ApplyStyle(style);
  223. }
  224. private TableCell CreateCell(string text)
  225. {
  226. TableCell cell = new TableCell();
  227. cell.Font = DrawUtils.DefaultReportFont;
  228. cell.Text = text;
  229. cell.HorzAlign = HorzAlign.Center;
  230. cell.VertAlign = VertAlign.Center;
  231. ApplyStyle(cell, "Header");
  232. return cell;
  233. }
  234. private TableCell CreateDataCell()
  235. {
  236. TableCell cell = new TableCell();
  237. cell.Font = DrawUtils.DefaultReportFont;
  238. cell.HorzAlign = HorzAlign.Right;
  239. cell.VertAlign = VertAlign.Center;
  240. ApplyStyle(cell, "Body");
  241. return cell;
  242. }
  243. private void SetHint(TableCell cell, string text)
  244. {
  245. cell.Assign(Matrix.Styles.DefaultStyle);
  246. cell.Text = text;
  247. cell.Font = DrawUtils.DefaultReportFont;
  248. cell.TextFill = new SolidFill(Color.Gray);
  249. cell.HorzAlign = HorzAlign.Center;
  250. cell.VertAlign = VertAlign.Center;
  251. cell.SetFlags(Flags.CanEdit, false);
  252. }
  253. private Point GetBodyLocation()
  254. {
  255. // determine the template's body location. Do not rely on HeaderWidth, HeaderHeight -
  256. // the template may be empty
  257. Point result = new Point();
  258. foreach (MatrixHeaderDescriptor descr in Matrix.Data.Columns)
  259. {
  260. if (descr.TemplateColumn != null)
  261. result.X = descr.TemplateColumn.Index;
  262. }
  263. foreach (MatrixHeaderDescriptor descr in Matrix.Data.Rows)
  264. {
  265. if (descr.TemplateRow != null)
  266. result.Y = descr.TemplateRow.Index;
  267. }
  268. return result;
  269. }
  270. private void InitResultTable(bool isTemplate)
  271. {
  272. Matrix.Data.Columns.AddTotalItems(isTemplate);
  273. Matrix.Data.Rows.AddTotalItems(isTemplate);
  274. List<MatrixHeaderItem> columnTerminalItems = Matrix.Data.Columns.RootItem.GetTerminalItems();
  275. List<MatrixHeaderItem> rowTerminalItems = Matrix.Data.Rows.RootItem.GetTerminalItems();
  276. // create corner
  277. List<MatrixDescriptor> descrList = new List<MatrixDescriptor>();
  278. if (Matrix.ShowTitle)
  279. descrList.Add(titleDescriptor);
  280. descrList.AddRange(Matrix.Data.Columns.ToArray());
  281. if (Matrix.Data.Cells.Count > 1 && Matrix.CellsSideBySide)
  282. descrList.Add(cellHeaderDescriptor);
  283. foreach (MatrixDescriptor descr in descrList)
  284. {
  285. TableRow row = new TableRow();
  286. if (descr.TemplateRow != null)
  287. row.Assign(descr.TemplateRow);
  288. ResultTable.Rows.Add(row);
  289. }
  290. descrList.Clear();
  291. descrList.AddRange(Matrix.Data.Rows.ToArray());
  292. if (Matrix.Data.Cells.Count > 1 && !Matrix.CellsSideBySide)
  293. descrList.Add(cellHeaderDescriptor);
  294. foreach (MatrixDescriptor descr in descrList)
  295. {
  296. TableColumn column = new TableColumn();
  297. if (descr.TemplateColumn != null)
  298. column.Assign(descr.TemplateColumn);
  299. ResultTable.Columns.Add(column);
  300. }
  301. // determine the body location
  302. Point bodyLocation = GetBodyLocation();
  303. // create columns
  304. foreach (MatrixHeaderItem item in columnTerminalItems)
  305. {
  306. foreach (MatrixCellDescriptor descr in Matrix.Data.Cells)
  307. {
  308. TableColumn column = new TableColumn();
  309. if (item.TemplateColumn != null && descr.TemplateColumn != null)
  310. column.Assign(Matrix.Columns[item.TemplateColumn.Index + (descr.TemplateColumn.Index - bodyLocation.X)]);
  311. ResultTable.Columns.Add(column);
  312. if (!Matrix.CellsSideBySide)
  313. break;
  314. }
  315. }
  316. // create rows
  317. foreach (MatrixHeaderItem item in rowTerminalItems)
  318. {
  319. foreach (MatrixCellDescriptor descr in Matrix.Data.Cells)
  320. {
  321. TableRow row = new TableRow();
  322. if (item.TemplateRow != null && descr.TemplateRow != null)
  323. row.Assign(Matrix.Rows[item.TemplateRow.Index + (descr.TemplateRow.Index - bodyLocation.Y)]);
  324. ResultTable.Rows.Add(row);
  325. if (Matrix.CellsSideBySide)
  326. break;
  327. }
  328. }
  329. }
  330. private void PrintHeaderCell(MatrixHeaderItem item, TableCellData resultCell, bool isEven)
  331. {
  332. TableCell templateCell = item.TemplateCell;
  333. if (templateCell != null)
  334. {
  335. if (designTime)
  336. {
  337. if (!item.IsTotal)
  338. templateCell.Text = item.Value.ToString();
  339. resultCell.RunTimeAssign(templateCell, true);
  340. }
  341. else
  342. {
  343. if (Matrix.DataSource != null)
  344. Matrix.DataSource.CurrentRowNo = item.DataRowNo;
  345. templateCell.SetValue(item.Value);
  346. if (!item.IsTotal)
  347. templateCell.Text = templateCell.Format.FormatValue(item.Value);
  348. templateCell.SaveState();
  349. if (isEven)
  350. templateCell.ApplyEvenStyle();
  351. templateCell.GetData();
  352. if (String.IsNullOrEmpty(templateCell.Hyperlink.Expression) &&
  353. (templateCell.Hyperlink.Kind == HyperlinkKind.DetailReport ||
  354. templateCell.Hyperlink.Kind == HyperlinkKind.DetailPage ||
  355. templateCell.Hyperlink.Kind == HyperlinkKind.Custom))
  356. templateCell.Hyperlink.Value = templateCell.Text;
  357. resultCell.RunTimeAssign(templateCell, true);
  358. templateCell.RestoreState();
  359. }
  360. }
  361. else
  362. {
  363. templateCell = CreateCell(item.IsTotal ? Res.Get("ComponentsMisc,Matrix,Total") : item.Value.ToString());
  364. resultCell.RunTimeAssign(templateCell, true);
  365. }
  366. }
  367. private void PrintColumnHeader(MatrixHeaderItem root, int left, int top, int level)
  368. {
  369. int dataWidth = 1;
  370. int height = HeaderHeight;
  371. if (Matrix.Data.Cells.Count > 1 && Matrix.CellsSideBySide)
  372. {
  373. dataWidth = Matrix.Data.Cells.Count;
  374. height--;
  375. }
  376. foreach (MatrixHeaderItem item in root.Items)
  377. {
  378. Matrix.ColumnValues = item.Values;
  379. TableCellData resultCell = ResultTable.GetCellData(left, top);
  380. int span = item.Span * dataWidth;
  381. int dy = 1;
  382. if (item.IsTotal)
  383. {
  384. dy = height - top;
  385. // correct evenStyleIndices
  386. for (int i = level + 1; i < evenStyleIndices.Length; i++)
  387. evenStyleIndices[i]++;
  388. }
  389. PrintHeaderCell(item, resultCell, evenStyleIndices[level] % 2 != 0);
  390. PrintColumnHeader(item, left, top + dy, level + 1);
  391. if (item.PageBreak && left > HeaderWidth)
  392. ResultTable.Columns[left].PageBreak = true;
  393. left += span;
  394. evenStyleIndices[level]++;
  395. // set spans after we have printed the cell. This will handle the cell internal objects layout correctly
  396. resultCell.ColSpan = span;
  397. if (item.IsTotal)
  398. {
  399. resultCell.RowSpan = height - top;
  400. }
  401. }
  402. // print cell header
  403. if (root.Items.Count == 0 && dataWidth > 1)
  404. {
  405. foreach (MatrixCellDescriptor descr in Matrix.Data.Cells)
  406. {
  407. TableCell templateCell = null;
  408. TableCellData resultCell = ResultTable.GetCellData(left, top);
  409. if (root.TemplateColumn != null && descr.TemplateColumn != null &&
  410. cellHeaderDescriptor.TemplateColumn != null && cellHeaderDescriptor.TemplateRow != null)
  411. {
  412. templateCell = Matrix[
  413. root.TemplateColumn.Index + (descr.TemplateColumn.Index - cellHeaderDescriptor.TemplateColumn.Index),
  414. cellHeaderDescriptor.TemplateRow.Index];
  415. }
  416. else
  417. templateCell = CreateCell(ExtractColumnName(descr.Expression));
  418. templateCell.SaveState();
  419. templateCell.GetData();
  420. resultCell.RunTimeAssign(templateCell, true);
  421. templateCell.RestoreState();
  422. left++;
  423. }
  424. }
  425. }
  426. private void PrintColumnHeader()
  427. {
  428. Matrix.RowValues = null;
  429. evenStyleIndices = new int[Matrix.Data.Columns.Count];
  430. PrintColumnHeader(Matrix.Data.Columns.RootItem, HeaderWidth, Matrix.ShowTitle ? 1 : 0, 0);
  431. }
  432. private void PrintRowHeader(MatrixHeaderItem root, int left, int top, int level)
  433. {
  434. int dataHeight = 1;
  435. int width = HeaderWidth;
  436. if (Matrix.Data.Cells.Count > 1 && !Matrix.CellsSideBySide)
  437. {
  438. dataHeight = Matrix.Data.Cells.Count;
  439. width--;
  440. }
  441. for (int index = 0; index < root.Items.Count; index++)
  442. {
  443. MatrixHeaderItem item = root.Items[index];
  444. Matrix.RowValues = item.Values;
  445. TableCellData resultCell = ResultTable.GetCellData(left, top);
  446. int span = item.Span * dataHeight;
  447. if (Matrix.SplitRows)
  448. {
  449. MatrixHeaderItem duplicate = new MatrixHeaderItem(root);
  450. duplicate.IsSplitted = true;
  451. duplicate.Value = item.Value;
  452. duplicate.TemplateRow = item.TemplateRow;
  453. duplicate.TemplateCell = item.TemplateCell;
  454. duplicate.TemplateColumn = item.TemplateColumn;
  455. for (int i = 1; i < span; i++)
  456. {
  457. root.Items.Insert(index + 1, duplicate);
  458. }
  459. span = 1;
  460. }
  461. int dx = 1;
  462. if (item.IsTotal)
  463. {
  464. dx = width - left;
  465. // correct evenStyleIndices
  466. for (int i = level + 1; i < evenStyleIndices.Length; i++)
  467. evenStyleIndices[i]++;
  468. }
  469. PrintHeaderCell(item, resultCell, evenStyleIndices[level] % 2 != 0);
  470. PrintRowHeader(item, left + dx, top, level + 1);
  471. if (item.PageBreak && top > HeaderHeight)
  472. ResultTable.Rows[top].PageBreak = true;
  473. top += span;
  474. evenStyleIndices[level]++;
  475. // set spans after we have printed the cell. This will handle the cell internal objects layout correctly
  476. resultCell.RowSpan = span;
  477. if (item.IsTotal)
  478. {
  479. resultCell.ColSpan = width - left;
  480. }
  481. }
  482. // print cell header
  483. if (root.Items.Count == 0 && dataHeight > 1)
  484. {
  485. foreach (MatrixCellDescriptor descr in Matrix.Data.Cells)
  486. {
  487. TableCell templateCell = null;
  488. TableCellData resultCell = ResultTable.GetCellData(left, top);
  489. if (root.TemplateRow != null && descr.TemplateRow != null &&
  490. cellHeaderDescriptor.TemplateColumn != null && cellHeaderDescriptor.TemplateRow != null)
  491. {
  492. templateCell = Matrix[cellHeaderDescriptor.TemplateColumn.Index,
  493. root.TemplateRow.Index + (descr.TemplateRow.Index - cellHeaderDescriptor.TemplateRow.Index)];
  494. }
  495. else
  496. templateCell = CreateCell(ExtractColumnName(descr.Expression));
  497. templateCell.SaveState();
  498. templateCell.GetData();
  499. resultCell.RunTimeAssign(templateCell, true);
  500. templateCell.RestoreState();
  501. top++;
  502. }
  503. }
  504. }
  505. private void PrintRowHeader()
  506. {
  507. Matrix.ColumnValues = null;
  508. evenStyleIndices = new int[Matrix.Data.Rows.Count];
  509. PrintRowHeader(Matrix.Data.Rows.RootItem, 0, HeaderHeight, 0);
  510. }
  511. private void PrintCorner()
  512. {
  513. List<MatrixDescriptor> rowDescr = new List<MatrixDescriptor>();
  514. List<MatrixDescriptor> colDescr = new List<MatrixDescriptor>();
  515. rowDescr.AddRange(Matrix.Data.Rows.ToArray());
  516. colDescr.AddRange(Matrix.Data.Columns.ToArray());
  517. if (Matrix.Data.Cells.Count > 1)
  518. {
  519. if (Matrix.CellsSideBySide)
  520. colDescr.Add(cellHeaderDescriptor);
  521. else
  522. rowDescr.Add(cellHeaderDescriptor);
  523. }
  524. int top = 0;
  525. bool firstRow = true;
  526. foreach (MatrixDescriptor col in colDescr)
  527. {
  528. int left = 0;
  529. foreach (MatrixDescriptor row in rowDescr)
  530. {
  531. TableCell templateCell = null;
  532. if (row.TemplateColumn != null && col.TemplateRow != null)
  533. templateCell = Matrix[row.TemplateColumn.Index, col.TemplateRow.Index];
  534. else if (firstRow)
  535. templateCell = CreateCell(ExtractColumnName(row.Expression));
  536. if (templateCell != null)
  537. {
  538. TableCellData resultCell = ResultTable.GetCellData(left, top + (Matrix.ShowTitle ? 1 : 0));
  539. templateCell.SaveState();
  540. if (!designTime)
  541. templateCell.GetData();
  542. resultCell.RunTimeAssign(templateCell, true);
  543. templateCell.RestoreState();
  544. // do not allow spans to go outside corner area
  545. resultCell.ColSpan = Math.Min(templateCell.ColSpan, rowDescr.Count - left);
  546. resultCell.RowSpan = Math.Min(templateCell.RowSpan, colDescr.Count - top);
  547. }
  548. left++;
  549. }
  550. firstRow = false;
  551. top++;
  552. }
  553. }
  554. private void PrintTitle()
  555. {
  556. TableCell templateCell = titleDescriptor.TemplateCell;
  557. if (titleDescriptor.TemplateCell == null)
  558. templateCell = CreateCell(Res.Get("ComponentsMisc,Matrix,Title"));
  559. TableCellData resultCell = ResultTable.GetCellData(HeaderWidth, 0);
  560. templateCell.SaveState();
  561. if (!designTime)
  562. templateCell.GetData();
  563. resultCell.RunTimeAssign(templateCell, true);
  564. resultCell.ColSpan = ResultTable.ColumnCount - HeaderWidth;
  565. templateCell.RestoreState();
  566. // print left-top cell
  567. if (titleDescriptor.TemplateCell == null)
  568. templateCell.Text = "";
  569. else
  570. templateCell = Matrix[0, 0];
  571. resultCell = ResultTable.GetCellData(0, 0);
  572. templateCell.SaveState();
  573. if (!designTime)
  574. templateCell.GetData();
  575. resultCell.RunTimeAssign(templateCell, true);
  576. templateCell.RestoreState();
  577. resultCell.ColSpan = HeaderWidth;
  578. }
  579. private void PrintHeaders()
  580. {
  581. PrintColumnHeader();
  582. PrintRowHeader();
  583. if (Matrix.ShowTitle)
  584. PrintTitle();
  585. PrintCorner();
  586. }
  587. private void PrintData_CalcTotals(int pass)
  588. {
  589. List<MatrixHeaderItem> columnTerminalItems = Matrix.Data.Columns.RootItem.GetTerminalItems();
  590. List<MatrixHeaderItem> rowTerminalItems = Matrix.Data.Rows.RootItem.GetTerminalItems();
  591. int dataCount = Matrix.Data.Cells.Count;
  592. cellValues = new object[dataCount];
  593. foreach (MatrixHeaderItem rowItem in rowTerminalItems)
  594. {
  595. foreach (MatrixHeaderItem columnItem in columnTerminalItems)
  596. {
  597. if ((pass == 1 && !(rowItem.IsTotal || columnItem.IsTotal)) ||
  598. (pass == 2 && (rowItem.IsTotal || columnItem.IsTotal)))
  599. continue;
  600. // at first we calc cells with non-custom functions
  601. // prepare FCellValues array which will be used when calculating custom functions
  602. for (int cellIndex = 0; cellIndex < dataCount; cellIndex++)
  603. {
  604. if (Matrix.Data.Cells[cellIndex].Function != MatrixAggregateFunction.Custom)
  605. cellValues[cellIndex] = GetCellValue(columnItem, rowItem, cellIndex);
  606. }
  607. // at second we calc cells with custom functions
  608. // (to allow the custom function to use other cells' values)
  609. for (int cellIndex = 0; cellIndex < dataCount; cellIndex++)
  610. {
  611. if (Matrix.Data.Cells[cellIndex].Function == MatrixAggregateFunction.Custom)
  612. cellValues[cellIndex] = GetCellValue(columnItem, rowItem, cellIndex);
  613. }
  614. Matrix.Data.Cells.SetValues(columnItem.Index, rowItem.Index, cellValues);
  615. }
  616. }
  617. }
  618. private void PrintData_CalcPercents()
  619. {
  620. int dataCount = Matrix.Data.Cells.Count;
  621. // check if we need to do this
  622. bool hasPercents = false;
  623. for (int cellIndex = 0; cellIndex < dataCount; cellIndex++)
  624. {
  625. if (Matrix.Data.Cells[cellIndex].Percent != MatrixPercent.None)
  626. hasPercents = true;
  627. }
  628. if (!hasPercents)
  629. return;
  630. List<MatrixHeaderItem> columnTerminalItems = Matrix.Data.Columns.RootItem.GetTerminalItems();
  631. List<MatrixHeaderItem> rowTerminalItems = Matrix.Data.Rows.RootItem.GetTerminalItems();
  632. cellValues = new object[dataCount];
  633. foreach (MatrixHeaderItem rowItem in rowTerminalItems)
  634. {
  635. foreach (MatrixHeaderItem columnItem in columnTerminalItems)
  636. {
  637. for (int cellIndex = 0; cellIndex < dataCount; cellIndex++)
  638. {
  639. object cellValue = Matrix.Data.Cells.GetValue(columnItem.Index, rowItem.Index, cellIndex);
  640. object totalValue = null;
  641. object value = null;
  642. int totalColumnIndex = Matrix.Data.Columns[0].TotalsFirst ? 0 : columnTerminalItems.Count - 1;
  643. int totalRowIndex = Matrix.Data.Rows[0].TotalsFirst ? 0 : rowTerminalItems.Count - 1;
  644. switch (Matrix.Data.Cells[cellIndex].Percent)
  645. {
  646. case MatrixPercent.None:
  647. value = cellValue;
  648. break;
  649. case MatrixPercent.ColumnTotal:
  650. totalValue = Matrix.Data.Cells.GetValue(columnTerminalItems[totalColumnIndex].Index, rowItem.Index, cellIndex);
  651. break;
  652. case MatrixPercent.RowTotal:
  653. totalValue = Matrix.Data.Cells.GetValue(columnItem.Index, rowTerminalItems[totalRowIndex].Index, cellIndex);
  654. break;
  655. case MatrixPercent.GrandTotal:
  656. totalValue = Matrix.Data.Cells.GetValue(columnTerminalItems[totalColumnIndex].Index, rowTerminalItems[totalRowIndex].Index, cellIndex);
  657. break;
  658. }
  659. if (cellValue != null && totalValue != null)
  660. value = ((Variant)(new Variant(cellValue) / new Variant(totalValue))).Value;
  661. cellValues[cellIndex] = value;
  662. }
  663. Matrix.Data.Cells.SetValues(columnItem.Index, rowItem.Index, cellValues);
  664. }
  665. }
  666. }
  667. private void PrintData()
  668. {
  669. // use two passes to calc cell values. This is necessary because this calculation
  670. // replaces an array of cell values by the single (aggregated) value.
  671. // At the first pass we calc total values only (so they include all cell values, not aggregated ones);
  672. // at the second pass we calc other values except total.
  673. PrintData_CalcTotals(1);
  674. PrintData_CalcTotals(2);
  675. // calc percents
  676. PrintData_CalcPercents();
  677. // fire AfterTotals event
  678. Matrix.OnAfterTotals(EventArgs.Empty);
  679. List<MatrixHeaderItem> columnTerminalItems = Matrix.Data.Columns.RootItem.GetTerminalItems();
  680. List<MatrixHeaderItem> rowTerminalItems = Matrix.Data.Rows.RootItem.GetTerminalItems();
  681. int dataCount = Matrix.Data.Cells.Count;
  682. int top = HeaderHeight;
  683. Point bodyLocation = GetBodyLocation();
  684. bool firstTimePrintingData = true;
  685. cellValues = new object[dataCount];
  686. Matrix.RowIndex = 0;
  687. foreach (MatrixHeaderItem rowItem in rowTerminalItems)
  688. {
  689. int left = HeaderWidth;
  690. Matrix.RowValues = rowItem.Values;
  691. Matrix.ColumnIndex = 0;
  692. foreach (MatrixHeaderItem columnItem in columnTerminalItems)
  693. {
  694. Matrix.ColumnValues = columnItem.Values;
  695. for (int cellIndex = 0; cellIndex < dataCount; cellIndex++)
  696. {
  697. TableCell templateCell = null;
  698. TableCellData resultCell = null;
  699. MatrixCellDescriptor descr = Matrix.Data.Cells[cellIndex];
  700. if (Matrix.CellsSideBySide)
  701. {
  702. if (columnItem.TemplateColumn != null && rowItem.TemplateRow != null && descr.TemplateColumn != null)
  703. {
  704. templateCell = Matrix[
  705. columnItem.TemplateColumn.Index + (descr.TemplateColumn.Index - bodyLocation.X),
  706. rowItem.TemplateRow.Index];
  707. }
  708. else
  709. templateCell = CreateDataCell();
  710. resultCell = ResultTable.GetCellData(left + cellIndex, top);
  711. }
  712. else
  713. {
  714. if (columnItem.TemplateColumn != null && rowItem.TemplateRow != null && descr.TemplateColumn != null)
  715. {
  716. templateCell = Matrix[columnItem.TemplateColumn.Index,
  717. rowItem.TemplateRow.Index + (descr.TemplateRow.Index - bodyLocation.Y)];
  718. }
  719. else
  720. templateCell = CreateDataCell();
  721. resultCell = ResultTable.GetCellData(left, top + cellIndex);
  722. }
  723. if (designTime)
  724. {
  725. if (firstTimePrintingData)
  726. templateCell.Text = "[" + ExtractColumnName(descr.Expression) + "]";
  727. else
  728. templateCell.Text = "";
  729. resultCell.RunTimeAssign(templateCell, true);
  730. }
  731. else
  732. {
  733. object value = Matrix.Data.GetValue(columnItem.Index, rowItem.Index, cellIndex);
  734. cellValues[cellIndex] = value;
  735. templateCell.Text = templateCell.FormatValue(value);
  736. templateCell.SaveState();
  737. if (String.IsNullOrEmpty(templateCell.Hyperlink.Expression) &&
  738. (templateCell.Hyperlink.Kind == HyperlinkKind.DetailReport ||
  739. templateCell.Hyperlink.Kind == HyperlinkKind.DetailPage ||
  740. templateCell.Hyperlink.Kind == HyperlinkKind.Custom))
  741. {
  742. string hyperlinkValue = "";
  743. string separator = templateCell.Hyperlink.ValuesSeparator;
  744. foreach (object obj in Matrix.ColumnValues)
  745. {
  746. hyperlinkValue += obj.ToString() + separator;
  747. }
  748. foreach (object obj in Matrix.RowValues)
  749. {
  750. hyperlinkValue += obj.ToString() + separator;
  751. }
  752. templateCell.Hyperlink.Value = hyperlinkValue.Substring(0, hyperlinkValue.Length - separator.Length);
  753. }
  754. int evenStyleIndex = Matrix.MatrixEvenStylePriority == MatrixEvenStylePriority.Rows ?
  755. Matrix.RowIndex : Matrix.ColumnIndex;
  756. if ((evenStyleIndex + 1) % 2 == 0)
  757. templateCell.ApplyEvenStyle();
  758. templateCell.GetData();
  759. resultCell.RunTimeAssign(templateCell, true);
  760. templateCell.RestoreState();
  761. }
  762. }
  763. firstTimePrintingData = false;
  764. Matrix.ColumnIndex++;
  765. if (Matrix.CellsSideBySide)
  766. {
  767. if (Matrix.KeepCellsSideBySide)
  768. ResultTable.Columns[left].KeepColumns = dataCount;
  769. left += dataCount;
  770. }
  771. else
  772. left++;
  773. }
  774. Matrix.RowIndex++;
  775. if (Matrix.CellsSideBySide)
  776. top++;
  777. else
  778. top += dataCount;
  779. }
  780. }
  781. private object GetCellValue(MatrixHeaderItem columnItem, MatrixHeaderItem rowItem, int cellIndex)
  782. {
  783. if (columnItem.IsTotal || rowItem.IsTotal)
  784. return GetAggregatedTotalValue(columnItem, rowItem, cellIndex);
  785. else
  786. return GetAggregatedValue(Matrix.Data.GetValues(columnItem.Index, rowItem.Index, cellIndex), cellIndex);
  787. }
  788. private object GetAggregatedTotalValue(MatrixHeaderItem column, MatrixHeaderItem row, int cellIndex)
  789. {
  790. ArrayList list = new ArrayList();
  791. if (column.IsTotal)
  792. column = column.Parent;
  793. if (row.IsTotal)
  794. row = row.Parent;
  795. List<MatrixHeaderItem> columnTerminalItems = column.GetTerminalItems();
  796. List<MatrixHeaderItem> rowTerminalItems = row.GetTerminalItems();
  797. // collect all values in the specified items
  798. foreach (MatrixHeaderItem rowItem in rowTerminalItems)
  799. {
  800. if (rowItem.IsTotal)
  801. continue;
  802. foreach (MatrixHeaderItem columnItem in columnTerminalItems)
  803. {
  804. if (columnItem.IsTotal)
  805. continue;
  806. ArrayList values = Matrix.Data.GetValues(columnItem.Index, rowItem.Index, cellIndex);
  807. if (values != null)
  808. list.AddRange(values);
  809. }
  810. }
  811. return GetAggregatedValue(list, cellIndex);
  812. }
  813. private object GetAggregatedValue(ArrayList list, int cellIndex)
  814. {
  815. if (list == null || list.Count == 0)
  816. return null;
  817. MatrixAggregateFunction function = Matrix.Data.Cells[cellIndex].Function;
  818. // custom function - just calculate the expression
  819. if (function == MatrixAggregateFunction.Custom)
  820. return Report.Calc(Matrix.Data.Cells[cellIndex].Expression);
  821. // Count function - just return the number of values
  822. if (function == MatrixAggregateFunction.Count)
  823. return list.Count;
  824. if (function == MatrixAggregateFunction.CountDistinct)
  825. {
  826. Hashtable distinctValues = new Hashtable();
  827. foreach (object value in list)
  828. {
  829. distinctValues[value] = 1;
  830. }
  831. return distinctValues.Keys.Count;
  832. }
  833. // aggregated value
  834. Variant aggrValue = new Variant();
  835. for (int i = 0; i < list.Count; i++)
  836. {
  837. object value = list[i];
  838. if (i == 0)
  839. {
  840. // assign the first value to aggrValue
  841. aggrValue = new Variant(value);
  842. }
  843. else
  844. {
  845. // handle other values
  846. switch (function)
  847. {
  848. case MatrixAggregateFunction.Sum:
  849. case MatrixAggregateFunction.Avg:
  850. aggrValue += new Variant(value);
  851. break;
  852. case MatrixAggregateFunction.Min:
  853. if (new Variant(value) < aggrValue)
  854. aggrValue = new Variant(value);
  855. break;
  856. case MatrixAggregateFunction.Max:
  857. if (new Variant(value) > aggrValue)
  858. aggrValue = new Variant(value);
  859. break;
  860. }
  861. }
  862. }
  863. // finish Avg calculation
  864. if (function == MatrixAggregateFunction.Avg)
  865. aggrValue = aggrValue / list.Count;
  866. return aggrValue.Value;
  867. }
  868. #endregion
  869. #region Public Methods
  870. public void BuildTemplate()
  871. {
  872. bool noColumns = Matrix.Data.Columns.Count == 0;
  873. bool noRows = Matrix.Data.Rows.Count == 0;
  874. bool noCells = Matrix.Data.Cells.Count == 0;
  875. // create temporary descriptors
  876. if (noColumns)
  877. Matrix.Data.Columns.Add(noColumnsDescriptor);
  878. if (noRows)
  879. Matrix.Data.Rows.Add(noRowsDescriptor);
  880. if (noCells)
  881. Matrix.Data.Cells.Add(noCellsDescriptor);
  882. UpdateTemplateSizes();
  883. // prepare data for the result table
  884. string[] columnValues = new string[Matrix.Data.Columns.Count];
  885. string[] rowValues = new string[Matrix.Data.Rows.Count];
  886. object[] cellValues = new object[Matrix.Data.Cells.Count];
  887. for (int i = 0; i < Matrix.Data.Columns.Count; i++)
  888. {
  889. columnValues[i] = "[" + ExtractColumnName(Matrix.Data.Columns[i].Expression) + "]";
  890. }
  891. for (int i = 0; i < Matrix.Data.Rows.Count; i++)
  892. {
  893. rowValues[i] = "[" + ExtractColumnName(Matrix.Data.Rows[i].Expression) + "]";
  894. }
  895. Matrix.Data.Clear();
  896. Matrix.Data.AddValue(columnValues, rowValues, cellValues, 0);
  897. // create the result table
  898. designTime = true;
  899. resultTable = new TableResult();
  900. InitResultTable(true);
  901. PrintHeaders();
  902. PrintData();
  903. // copy the result table to the Matrix
  904. Matrix.ColumnCount = ResultTable.ColumnCount;
  905. Matrix.RowCount = ResultTable.RowCount;
  906. Matrix.FixedColumns = HeaderWidth;
  907. Matrix.FixedRows = HeaderHeight;
  908. Matrix.CreateUniqueNames();
  909. for (int x = 0; x < Matrix.ColumnCount; x++)
  910. {
  911. Matrix.Columns[x].Assign(ResultTable.Columns[x]);
  912. }
  913. for (int y = 0; y < Matrix.RowCount; y++)
  914. {
  915. Matrix.Rows[y].Assign(ResultTable.Rows[y]);
  916. }
  917. for (int x = 0; x < Matrix.ColumnCount; x++)
  918. {
  919. for (int y = 0; y < Matrix.RowCount; y++)
  920. {
  921. TableCell cell = Matrix[x, y];
  922. // call AssignAll with assignName parameter to preserve names of objects contained in a cell
  923. ResultTable[x, y].Name = cell.Name;
  924. cell.AssignAll(ResultTable[x, y], true);
  925. cell.SetFlags(Flags.CanEdit, true);
  926. }
  927. }
  928. UpdateDescriptors();
  929. resultTable.Dispose();
  930. // clear temporary descriptors, set hints
  931. if (noColumns)
  932. {
  933. SetHint(Matrix[HeaderWidth, Matrix.ShowTitle ? 1 : 0], Res.Get("ComponentsMisc,Matrix,NewColumn"));
  934. Matrix.Data.Columns.Clear();
  935. }
  936. else
  937. {
  938. noColumnsDescriptor.TemplateColumn = Matrix.Data.Columns[0].TemplateColumn;
  939. noColumnsDescriptor.TemplateRow = Matrix.Data.Columns[0].TemplateRow;
  940. noColumnsDescriptor.TemplateCell = Matrix.Data.Columns[0].TemplateCell;
  941. }
  942. if (noRows)
  943. {
  944. SetHint(Matrix[0, HeaderHeight], Res.Get("ComponentsMisc,Matrix,NewRow"));
  945. Matrix.Data.Rows.Clear();
  946. }
  947. else
  948. {
  949. noRowsDescriptor.TemplateColumn = Matrix.Data.Rows[0].TemplateColumn;
  950. noRowsDescriptor.TemplateRow = Matrix.Data.Rows[0].TemplateRow;
  951. noRowsDescriptor.TemplateCell = Matrix.Data.Rows[0].TemplateCell;
  952. }
  953. if (noCells)
  954. {
  955. SetHint(Matrix[HeaderWidth, HeaderHeight], Res.Get("ComponentsMisc,Matrix,NewCell"));
  956. Matrix.Data.Cells.Clear();
  957. }
  958. else
  959. {
  960. noCellsDescriptor.TemplateColumn = Matrix.Data.Cells[0].TemplateColumn;
  961. noCellsDescriptor.TemplateRow = Matrix.Data.Cells[0].TemplateRow;
  962. noCellsDescriptor.TemplateCell = Matrix.Data.Cells[0].TemplateCell;
  963. }
  964. }
  965. public void UpdateDescriptors()
  966. {
  967. bool noColumns = Matrix.Data.Columns.Count == 0;
  968. bool noRows = Matrix.Data.Rows.Count == 0;
  969. bool noCells = Matrix.Data.Cells.Count == 0;
  970. // create temporary descriptors
  971. if (noColumns)
  972. Matrix.Data.Columns.Add(noColumnsDescriptor);
  973. if (noRows)
  974. Matrix.Data.Rows.Add(noRowsDescriptor);
  975. if (noCells)
  976. Matrix.Data.Cells.Add(noCellsDescriptor);
  977. UpdateTemplateSizes();
  978. Matrix.FixedColumns = HeaderWidth;
  979. Matrix.FixedRows = HeaderHeight;
  980. UpdateColumnDescriptors();
  981. UpdateRowDescriptors();
  982. UpdateCellDescriptors();
  983. UpdateOtherDescriptors();
  984. // clear temporary descriptors
  985. if (noColumns)
  986. Matrix.Data.Columns.Clear();
  987. if (noRows)
  988. Matrix.Data.Rows.Clear();
  989. if (noCells)
  990. Matrix.Data.Cells.Clear();
  991. }
  992. public void StartPrint()
  993. {
  994. if ((Matrix.Data.Columns.Count == 0 && Matrix.Data.Rows.Count == 0) || Matrix.Data.Cells.Count == 0)
  995. throw new Exception(String.Format(Res.Get("Messages,MatrixError"), Matrix.Name));
  996. designTime = false;
  997. noColumns = Matrix.Data.Columns.Count == 0;
  998. noRows = Matrix.Data.Rows.Count == 0;
  999. // create temporary descriptors
  1000. if (noColumns)
  1001. Matrix.Data.Columns.Add(noColumnsDescriptor);
  1002. if (noRows)
  1003. Matrix.Data.Rows.Add(noRowsDescriptor);
  1004. Config.ReportSettings.OnProgress(Report, Res.Get("ComponentsMisc,Matrix,FillData"), 0, 0);
  1005. Matrix.Data.Clear();
  1006. Matrix.OnManualBuild(EventArgs.Empty);
  1007. }
  1008. public void AddDataRow()
  1009. {
  1010. object[] columnValues = new object[Matrix.Data.Columns.Count];
  1011. object[] rowValues = new object[Matrix.Data.Rows.Count];
  1012. object[] cellValues = new object[Matrix.Data.Cells.Count];
  1013. string expression = "";
  1014. for (int i = 0; i < Matrix.Data.Columns.Count; i++)
  1015. {
  1016. expression = Matrix.Data.Columns[i].Expression;
  1017. columnValues[i] = String.IsNullOrEmpty(expression) ? null : Report.Calc(expression);
  1018. }
  1019. for (int i = 0; i < Matrix.Data.Rows.Count; i++)
  1020. {
  1021. expression = Matrix.Data.Rows[i].Expression;
  1022. rowValues[i] = String.IsNullOrEmpty(expression) ? null : Report.Calc(expression);
  1023. }
  1024. for (int i = 0; i < Matrix.Data.Cells.Count; i++)
  1025. {
  1026. // skip custom function calculation; it will be calculated when we print the value
  1027. if (Matrix.Data.Cells[i].Function == MatrixAggregateFunction.Custom)
  1028. cellValues[i] = 0;
  1029. else
  1030. cellValues[i] = Report.Calc(Matrix.Data.Cells[i].Expression);
  1031. }
  1032. Matrix.Data.AddValue(columnValues, rowValues, cellValues, Matrix.DataSource.CurrentRowNo);
  1033. }
  1034. public void AddEmptyDataRow()
  1035. {
  1036. object[] columnValues = new object[Matrix.Data.Columns.Count];
  1037. object[] rowValues = new object[Matrix.Data.Rows.Count];
  1038. object[] cellValues = new object[Matrix.Data.Cells.Count];
  1039. Matrix.Data.AddValue(columnValues, rowValues, cellValues, 0);
  1040. }
  1041. public void AddDataRows()
  1042. {
  1043. if (Matrix.DataSource != null)
  1044. {
  1045. Matrix.DataSource.Init(Matrix.Filter);
  1046. while (Matrix.DataSource.HasMoreRows)
  1047. {
  1048. AddDataRow();
  1049. Matrix.DataSource.Next();
  1050. }
  1051. }
  1052. }
  1053. public void FinishPrint()
  1054. {
  1055. if (!Matrix.Data.IsEmpty || Matrix.PrintIfEmpty)
  1056. {
  1057. if (Matrix.Data.IsEmpty)
  1058. AddEmptyDataRow();
  1059. UpdateDescriptors();
  1060. ResultTable.FixedColumns = HeaderWidth;
  1061. ResultTable.FixedRows = HeaderHeight;
  1062. InitResultTable(false);
  1063. PrintHeaders();
  1064. PrintData();
  1065. }
  1066. // clear temporary descriptors
  1067. if (noColumns)
  1068. Matrix.Data.Columns.Clear();
  1069. if (noRows)
  1070. Matrix.Data.Rows.Clear();
  1071. }
  1072. public void UpdateStyle()
  1073. {
  1074. for (int y = 0; y < Matrix.RowCount; y++)
  1075. {
  1076. for (int x = 0; x < Matrix.ColumnCount; x++)
  1077. {
  1078. string style = x < HeaderWidth || y < HeaderHeight ? "Header" : "Body";
  1079. ApplyStyle(Matrix[x, y], style);
  1080. }
  1081. }
  1082. }
  1083. #endregion
  1084. public MatrixHelper(MatrixObject matrix)
  1085. {
  1086. this.matrix = matrix;
  1087. titleDescriptor = new MatrixDescriptor();
  1088. cellHeaderDescriptor = new MatrixDescriptor();
  1089. cellHeaderDescriptor.Expression = "Data";
  1090. noColumnsDescriptor = new MatrixHeaderDescriptor("", false);
  1091. noRowsDescriptor = new MatrixHeaderDescriptor("", false);
  1092. noCellsDescriptor = new MatrixCellDescriptor();
  1093. }
  1094. }
  1095. }