dbwhtml.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  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. {$mode objfpc}
  12. {$H+}
  13. unit dbwhtml;
  14. Interface
  15. uses sysutils,classes,db,whtml;
  16. Type
  17. THTMLAlign = (haDefault,haLeft,haRight,haCenter); // Compatible with Delphi.
  18. THTMLVAlign = (haVDefault,haTop,haMiddle,haBottom,haBaseLine); // Compatible with Delphi.
  19. TGetCellContentsEvent = Procedure (Sender : TObject; Var CellData : String) of object;
  20. TCellAttributesEvent = Procedure (Sender : TObject;
  21. Var BGColor : String;
  22. Var Align : THTMLAlign;
  23. Var VAlign : THTMLValign;
  24. Var CustomAttr : String) of Object;
  25. TRowAttributesEvent = Procedure (Sender : TObject;
  26. Var BGColor : String;
  27. Var Align : THTMLAlign;
  28. Var VAlign : THTMLValign;
  29. Var CustomAttr : String) of Object;
  30. TRowAttributes = Class(TPersistent)
  31. Private
  32. FAlign : THTMLAlign;
  33. FVAlign : THTMLVAlign;
  34. FBGColor : String;
  35. FCustom : String;
  36. Public
  37. Procedure Assign(Source : TPersistent); Override;
  38. Property Align : THTMLAlign Read FAlign Write FAlign;
  39. Property BGColor : String Read FBGColor Write FBGColor;
  40. Property Custom : String Read FCustom Write FCustom;
  41. Property VAlign : THTMLVAlign Read FVAlign Write FVAlign;
  42. end;
  43. TTableColumn = Class(TCollectionItem)
  44. private
  45. FActionUrl: String;
  46. FAlign: THTMLAlign;
  47. FVAlign : THTMLVAlign;
  48. FBGColor: String;
  49. FCaptionURL: String;
  50. FFieldName : String;
  51. FCaption : String;
  52. FGetColumn: String;
  53. FGetCellContent : TGetCellContentsEvent;
  54. FImgUrl: String;
  55. Protected
  56. FField : TField; // Filled.
  57. Published
  58. Property FieldName : String Read FFieldName Write FFieldName;
  59. Property Caption : String Read FCaption Write FCaption;
  60. Property ImgUrl : String Read FImgUrl Write FImgUrl;
  61. Property ActionUrl : String Read FActionUrl Write FActionUrl;
  62. Property CaptionURL : String Read FCaptionURL Write FCaptionURL;
  63. Property BGColor : String Read FBGColor Write FBGColor;
  64. Property Align : THTMLAlign read FAlign Write Falign;
  65. Property VAlign : THTMLVAlign Read FValign Write FVAlign;
  66. Property OnGetCellContents : TGetCellContentsEvent Read FGetCellContent Write FGetCellContent;
  67. end;
  68. TTableColumns = Class(TCollection)
  69. Constructor Create;
  70. private
  71. function GetColumn(Index : Integer): TTableColumn;
  72. procedure SetColumn(Index : Integer; const AValue: TTableColumn);
  73. Public
  74. Function FindColumn(ColumnName : String) : TTableColumn;
  75. Function ColumnByName(ColumnName : String) : TTableColumn;
  76. Property Items[Index : Integer] : TTableColumn Read GetColumn Write SetColumn;
  77. end;
  78. THTMLProducer = Class(TComponent)
  79. Private
  80. FDataset : TDataset;
  81. FContents: TMemorySTream;
  82. Function GetContent : String;
  83. Protected
  84. Procedure CheckContents;
  85. Procedure WriteString(S : TStream; Const Value : String);
  86. Procedure WriteString(S : TStream; Const Fmt : String; Args : Array Of Const);
  87. Public
  88. Destructor Destroy; override;
  89. Procedure ClearContent;
  90. Procedure CreateContent; virtual; Abstract;
  91. Property Content : String Read GetContent;
  92. Published
  93. Property Dataset : TDataset Read FDataset Write FDataset;
  94. end;
  95. TTableProducer = Class(THTMLProducer)
  96. Private
  97. FGetRowAttrs: TRowAttributesEvent;
  98. FRowAttributes: TRowAttributes;
  99. FTableColumns : TTableColumns;
  100. FBorder : Boolean;
  101. FBGColor : String;
  102. FCurrentRow : Integer;
  103. FCurrentCol : Integer;
  104. FGetCellAttrs : TCellAttributesEvent;
  105. procedure SetRowAttributes(const AValue: TRowAttributes);
  106. Procedure SetTableColumns(Value : TTableColumns);
  107. Protected
  108. Procedure BindColumns;
  109. Procedure CreateTableColumns; Virtual;
  110. Procedure CreateTableHeader(Stream : TStream);
  111. Procedure CreateHeaderCell(C : TTableColumn; Stream : TStream); virtual;
  112. Procedure CreateTableRow(Stream : TStream);virtual;
  113. Procedure StartTable(Stream : TStream); virtual;
  114. Procedure EndTable(Stream : TStream); virtual;
  115. Procedure EmitFieldCell(C : TTableColumn; Stream : TStream); virtual;
  116. Public
  117. Constructor Create(AOwner : TComponent); override;
  118. Destructor Destroy; virtual;
  119. Function CreateAttr(Const ABGColor : String; A : THTMLAlign; VA : THTMLVAlign; CustomAttr : String) : String;
  120. Procedure Clear;
  121. Procedure CreateColumns(FieldList : TStrings);
  122. Procedure CreateColumns(FieldList : String);
  123. Procedure CreateTable(Stream : TStream);
  124. Procedure CreateTable;
  125. Procedure CreateContent; override;
  126. Property CurrentRow : Integer Read FCurrentRow;
  127. Property CurrentCol : Integer Read FCurrentCol;
  128. Published
  129. Property BGColor : String Read FBGColor Write FBGColor;
  130. Property Border : Boolean Read FBorder Write FBorder;
  131. Property RowAttributes : TRowAttributes Read FRowAttributes Write SetRowAttributes;
  132. Property TableColumns : TTableColumns Read FTableColumns Write SetTableColumns;
  133. Property OnGetCellAttributes : TCellAttributesEvent Read FGetCellAttrs write FGetCellAttrs;
  134. Property OnGetRowAttributes : TRowAttributesEvent Read FGetRowAttrs write FGetRowAttrs;
  135. end;
  136. TComboBoxProducer = Class(THTMLProducer)
  137. private
  138. FDatafield: String;
  139. FInputName: String;
  140. FValue: String;
  141. FValueField: String;
  142. function GetInputName: String;
  143. protected
  144. procedure CreateItem(Stream : TStream; VF,DF : TField; Selected : Boolean); virtual;
  145. Public
  146. Constructor Create(AOwner : TComponent); override;
  147. Destructor Destroy; virtual;
  148. Procedure CreateComboBox(Stream : TStream);
  149. Procedure CreateComboBox;
  150. Procedure CreateContent; override;
  151. Published
  152. Property ValueField : String Read FValueField Write FValueField;
  153. Property DataField : String Read FDatafield Write FDataField;
  154. Property Value : String Read FValue Write FValue;
  155. Property InputName : String Read GetInputName Write FInputName;
  156. end;
  157. TDBHtmlWriter = Class(THTMLWriter)
  158. Protected
  159. Function CreateTableProducer: TTableProducer; virtual;
  160. Public
  161. Procedure CreateTable(Dataset : TDataset);
  162. Procedure CreateTable(Dataset : TDataset; Producer : TTableProducer);
  163. end;
  164. EDBWriter = Class(Exception);
  165. Implementation
  166. uses dbconst;
  167. { TTableColumns }
  168. constructor TTableColumns.Create;
  169. begin
  170. inherited Create(TTableColumn);
  171. end;
  172. function TTableColumns.GetColumn(Index : Integer): TTableColumn;
  173. begin
  174. Result:=TTableColumn(Inherited Items[Index]);
  175. end;
  176. procedure TTableColumns.SetColumn(Index : Integer; const AValue: TTableColumn);
  177. begin
  178. Inherited Items[Index]:=AValue;
  179. end;
  180. function TTableColumns.FindColumn(ColumnName: String): TTableColumn;
  181. Var
  182. I : Integer;
  183. begin
  184. Result:=Nil;
  185. I:=Count-1;
  186. While (I>=0) and (CompareText(Items[i].FieldName,ColumnName)<>0) do
  187. Dec(I);
  188. If (I>=0) then
  189. Result:=Items[I];
  190. end;
  191. function TTableColumns.ColumnByName(ColumnName: String): TTableColumn;
  192. begin
  193. Result:=FindColumn(ColumnName);
  194. If (Result=Nil) then
  195. Raise EDBWriter.CreateFmt(SErrColumnNotFound,[ColumnName]);
  196. end;
  197. { TTableProducer }
  198. procedure TTableProducer.BindColumns;
  199. Var
  200. I : Integer;
  201. begin
  202. With FTableColumns do
  203. For I:=0 to Count-1 do
  204. With TTableColumn(Items[I]) do
  205. If (FieldName<>'') then
  206. FField:=FDataset.FieldByName(FieldName)
  207. else
  208. FField:=Nil;
  209. end;
  210. procedure TTableProducer.CreateTableColumns;
  211. begin
  212. FTableColumns:=TTableColumns.Create;
  213. end;
  214. procedure TTableProducer.CreateTableHeader(Stream : TStream);
  215. Var
  216. I : Integer;
  217. begin
  218. WriteString(Stream,'<TR>');
  219. With FTableColumns do
  220. For I:=0 to Count-1 do
  221. begin
  222. FCurrentCol:=I;
  223. CreateHeaderCell(TTableColumn(Items[I]),Stream);
  224. end;
  225. WriteString(Stream,'</TR>'#10);
  226. end;
  227. procedure TTableProducer.CreateHeaderCell(C: TTableColumn; Stream: TStream);
  228. Var
  229. URL : String;
  230. begin
  231. WriteString(Stream,'<TH>');
  232. With C do
  233. begin
  234. If (FCaptionURL<>'') then
  235. begin
  236. URL:=Format(FCaptionURL,[FieldName]);
  237. URL:=Format('<A HREF="%s">',[URL]);
  238. WriteString(Stream,URL);
  239. end;
  240. WriteString(Stream,Caption);
  241. If (FCaptionURL<>'') then
  242. WriteString(Stream,'</A>');
  243. If (FImgURL<>'') then
  244. begin
  245. if (FCaptionURL<>'') then
  246. WriteString(Stream,URL);
  247. WriteString(Stream,'<IMG SRC="%s">',[FImgURL]);
  248. If (FCaptionURL<>'') then
  249. WriteString(Stream,'</A>');
  250. end;
  251. end;
  252. WriteString(Stream,'</TH>');
  253. end;
  254. procedure TTableProducer.CreateTableRow(Stream : TStream);
  255. Var
  256. I : Integer;
  257. BG : String;
  258. A : THTMLAlign;
  259. VA : THTMLVAlign;
  260. RTAG,CustA : String;
  261. begin
  262. With FRowAttributes do
  263. begin
  264. BG:=FBGColor;
  265. A:=FAlign;
  266. VA:=VAlign;
  267. CustA:=FCustom;
  268. end;
  269. If Assigned(FGetRowAttrs) then
  270. FGetRowAttrs(Self,BG,A,VA,CustA);
  271. RTAG:=CreateAttr(BG,A,VA,CustA);
  272. If (RTAG='') then
  273. RTag:='<TR>'
  274. else
  275. RTag:='<TR '+RTag+'>';
  276. WriteString(Stream,RTag);
  277. With FTableColumns do
  278. For I:=0 to Count-1 do
  279. EmitFieldCell(TTableColumn(Items[I]),Stream);
  280. WriteString(Stream,'</TR>'#10);
  281. end;
  282. procedure TTableProducer.StartTable(Stream: TStream);
  283. Var
  284. S : String;
  285. begin
  286. S:='<TABLE';
  287. If Border then
  288. S:=S+' BORDER=1';
  289. If (BGColor<>'') then
  290. S:=S+'BGCOlor="'+BGColor+'"';
  291. S:=S+'>';
  292. WriteString(Stream,S);
  293. end;
  294. procedure TTableProducer.EndTable(Stream: TStream);
  295. begin
  296. WriteString(Stream,'</TABLE>'#10);
  297. end;
  298. Function TTableProducer.CreateAttr(Const ABGColor : String; A : THTMLAlign; VA : THTMLVAlign; CustomAttr : String) : String;
  299. Const
  300. HAligns : Array[THTMLAlign] of string = ('','"left"','"right"','"center"');
  301. VAligns : Array[THTMLVAlign] of string = ('','"top"','"middle"','"bottom"','"baseLine"');
  302. begin
  303. Result:='';
  304. If (ABGColor<>'') then
  305. Result:='BGColor="'+ABGColor+'"';
  306. If (A<>haDefault) then
  307. Result:=Result+' Align='+HAligns[A];
  308. if (VA<>haVDefault) then
  309. Result:=Result+' Align='+VAligns[VA];
  310. If (CustomAttr<>'') then
  311. Result:=Result+' '+CustomAttr;
  312. end;
  313. procedure TTableProducer.EmitFieldCell(C: TTableColumn; Stream: TStream);
  314. Var
  315. URL : String;
  316. BG : String;
  317. A : THTMLAlign;
  318. VA : THTMLVAlign;
  319. CellA,CustA : String;
  320. begin
  321. BG:=C.BGColor;
  322. A:=C.Align;
  323. VA:=C.Valign;
  324. CustA:='';
  325. If Assigned(FGetCellAttrs) then
  326. FGetCellAttrs(Self,BG,A,VA,CustA);
  327. CellA:=CreateAttr(BGColor,A,VA,CustA);
  328. If (CellA='') then
  329. CellA:='<TD>'
  330. else
  331. CellA:='<TD '+CellA+'>';
  332. WriteString(Stream,CellA);
  333. // Reuse for contents.
  334. CellA:='';
  335. If (C.FField<>Nil) then
  336. CellA:=C.FField.AsString;
  337. If Assigned(C.FGetCellContent) then
  338. C.FGetCellContent(Self,CellA);
  339. With C.FField Do
  340. begin
  341. URL:=C.ActionURL;
  342. If (URL<>'') then
  343. begin
  344. URL:=Format(C.ActionURL,[AsString]);
  345. WriteString(Stream,'<A HREF="%s">',[URL]);
  346. end;
  347. WriteString(Stream,CellA);
  348. If (URL<>'') then
  349. WriteString(Stream,'</A>');
  350. end;
  351. WriteString(Stream,'</TD>');
  352. end;
  353. constructor TTableProducer.Create(AOwner : TComponent);
  354. begin
  355. Inherited Create(AOwner);
  356. FRowAttributes:=TRowAttributes.Create;
  357. CreateTableColumns;
  358. FCurrentRow:=-1;
  359. FCurrentCol:=-1;
  360. end;
  361. destructor TTableProducer.Destroy;
  362. begin
  363. FTableColumns.Free;
  364. Inherited;
  365. end;
  366. procedure TTableProducer.Clear;
  367. begin
  368. FTableColumns.Clear;
  369. If Assigned(FContents) then
  370. FreeAndNil(FContents);
  371. FBorder:=False;
  372. end;
  373. procedure TTableProducer.CreateColumns(FieldList: TStrings);
  374. Var
  375. I : Integer;
  376. FN : String;
  377. begin
  378. For I:=0 to FDataset.FieldCount-1 do
  379. begin
  380. FN:=FDataset.Fields[I].FieldName;
  381. If (FieldList=Nil) or (FieldList.IndexOf(FN)<>-1) then
  382. With FTableColumns.Add as TTableColumn do
  383. begin
  384. FieldName:=FN;
  385. Caption:=FDataset.Fields[i].DisplayName;
  386. end;
  387. end
  388. end;
  389. procedure TTableProducer.CreateColumns(FieldList: String);
  390. Var
  391. L : TStringList;
  392. begin
  393. If (FieldList='') then
  394. CreateColumns(Nil)
  395. else
  396. begin
  397. L:=TStringList.Create;
  398. try
  399. L.CommaText:=FieldList;
  400. CreateColumns(L);
  401. Finally
  402. L.Free;
  403. end;
  404. end;
  405. end;
  406. procedure TTableProducer.CreateTable(Stream: TStream);
  407. begin
  408. If FTableColumns.Count=0 then
  409. CreateColumns(Nil);
  410. BindColumns;
  411. StartTable(Stream);
  412. Try
  413. FCurrentRow:=0;
  414. CreateTableHeader(Stream);
  415. While Not Dataset.EOF do
  416. begin
  417. Inc(FCurrentRow);
  418. CreateTableRow(Stream);
  419. Dataset.Next;
  420. end;
  421. Finally
  422. EndTable(Stream);
  423. FCurrentRow:=-1;
  424. FCurrentCol:=-1;
  425. end;
  426. end;
  427. procedure TTableProducer.CreateTable;
  428. begin
  429. CheckContents;
  430. CreateTable(FContents);
  431. end;
  432. procedure TTableProducer.CreateContent;
  433. begin
  434. CreateTable;
  435. end;
  436. Procedure TTableProducer.SetTableColumns(Value : TTableColumns);
  437. begin
  438. FTableColumns.Assign(Value);
  439. end;
  440. procedure TTableProducer.SetRowAttributes(const AValue: TRowAttributes);
  441. begin
  442. if (FRowAttributes=AValue) then
  443. exit;
  444. FRowAttributes.Assign(AValue);
  445. end;
  446. { TComboBoxProducer }
  447. function TComboBoxProducer.GetInputName: String;
  448. begin
  449. If (FInputName='') then
  450. Result:=Name
  451. else
  452. Result:=FInputName;
  453. end;
  454. constructor TComboBoxProducer.Create(AOwner: TComponent);
  455. begin
  456. inherited Create(AOwner);
  457. end;
  458. destructor TComboBoxProducer.Destroy;
  459. begin
  460. Inherited;
  461. end;
  462. procedure TComboBoxProducer.CreateItem(Stream : TStream; VF,DF : TField; Selected : Boolean);
  463. Const
  464. SOptions : Array[Boolean] of String = ('<OPTION','<OPTION SELECTED');
  465. Var
  466. S : String;
  467. begin
  468. WriteString(STream,SOptions[Selected]);
  469. If (VF<>Nil) and (VF<>DF) then
  470. WriteString(Stream,' VALUE="'+VF.AsString+'"');
  471. WriteString(Stream,'>'+DF.AsString+#10);
  472. end;
  473. procedure TComboBoxProducer.CreateComboBox(Stream: TStream);
  474. Var
  475. VF,DF,SF : TField;
  476. begin
  477. DF:=Dataset.FieldByNAme(DataField);
  478. if (ValueField<>'') then
  479. VF:=Dataset.FieldByName(ValueField)
  480. else
  481. VF:=Nil;
  482. If (Value='') then
  483. SF:=Nil
  484. else
  485. if VF<>NIl then
  486. SF:=VF
  487. else
  488. SF:=DF;
  489. WriteString(Stream,'<SELECT NAME="'+InputName+'">');
  490. Try
  491. While not Dataset.EOF do
  492. begin
  493. CreateItem(Stream,VF,DF,((SF<>Nil) and (SF.AsString=Value)));
  494. Dataset.Next;
  495. end;
  496. Finally
  497. WriteString(Stream,'</SELECT>');
  498. end;
  499. end;
  500. procedure TComboBoxProducer.CreateComboBox;
  501. begin
  502. CheckContents;
  503. CreateComboBox(FContents);
  504. end;
  505. procedure TComboBoxProducer.CreateContent;
  506. begin
  507. CreateComboBox;
  508. end;
  509. { THTMLProceder }
  510. function THTMLProducer.GetContent: String;
  511. begin
  512. If Assigned(FContents) then
  513. begin
  514. SetLength(Result,FContents.Size);
  515. If (FContents.Size>0) then
  516. Move(FContents,Result[1],FContents.Size);
  517. end;
  518. end;
  519. procedure THTMLProducer.CheckContents;
  520. begin
  521. If Assigned(FContents) then
  522. FContents.Clear
  523. else
  524. FContents:=TMemoryStream.Create;
  525. end;
  526. destructor THTMLProducer.Destroy;
  527. begin
  528. If Assigned(FContents) then
  529. FreeAndNil(FContents);
  530. inherited Destroy;
  531. end;
  532. procedure THTMLProducer.ClearContent;
  533. begin
  534. If Assigned(FContents) then
  535. FContents.Clear;
  536. end;
  537. procedure THTMLProducer.WriteString(S: TStream; const Value: String);
  538. Var
  539. L : Integer;
  540. begin
  541. L:=Length(Value);
  542. If L>0 then
  543. S.Write(Value[1],L);
  544. end;
  545. procedure THTMLProducer.WriteString(S: TStream; const Fmt: String;
  546. Args: array of const);
  547. begin
  548. WriteString(S,Format(Fmt,Args));
  549. end;
  550. { TDBHtmlWriter }
  551. function TDBHtmlWriter.CreateTableProducer: TTableProducer;
  552. begin
  553. Result:=TTableProducer.Create(Nil);
  554. end;
  555. procedure TDBHtmlWriter.CreateTable(Dataset: TDataset);
  556. Var
  557. P : TTableProducer;
  558. begin
  559. P:=CreateTableProducer;
  560. Try
  561. CreateTable(Dataset,P);
  562. Finally
  563. P.Free;
  564. end;
  565. end;
  566. procedure TDBHtmlWriter.CreateTable(Dataset: TDataset; Producer: TTableProducer);
  567. begin
  568. Producer.Dataset:=Dataset;
  569. Producer.CreateTable(Self.Stream);
  570. end;
  571. { TRowAttributes }
  572. Procedure TRowAttributes.Assign(Source : TPersistent);
  573. Var
  574. R : TRowAttributes;
  575. begin
  576. If Source is TRowAttributes then
  577. begin
  578. R:=TRowAttributes(Source);
  579. FAlign:=R.FAlign;
  580. FBGColor:=R.FBGColor;
  581. FCustom:=R.FCustom;
  582. FVAlign:=R.FVAlign;
  583. end
  584. else
  585. Inherited Assign(Source)
  586. end;
  587. end.
  588. {
  589. $Log$
  590. Revision 1.7 2004-10-16 09:20:25 michael
  591. + Moved resourcestrings to dbconst
  592. Revision 1.6 2003/10/28 08:42:01 michael
  593. + Added ColumnByName method to TTAbleColumns
  594. Revision 1.4 2003/10/03 22:43:17 michael
  595. + Published tablecolumns property in tableproducer
  596. Revision 1.3 2003/10/03 08:42:22 michael
  597. + Form support.
  598. Revision 1.2 2003/10/01 21:07:48 michael
  599. + Added log/header
  600. }