fpreportcontnr.pp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. {
  2. This file is part of the Free Component Library.
  3. Copyright (c) 2017 Michael Van Canneyt, member of the Free Pascal development team
  4. Report Data loop classes based on object lists in contnrs unit.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit fpreportcontnr;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, fpreport, contnrs;
  16. Type
  17. { TFPReportObjectData }
  18. TFPReportObjectData = class(TFPReportData)
  19. private
  20. FIndex : Integer;
  21. protected
  22. Function GetObjectCount : Integer; virtual; Abstract;
  23. Function GetObject(Aindex :Integer) : TObject; virtual; Abstract;
  24. Function GetObjectClass : TClass; virtual;
  25. procedure DoGetValue(const AFieldName: string; var AValue: variant); override;
  26. procedure DoInitDataFields; override;
  27. procedure DoOpen; override;
  28. procedure DoFirst; override;
  29. procedure DoNext; override;
  30. procedure DoClose; override;
  31. function DoEOF: boolean; override;
  32. Public
  33. property DataFields;
  34. end;
  35. { TFPReportCollectionData }
  36. TFPReportCollectionData = class(TFPReportObjectData)
  37. private
  38. FCollection: TCollection;
  39. FOwnsCollection: Boolean;
  40. Protected
  41. Function GetObjectCount : Integer; override;
  42. Function GetObject(Aindex :Integer) : TObject; override;
  43. Function GetObjectClass : TClass; override;
  44. Public
  45. Destructor Destroy; override;
  46. Property Collection : TCollection Read FCollection Write FCollection;
  47. Published
  48. Property OwnsCollection : Boolean Read FOwnsCollection Write FOwnsCollection;
  49. end;
  50. { TFPReportObjectListData }
  51. TFPReportObjectListData = class(TFPReportObjectData)
  52. private
  53. FList : TFPObjectList;
  54. FOwnsList: Boolean;
  55. Protected
  56. Function GetObjectCount : Integer; override;
  57. Function GetObject(Aindex :Integer) : TObject; override;
  58. Function GetObjectClass : TClass; override;
  59. Public
  60. Destructor Destroy; override;
  61. Property List : TFPObjectList Read FList Write FList;
  62. Published
  63. Property OwnsList : Boolean Read FOwnsList Write FOwnsList;
  64. end;
  65. implementation
  66. uses typinfo, variants;
  67. { TFPReportObjectListData }
  68. function TFPReportObjectListData.GetObjectCount: Integer;
  69. begin
  70. if Assigned(FList) then
  71. Result:=FList.Count
  72. else
  73. Result:=0;
  74. end;
  75. function TFPReportObjectListData.GetObject(Aindex: Integer): TObject;
  76. begin
  77. if Assigned(FList) then
  78. Result:=FList[AIndex]
  79. else
  80. Result:=Nil;
  81. end;
  82. function TFPReportObjectListData.GetObjectClass: TClass;
  83. begin
  84. if Assigned(FList) and (FList.Count>0) then
  85. Result:=FList[0].ClassType
  86. else
  87. Result:=Nil;
  88. end;
  89. destructor TFPReportObjectListData.Destroy;
  90. begin
  91. if FOwnsList then
  92. FreeAndNil(Flist);
  93. inherited Destroy;
  94. end;
  95. { TFPReportCollectionData }
  96. function TFPReportCollectionData.GetObjectCount: Integer;
  97. begin
  98. if Assigned(FCollection) then
  99. Result:=FCollection.Count
  100. else
  101. Result:=0;
  102. end;
  103. function TFPReportCollectionData.GetObject(Aindex: Integer): TObject;
  104. begin
  105. if Assigned(FCollection) then
  106. Result:=FCollection.Items[AIndex]
  107. else
  108. Result:=Nil;
  109. end;
  110. function TFPReportCollectionData.GetObjectClass: TClass;
  111. begin
  112. if Assigned(FCollection) then
  113. if (FCollection.Count>0) then
  114. Result:=FCollection.Items[0].ClassType
  115. else
  116. Result:=FCollection.ItemClass
  117. else
  118. Result:=Nil;
  119. end;
  120. destructor TFPReportCollectionData.Destroy;
  121. begin
  122. if FOwnsCollection then
  123. FreeAndNil(FCollection);
  124. inherited Destroy;
  125. end;
  126. { TFPReportObjectData }
  127. function TFPReportObjectData.GetObjectClass: TClass;
  128. Var
  129. O : TObject;
  130. begin
  131. O:=GetObject(0);
  132. if Assigned(O) then
  133. Result:=O.ClassType
  134. else
  135. Result:=nil;
  136. end;
  137. procedure TFPReportObjectData.DoGetValue(const AFieldName: string;
  138. var AValue: variant);
  139. Var
  140. O : TObject;
  141. PI : PPropInfo;
  142. begin
  143. inherited DoGetValue(AFieldName, AValue);
  144. O:=GetObject(FIndex);
  145. if Assigned(O) then
  146. begin
  147. PI:=GetPropInfo(O,AFieldName);
  148. if Assigned(PI) then
  149. {$if FPC_FULLVERSION<=30000}
  150. aValue:=GetPropValue(O,PI^.Name,True);
  151. {$else}
  152. aValue:=GetPropValue(O,PI,True);
  153. {$endif}
  154. end;
  155. end;
  156. procedure TFPReportObjectData.DoInitDataFields;
  157. Const
  158. tkAllowed = tkProperties -
  159. [tkArray,tkRecord,tkInterface,tkClass,
  160. tkObject,tkDynArray,tkInterfaceRaw,tkProcVar,
  161. tkHelper{$if FPC_FULLVERSION>30000},tkFile,tkClassRef,tkPointer{$ENDIF}];
  162. Var
  163. C : TClass;
  164. PL : PPropList;
  165. I,Count : Integer;
  166. K : TFPReportFieldKind;
  167. Tk : TTypeKind;
  168. begin
  169. inherited DoInitDataFields;
  170. C:=GetObjectClass;
  171. if C=Nil then exit;
  172. Count:=GetPropList(C,PL);
  173. try
  174. For I:=0 to Count-1 do
  175. begin
  176. TK:=PL^[i]^.PropType^.Kind;
  177. if (Tk in tkAllowed) then
  178. begin
  179. Case TK of
  180. tkInteger,tkInt64,tkQWord :
  181. K:=rfkInteger;
  182. tkSet,tkSString,tkLString,tkAString,
  183. tkChar,tkEnumeration,tkWChar,tkUString,tkUChar,tkWString,tkVariant :
  184. k:=rfkString;
  185. tkFloat :
  186. if PL^[i]^.PropType=TypeInfo(TDateTime) then
  187. K:=rfkDateTime
  188. else
  189. K:=rfkFloat;
  190. tkBool:
  191. K:=rfkBoolean;
  192. end;
  193. Datafields.AddField(PL^[i]^.Name,K);
  194. end;
  195. end;
  196. finally
  197. FreeMem(PL);
  198. end;
  199. end;
  200. procedure TFPReportObjectData.DoOpen;
  201. begin
  202. inherited DoOpen;
  203. FIndex:=0;
  204. end;
  205. procedure TFPReportObjectData.DoFirst;
  206. begin
  207. inherited DoFirst;
  208. FIndex:=0;
  209. end;
  210. procedure TFPReportObjectData.DoNext;
  211. begin
  212. inherited DoNext;
  213. Inc(FIndex);
  214. end;
  215. procedure TFPReportObjectData.DoClose;
  216. begin
  217. FIndex:=-1;
  218. inherited DoClose;
  219. DataFields.Clear;
  220. end;
  221. function TFPReportObjectData.DoEOF: boolean;
  222. begin
  223. Result:=inherited DoEOF;
  224. Result:=Result or (FIndex<0) or (FIndex>=GetObjectCount);
  225. end;
  226. end.