TableCell.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.ComponentModel;
  5. using System.Drawing;
  6. using FastReport.Utils;
  7. using System.Windows.Forms;
  8. namespace FastReport.Table
  9. {
  10. /// <summary>
  11. /// Specifies how to display the duplicate values.
  12. /// </summary>
  13. public enum CellDuplicates
  14. {
  15. /// <summary>
  16. /// The <b>TableCell</b> can show duplicate values.
  17. /// </summary>
  18. Show,
  19. /// <summary>
  20. /// The <b>TableCell</b> with duplicate value will be shown but with no text.
  21. /// </summary>
  22. Clear,
  23. /// <summary>
  24. /// Several <b>TableCell</b> objects with the same value will be merged into one object.
  25. /// </summary>
  26. Merge,
  27. /// <summary>
  28. /// Several <b>TableCell</b> objects with the same non-empty value will be merged into one object.
  29. /// </summary>
  30. MergeNonEmpty
  31. }
  32. /// <summary>
  33. /// Represents a table cell.
  34. /// </summary>
  35. /// <remarks>
  36. /// Use <see cref="ColSpan"/>, <see cref="RowSpan"/> properties to set the cell's
  37. /// column and row spans. To put an object inside the cell, use its <see cref="Objects"/> property:
  38. /// <code>
  39. /// TableCell cell1;
  40. /// PictureObject picture1 = new PictureObject();
  41. /// picture1.Bounds = new RectangleF(0, 0, 32, 32);
  42. /// picture1.Name = "Picture1";
  43. /// cell1.Objects.Add(picture1);
  44. /// </code>
  45. /// </remarks>
  46. public partial class TableCell : TextObject, IParent
  47. {
  48. #region Fields
  49. private int colSpan;
  50. private int rowSpan;
  51. private ReportComponentCollection objects;
  52. private TableCellData cellData;
  53. private int savedOriginalObjectsCount;
  54. #endregion
  55. #region Properties
  56. /// <summary>
  57. /// Gets a collection of objects contained in this cell.
  58. /// </summary>
  59. [Browsable(false)]
  60. public ReportComponentCollection Objects
  61. {
  62. get
  63. {
  64. if (CellData != null)
  65. return CellData.Objects;
  66. return objects;
  67. }
  68. }
  69. /// <summary>
  70. /// Gets or sets the column span for this cell.
  71. /// </summary>
  72. [DefaultValue(1)]
  73. [Category("Appearance")]
  74. public int ColSpan
  75. {
  76. get
  77. {
  78. if (CellData != null)
  79. return CellData.ColSpan;
  80. return colSpan;
  81. }
  82. set
  83. {
  84. if (CellData != null)
  85. CellData.ColSpan = value;
  86. colSpan = value;
  87. }
  88. }
  89. /// <summary>
  90. /// Gets or sets the row span for this cell.
  91. /// </summary>
  92. [DefaultValue(1)]
  93. [Category("Appearance")]
  94. public int RowSpan
  95. {
  96. get
  97. {
  98. if (CellData != null)
  99. return CellData.RowSpan;
  100. return rowSpan;
  101. }
  102. set
  103. {
  104. if (CellData != null)
  105. CellData.RowSpan = value;
  106. rowSpan = value;
  107. }
  108. }
  109. /// <inheritdoc/>
  110. public override string Text
  111. {
  112. get
  113. {
  114. if (CellData != null)
  115. return CellData.Text;
  116. return base.Text;
  117. }
  118. set
  119. {
  120. if (CellData != null)
  121. CellData.Text = value;
  122. base.Text = value;
  123. }
  124. }
  125. /// <summary>
  126. /// Gets or sets a value that determines how to display duplicate values in the cells of the same group.
  127. /// </summary>
  128. [DefaultValue(CellDuplicates.Show)]
  129. [Category("Behavior")]
  130. public CellDuplicates CellDuplicates { get; set; }
  131. /// <summary>
  132. /// Ges or sets data associated with this cell. For internal use only.
  133. /// </summary>
  134. [Browsable(false)]
  135. public TableCellData CellData
  136. {
  137. get { return cellData; }
  138. set { cellData = value; }
  139. }
  140. /// <summary>
  141. /// Gets the address of this cell.
  142. /// </summary>
  143. [Browsable(false)]
  144. public Point Address
  145. {
  146. get { return CellData == null ? new Point() : CellData.Address; }
  147. }
  148. /// <summary>
  149. /// This property is not relevant to this class.
  150. /// </summary>
  151. [Browsable(false)]
  152. public override float Width
  153. {
  154. get
  155. {
  156. if (CellData != null)
  157. return CellData.Width;
  158. return base.Width;
  159. }
  160. set
  161. {
  162. base.Width = value;
  163. }
  164. }
  165. /// <summary>
  166. /// This property is not relevant to this class.
  167. /// </summary>
  168. [Browsable(false)]
  169. public override float Height
  170. {
  171. get
  172. {
  173. if (CellData != null)
  174. return CellData.Height;
  175. return base.Height;
  176. }
  177. set
  178. {
  179. base.Height = value;
  180. }
  181. }
  182. /// <inheritdoc/>
  183. public override float AbsLeft
  184. {
  185. get { return (Table != null) ? Table.AbsLeft + Left : base.AbsLeft; }
  186. }
  187. /// <inheritdoc/>
  188. public override float AbsTop
  189. {
  190. get { return (Table != null) ? Table.AbsTop + Top : base.AbsTop; }
  191. }
  192. /// <summary>
  193. /// Gets the <b>TableBase</b> object which this cell belongs to.
  194. /// </summary>
  195. [Browsable(false)]
  196. public TableBase Table
  197. {
  198. get { return Parent == null ? null : Parent.Parent as TableBase; }
  199. }
  200. #endregion
  201. #region Public Methods
  202. /// <inheritdoc/>
  203. public override void Assign(Base source)
  204. {
  205. base.Assign(source);
  206. TableCell src = source as TableCell;
  207. ColSpan = src.ColSpan;
  208. RowSpan = src.RowSpan;
  209. CellDuplicates = src.CellDuplicates;
  210. }
  211. /// <summary>
  212. /// Creates the exact copy of this cell.
  213. /// </summary>
  214. /// <returns>The copy of this cell.</returns>
  215. public TableCell Clone()
  216. {
  217. TableCell cell = new TableCell();
  218. cell.AssignAll(this);
  219. return cell;
  220. }
  221. /// <summary>
  222. /// Determines if two cells have identical settings.
  223. /// </summary>
  224. /// <param name="cell">Cell to compare with.</param>
  225. /// <returns><b>true</b> if cells are equal.</returns>
  226. public bool Equals(TableCell cell)
  227. {
  228. // do not override exising Equals method. It is used to compare elements in a list,
  229. // and will cause problems in the designer.
  230. return cell != null &&
  231. Fill.Equals(cell.Fill) &&
  232. TextFill.Equals(cell.TextFill) &&
  233. HorzAlign == cell.HorzAlign &&
  234. VertAlign == cell.VertAlign &&
  235. Border.Equals(cell.Border) &&
  236. Font.Equals(cell.Font) &&
  237. Formats.Equals(cell.Formats) &&
  238. Highlight.Equals(cell.Highlight) &&
  239. Restrictions == cell.Restrictions &&
  240. Hyperlink.Equals(cell.Hyperlink) &&
  241. Padding == cell.Padding &&
  242. AllowExpressions == cell.AllowExpressions &&
  243. Brackets == cell.Brackets &&
  244. HideZeros == cell.HideZeros &&
  245. HideValue == cell.HideValue &&
  246. Angle == cell.Angle &&
  247. RightToLeft == cell.RightToLeft &&
  248. WordWrap == cell.WordWrap &&
  249. Underlines == cell.Underlines &&
  250. Trimming == cell.Trimming &&
  251. FontWidthRatio == cell.FontWidthRatio &&
  252. FirstTabOffset == cell.FirstTabOffset &&
  253. ParagraphOffset == cell.ParagraphOffset &&
  254. TabWidth == cell.TabWidth &&
  255. Clip == cell.Clip &&
  256. Wysiwyg == cell.Wysiwyg &&
  257. LineHeight == cell.LineHeight &&
  258. Style == cell.Style &&
  259. EvenStyle == cell.EvenStyle &&
  260. HoverStyle == cell.HoverStyle &&
  261. HasHtmlTags == cell.HasHtmlTags &&
  262. NullValue == cell.NullValue &&
  263. ProcessAt == cell.ProcessAt &&
  264. Printable == cell.Printable &&
  265. Exportable == cell.Exportable &&
  266. CellDuplicates == cell.CellDuplicates &&
  267. // events
  268. BeforePrintEvent == cell.BeforePrintEvent &&
  269. AfterPrintEvent == cell.AfterPrintEvent &&
  270. AfterDataEvent == cell.AfterDataEvent
  271. &&
  272. Cursor == cell.Cursor &&
  273. ClickEvent == cell.ClickEvent &&
  274. MouseDownEvent == cell.MouseDownEvent &&
  275. MouseMoveEvent == cell.MouseMoveEvent &&
  276. MouseUpEvent == cell.MouseUpEvent &&
  277. MouseEnterEvent == cell.MouseEnterEvent &&
  278. MouseLeaveEvent == cell.MouseLeaveEvent
  279. ;
  280. }
  281. /// <inheritdoc/>
  282. public override void Serialize(FRWriter writer)
  283. {
  284. TableCell c = writer.DiffObject as TableCell;
  285. base.Serialize(writer);
  286. if (ColSpan != c.ColSpan)
  287. writer.WriteInt("ColSpan", ColSpan);
  288. if (RowSpan != c.RowSpan)
  289. writer.WriteInt("RowSpan", RowSpan);
  290. if (CellDuplicates != c.CellDuplicates)
  291. writer.WriteValue("CellDuplicates", CellDuplicates);
  292. }
  293. /// <summary>
  294. /// Changes the cell's style.
  295. /// </summary>
  296. /// <param name="style">The new style.</param>
  297. /// <remarks>
  298. /// Each cell in a dynamic table object (or in a matrix) has associated style.
  299. /// Several cells may share one style. If you try to change the cell's appearance directly
  300. /// (like setting cell.TextColor), it may affect other cells in the table.
  301. /// To change the single cell, use this method.
  302. /// </remarks>
  303. public void SetStyle(TableCell style)
  304. {
  305. cellData.SetStyle(style);
  306. }
  307. #endregion
  308. #region Report Engine
  309. /// <inheritdoc/>
  310. public override string[] GetExpressions()
  311. {
  312. List<string> expressions = new List<string>();
  313. expressions.AddRange(base.GetExpressions());
  314. if (Objects != null)
  315. {
  316. foreach (ReportComponentBase c in Objects)
  317. {
  318. expressions.AddRange(c.GetExpressions());
  319. }
  320. }
  321. return expressions.ToArray();
  322. }
  323. /// <inheritdoc/>
  324. public override void SaveState()
  325. {
  326. base.SaveState();
  327. OnBeforePrint(EventArgs.Empty);
  328. if (Objects != null)
  329. {
  330. savedOriginalObjectsCount = Objects.Count;
  331. foreach (ReportComponentBase c in Objects)
  332. {
  333. c.SaveState();
  334. c.OnBeforePrint(EventArgs.Empty);
  335. }
  336. }
  337. }
  338. /// <inheritdoc/>
  339. public override void RestoreState()
  340. {
  341. OnAfterPrint(EventArgs.Empty);
  342. base.RestoreState();
  343. if (Objects != null)
  344. {
  345. while (Objects.Count > savedOriginalObjectsCount)
  346. {
  347. Objects[Objects.Count - 1].Dispose();
  348. }
  349. for (int i = 0; i < Objects.Count; i++)
  350. {
  351. ReportComponentBase c = Objects[i];
  352. c.OnAfterPrint(EventArgs.Empty);
  353. c.RestoreState();
  354. }
  355. }
  356. }
  357. /// <inheritdoc/>
  358. public override void GetData()
  359. {
  360. base.GetData();
  361. if (Table != null && Table.IsInsideSpan(this))
  362. Text = "";
  363. if (Objects != null)
  364. {
  365. for (int i = 0; i < savedOriginalObjectsCount; i++)
  366. {
  367. ReportComponentBase c = Objects[i];
  368. c.GetData();
  369. c.OnAfterData();
  370. }
  371. }
  372. OnAfterData();
  373. }
  374. #endregion
  375. #region IParent Members
  376. /// <inheritdoc/>
  377. public bool CanContain(Base child)
  378. {
  379. bool insideSpan = false;
  380. if (Table != null)
  381. insideSpan = Table.IsInsideSpan(this);
  382. return !insideSpan && child is ReportComponentBase && !(child is BandBase) && child != Table;
  383. }
  384. /// <inheritdoc/>
  385. public void GetChildObjects(ObjectCollection list)
  386. {
  387. if (Objects != null)
  388. {
  389. foreach (ReportComponentBase obj in Objects)
  390. {
  391. list.Add(obj);
  392. }
  393. }
  394. }
  395. /// <inheritdoc/>
  396. public void AddChild(Base child)
  397. {
  398. if (child is ReportComponentBase)
  399. {
  400. if (Objects == null)
  401. {
  402. objects = new ReportComponentCollection(this);
  403. if (CellData != null)
  404. CellData.Objects = objects;
  405. }
  406. Objects.Add(child as ReportComponentBase);
  407. if (child is TableBase)
  408. (child as TableBase).PrintOnParent = true;
  409. }
  410. }
  411. /// <inheritdoc/>
  412. public void RemoveChild(Base child)
  413. {
  414. if (child is ReportComponentBase)
  415. Objects.Remove(child as ReportComponentBase);
  416. }
  417. /// <inheritdoc/>
  418. public int GetChildOrder(Base child)
  419. {
  420. if (child is ReportComponentBase)
  421. return Objects.IndexOf(child as ReportComponentBase);
  422. return 0;
  423. }
  424. /// <inheritdoc/>
  425. public void SetChildOrder(Base child, int order)
  426. {
  427. if (child is ReportComponentBase)
  428. {
  429. int oldOrder = child.ZOrder;
  430. if (oldOrder != -1 && order != -1 && oldOrder != order)
  431. {
  432. if (order > Objects.Count)
  433. order = Objects.Count;
  434. if (oldOrder <= order)
  435. order--;
  436. Objects.Remove(child as ReportComponentBase);
  437. Objects.Insert(order, child as ReportComponentBase);
  438. UpdateLayout(0, 0);
  439. }
  440. }
  441. }
  442. /// <inheritdoc/>
  443. public void UpdateLayout(float dx, float dy)
  444. {
  445. if (CellData != null)
  446. CellData.UpdateLayout(dx, dy);
  447. }
  448. #endregion
  449. /// <summary>
  450. /// Initializes a new instance of the <see cref="TableCell"/> class.
  451. /// </summary>
  452. public TableCell()
  453. {
  454. colSpan = 1;
  455. rowSpan = 1;
  456. Padding = new Padding(2, 1, 2, 1);
  457. SetFlags(Flags.CanDelete | Flags.CanCopy | Flags.CanMove | Flags.CanResize |
  458. Flags.CanChangeParent | Flags.CanDraw | Flags.CanWriteBounds, false);
  459. BaseName = "Cell";
  460. }
  461. }
  462. }