dbwhtml.pp 16 KB

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