ReportEngine.ProcessAt.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using FastReport.Utils;
  2. using System.Collections.Generic;
  3. namespace FastReport.Engine
  4. {
  5. internal enum EngineState
  6. {
  7. ReportStarted,
  8. ReportFinished,
  9. ReportPageStarted,
  10. ReportPageFinished,
  11. PageStarted,
  12. PageFinished,
  13. ColumnStarted,
  14. ColumnFinished,
  15. BlockStarted,
  16. BlockFinished,
  17. GroupStarted,
  18. GroupFinished
  19. }
  20. internal class EngineStateChangedEventArgs
  21. {
  22. #region Fields
  23. private ReportEngine engine;
  24. private EngineState state;
  25. #endregion Fields
  26. #region Properties
  27. public ReportEngine Engine
  28. {
  29. get { return engine; }
  30. }
  31. public EngineState State
  32. {
  33. get { return state; }
  34. }
  35. #endregion Properties
  36. #region Constructors
  37. internal EngineStateChangedEventArgs(ReportEngine engine, EngineState state)
  38. {
  39. this.engine = engine;
  40. this.state = state;
  41. }
  42. #endregion Constructors
  43. }
  44. internal delegate void EngineStateChangedEventHandler(object sender, EngineStateChangedEventArgs e);
  45. internal class ProcessInfo
  46. {
  47. #region Fields
  48. private TextObject textObject;
  49. private XmlItem xmlItem;
  50. #endregion Fields
  51. #region Properties
  52. public TextObjectBase TextObject
  53. {
  54. get { return textObject; }
  55. }
  56. #endregion Properties
  57. #region Constructors
  58. public ProcessInfo(TextObject obj, XmlItem item)
  59. {
  60. textObject = obj;
  61. xmlItem = item;
  62. }
  63. #endregion Constructors
  64. #region Public Methods
  65. public void Process()
  66. {
  67. textObject.SaveState();
  68. try
  69. {
  70. textObject.GetData();
  71. string fill_clr = textObject.FillColor.IsNamedColor ? textObject.FillColor.Name :
  72. "#" + textObject.FillColor.Name;
  73. string txt_clr = textObject.TextColor.IsNamedColor ? textObject.TextColor.Name :
  74. "#" + textObject.TextColor.Name;
  75. xmlItem.SetProp("x", textObject.Text);
  76. xmlItem.SetProp("Fill.Color", fill_clr);
  77. xmlItem.SetProp("TextFill.Color", txt_clr);
  78. xmlItem.SetProp("Font.Name", textObject.Font.Name);
  79. }
  80. finally
  81. {
  82. textObject.RestoreState();
  83. }
  84. }
  85. public bool Process(object sender, EngineState state)
  86. {
  87. ProcessAt processAt = textObject.ProcessAt;
  88. bool canProcess = false;
  89. if ((processAt == ProcessAt.DataFinished && state == EngineState.BlockFinished) ||
  90. (processAt == ProcessAt.GroupFinished && state == EngineState.GroupFinished))
  91. {
  92. // check which data is finished
  93. BandBase topParentBand = textObject.Band;
  94. if (topParentBand is ChildBand)
  95. topParentBand = (topParentBand as ChildBand).GetTopParentBand;
  96. if (processAt == ProcessAt.DataFinished && state == EngineState.BlockFinished)
  97. {
  98. // total can be printed on the same data header, or on its parent data band
  99. DataBand senderBand = sender as DataBand;
  100. canProcess = true;
  101. if (topParentBand is DataHeaderBand && (topParentBand.Parent != sender))
  102. canProcess = false;
  103. if (topParentBand is DataBand && senderBand.Parent != topParentBand)
  104. canProcess = false;
  105. }
  106. else
  107. {
  108. // total can be printed on the same group header
  109. canProcess = sender == topParentBand;
  110. }
  111. }
  112. else
  113. {
  114. canProcess = (processAt == ProcessAt.ReportFinished && state == EngineState.ReportFinished) ||
  115. (processAt == ProcessAt.ReportPageFinished && state == EngineState.ReportPageFinished) ||
  116. (processAt == ProcessAt.PageFinished && state == EngineState.PageFinished) ||
  117. (processAt == ProcessAt.ColumnFinished && state == EngineState.ColumnFinished);
  118. }
  119. if (canProcess)
  120. {
  121. Process();
  122. return true;
  123. }
  124. else
  125. return false;
  126. }
  127. #endregion Public Methods
  128. }
  129. public partial class ReportEngine
  130. {
  131. #region Fields
  132. private List<ProcessInfo> objectsToProcess;
  133. #endregion Fields
  134. #region Events
  135. internal event EngineStateChangedEventHandler StateChanged;
  136. #endregion Events
  137. #region Private Methods
  138. private void ProcessObjects(object sender, EngineState state)
  139. {
  140. for (int i = 0; i < objectsToProcess.Count; i++)
  141. {
  142. ProcessInfo info = objectsToProcess[i];
  143. if (info.Process(sender, state))
  144. {
  145. objectsToProcess.RemoveAt(i);
  146. i--;
  147. }
  148. }
  149. }
  150. private void OnStateChanged(object sender, EngineState state)
  151. {
  152. ProcessObjects(sender, state);
  153. if (StateChanged != null)
  154. StateChanged(sender, new EngineStateChangedEventArgs(this, state));
  155. }
  156. #endregion Private Methods
  157. #region Internal Methods
  158. internal void AddObjectToProcess(Base obj, XmlItem item)
  159. {
  160. TextObject textObj = obj as TextObject;
  161. if (textObj == null || textObj.ProcessAt == ProcessAt.Default)
  162. return;
  163. objectsToProcess.Add(new ProcessInfo(textObj, item));
  164. }
  165. #endregion Internal Methods
  166. #region Public Methods
  167. /// <summary>
  168. /// Processes the specified text object which <b>ProcessAt</b> property is set to <b>Custom</b>.
  169. /// </summary>
  170. /// <param name="obj">The text object to process.</param>
  171. public void ProcessObject(TextObjectBase obj)
  172. {
  173. for (int i = 0; i < objectsToProcess.Count; i++)
  174. {
  175. ProcessInfo info = objectsToProcess[i];
  176. if (info.TextObject == obj)
  177. {
  178. info.Process();
  179. objectsToProcess.RemoveAt(i);
  180. break;
  181. }
  182. }
  183. }
  184. #endregion Public Methods
  185. }
  186. }