/Source/FR_Class.pas

http://github.com/FastReports/FreeReport · Pascal · 7335 lines · 6646 code · 487 blank · 202 comment · 865 complexity · 52e74cfa96e31edbea7bd9f745adfb88 MD5 · raw file

Large files are truncated click here to view the full file

  1. {*****************************************}
  2. { }
  3. { FastReport v2.3 }
  4. { Report classes }
  5. { }
  6. { Copyright (c) 1998-99 by Tzyganenko A. }
  7. { }
  8. {*****************************************}
  9. unit FR_Class;
  10. interface
  11. {$I FR.inc}
  12. uses
  13. SysUtils, Windows, Messages, Classes, Graphics, Printers, Controls,
  14. Forms, StdCtrls, ComCtrls, Dialogs, Menus, Buttons,
  15. FR_View, FR_Pars, FR_Intrp, FR_DSet, FR_DBSet, FR_DBRel
  16. {$IFDEF Delphi6}
  17. , Variants
  18. {$ENDIF}
  19. {$IFDEF IBO}
  20. , IB_Components
  21. {$ELSE}
  22. , DB
  23. {$ENDIF};
  24. const
  25. // object flags
  26. flStretched = 1;
  27. flWordWrap = 2;
  28. flWordBreak = 4;
  29. flAutoSize = 8;
  30. flBandNewPageAfter = 2;
  31. flBandPrintifSubsetEmpty = 4;
  32. flBandPageBreak = 8;
  33. flBandOnFirstPage = $10;
  34. flBandOnLastPage = $20;
  35. flBandRepeatHeader = $40;
  36. flPictCenter = 2;
  37. flPictRatio = 4;
  38. flWantHook = $8000;
  39. // object types
  40. gtMemo = 0;
  41. gtPicture = 1;
  42. gtBand = 2;
  43. gtSubReport = 3;
  44. gtLine = 4;
  45. gtAddIn = 10;
  46. // frame types
  47. frftNone = 0;
  48. frftRight = 1;
  49. frftDown = 2;
  50. frftLeft = 4;
  51. frftUp = 8;
  52. // text align
  53. frtaLeft = 0;
  54. frtaRight = 1;
  55. frtaCenter = 2;
  56. frtaVertical = 4;
  57. frtaMiddle = 8;
  58. frtaDown = 16;
  59. type
  60. TfrDrawMode = (drAll, drCalcHeight, drAfterCalcHeight, drPart);
  61. TfrBandType = (btReportTitle, btReportSummary,
  62. btPageHeader, btPageFooter,
  63. btMasterHeader, btMasterData, btMasterFooter,
  64. btDetailHeader, btDetailData, btDetailFooter,
  65. btSubDetailHeader, btSubDetailData, btSubDetailFooter,
  66. btOverlay, btColumnHeader, btColumnFooter,
  67. btGroupHeader, btGroupFooter,
  68. btCrossHeader, btCrossData, btCrossFooter, btNone);
  69. TfrDataSetPosition = (psLocal, psGlobal);
  70. TfrValueType = (vtNotAssigned, vtDBField, vtOther, vtFRVar);
  71. TfrPageMode = (pmNormal, pmBuildList);
  72. TfrBandRecType = (rtShowBand, rtFirst, rtNext);
  73. TfrRgnType = (rtNormal, rtExtended);
  74. TfrReportType = (rtSimple, rtMultiple);
  75. TfrView = class;
  76. TfrBand = class;
  77. TfrPage = class;
  78. TfrReport = class;
  79. TfrExportFilter = class;
  80. TDetailEvent = procedure(const ParName: String; var ParValue: Variant) of object;
  81. TEnterRectEvent = procedure(Memo: TStringList; View: TfrView) of object;
  82. TBeginDocEvent = procedure of object;
  83. TEndDocEvent = procedure of object;
  84. TBeginPageEvent = procedure(pgNo: Integer) of object;
  85. TEndPageEvent = procedure(pgNo: Integer) of object;
  86. TBeginBandEvent = procedure(Band: TfrBand) of object;
  87. TEndBandEvent = procedure(Band: TfrBand) of object;
  88. TProgressEvent = procedure(n: Integer) of object;
  89. TBeginColumnEvent = procedure(Band: TfrBand) of object;
  90. TPrintColumnEvent = procedure(ColNo: Integer; var Width: Integer) of object;
  91. TManualBuildEvent = procedure(Page: TfrPage) of object;
  92. TfrHighlightAttr = packed record
  93. FontStyle: Word;
  94. FontColor, FillColor: TColor;
  95. end;
  96. TfrPrnInfo = record // print info about page size, margins e.t.c
  97. PPgw, PPgh, Pgw, Pgh: Integer; // page width/height (printer/screen)
  98. POfx, POfy, Ofx, Ofy: Integer; // offset x/y
  99. PPw, PPh, Pw, Ph: Integer; // printable width/height
  100. end;
  101. PfrPageInfo = ^TfrPageInfo;
  102. TfrPageInfo = packed record // pages of a preview
  103. R: TRect;
  104. pgSize: Word;
  105. pgWidth, pgHeight: Integer;
  106. pgOr: TPrinterOrientation;
  107. pgMargins: Boolean;
  108. PrnInfo: TfrPrnInfo;
  109. Visible: Boolean;
  110. Stream: TMemoryStream;
  111. Page: TfrPage;
  112. end;
  113. PfrBandRec = ^TfrBandRec;
  114. TfrBandRec = packed record
  115. Band: TfrBand;
  116. Action: TfrBandRecType;
  117. end;
  118. TfrView = class(TObject)
  119. private
  120. procedure P1Click(Sender: TObject);
  121. protected
  122. SaveX, SaveY, SaveDX, SaveDY: Integer;
  123. SaveFW: Single;
  124. BaseName: String;
  125. Canvas: TCanvas;
  126. DRect: TRect;
  127. gapx, gapy: Integer;
  128. Memo1: TStringList;
  129. FDataSet: TfrTDataSet;
  130. FField: String;
  131. olddy: Integer;
  132. StreamMode: (smDesigning, smPrinting);
  133. procedure ShowBackGround; virtual;
  134. procedure ShowFrame; virtual;
  135. procedure BeginDraw(ACanvas: TCanvas);
  136. procedure GetBlob(b: TfrTField); virtual;
  137. procedure OnHook(View: TfrView); virtual;
  138. public
  139. Parent: TfrBand;
  140. Name: String;
  141. ID: Integer;
  142. Typ: Byte;
  143. Selected: Boolean;
  144. OriginalRect: TRect;
  145. ScaleX, ScaleY: Double; // used for scaling objects in preview
  146. OffsX, OffsY: Integer; //
  147. IsPrinting: Boolean;
  148. x, y, dx, dy: Integer;
  149. Flags: Word;
  150. FrameTyp: Word;
  151. FrameWidth: Single;
  152. FrameColor: TColor;
  153. FrameStyle: Word;
  154. FillColor: TColor;
  155. Format: Integer;
  156. FormatStr: String;
  157. Visible: WordBool;
  158. Memo, Script: TStringList;
  159. constructor Create; virtual;
  160. destructor Destroy; override;
  161. procedure Assign(From: TfrView); virtual;
  162. procedure CalcGaps; virtual;
  163. procedure RestoreCoord; virtual;
  164. procedure Draw(Canvas: TCanvas); virtual; abstract;
  165. procedure Print(Stream: TStream); virtual;
  166. procedure ExportData; virtual;
  167. procedure LoadFromStream(Stream: TStream); virtual;
  168. procedure SaveToStream(Stream: TStream); virtual;
  169. procedure SaveToFR3Stream(Stream: TStream); virtual;
  170. procedure Resized; virtual;
  171. procedure DefinePopupMenu(Popup: TPopupMenu); virtual;
  172. function GetClipRgn(rt: TfrRgnType): HRGN; virtual;
  173. procedure CreateUniqueName;
  174. procedure SetBounds(Left, Top, Width, Height: Integer);
  175. end;
  176. TfrStretcheable = class(TfrView)
  177. protected
  178. ActualHeight: Integer;
  179. DrawMode: TfrDrawMode;
  180. function CalcHeight: Integer; virtual; abstract;
  181. function MinHeight: Integer; virtual; abstract;
  182. function RemainHeight: Integer; virtual; abstract;
  183. end;
  184. TfrMemoView = class(TfrStretcheable)
  185. private
  186. FFont: TFont;
  187. procedure P1Click(Sender: TObject);
  188. procedure P2Click(Sender: TObject);
  189. procedure P3Click(Sender: TObject);
  190. procedure P4Click(Sender: TObject);
  191. procedure P5Click(Sender: TObject);
  192. procedure SetFont(Value: TFont);
  193. protected
  194. Streaming: Boolean;
  195. TextHeight: Integer;
  196. CurStrNo: Integer;
  197. Exporting: Boolean;
  198. procedure ExpandVariables;
  199. procedure AssignFont(Canvas: TCanvas);
  200. procedure WrapMemo;
  201. procedure ShowMemo;
  202. function CalcWidth(Memo: TStringList): Integer;
  203. function CalcHeight: Integer; override;
  204. function MinHeight: Integer; override;
  205. function RemainHeight: Integer; override;
  206. procedure GetBlob(b: TfrTField); override;
  207. public
  208. Adjust: Integer;
  209. Highlight: TfrHighlightAttr;
  210. HighlightStr: String;
  211. LineSpacing, CharacterSpacing: Integer;
  212. constructor Create; override;
  213. destructor Destroy; override;
  214. procedure Assign(From: TfrView); override;
  215. procedure Draw(Canvas: TCanvas); override;
  216. procedure Print(Stream: TStream); override;
  217. procedure ExportData; override;
  218. procedure LoadFromStream(Stream: TStream); override;
  219. procedure SaveToStream(Stream: TStream); override;
  220. procedure SaveToFR3Stream(Stream: TStream); override;
  221. procedure DefinePopupMenu(Popup: TPopupMenu); override;
  222. property Font: TFont read FFont write SetFont;
  223. end;
  224. TfrBandView = class(TfrView)
  225. private
  226. procedure P1Click(Sender: TObject);
  227. procedure P2Click(Sender: TObject);
  228. procedure P3Click(Sender: TObject);
  229. procedure P4Click(Sender: TObject);
  230. procedure P5Click(Sender: TObject);
  231. procedure P6Click(Sender: TObject);
  232. function GetBandType: TfrBandType;
  233. procedure SetBandType(const Value: TfrBandType);
  234. public
  235. constructor Create; override;
  236. procedure Draw(Canvas: TCanvas); override;
  237. procedure DefinePopupMenu(Popup: TPopupMenu); override;
  238. function GetClipRgn(rt: TfrRgnType): HRGN; override;
  239. procedure SaveToFR3Stream(Stream: TStream); override;
  240. property BandType: TfrBandType read GetBandType write SetBandType;
  241. property DataSet: String read FormatStr write FormatStr;
  242. property GroupCondition: String read FormatStr write FormatStr;
  243. end;
  244. TfrSubReportView = class(TfrView)
  245. public
  246. SubPage: Integer;
  247. constructor Create; override;
  248. procedure Assign(From: TfrView); override;
  249. procedure Draw(Canvas: TCanvas); override;
  250. procedure LoadFromStream(Stream: TStream); override;
  251. procedure SaveToStream(Stream: TStream); override;
  252. procedure SaveToFR3Stream(Stream: TStream); override;
  253. procedure DefinePopupMenu(Popup: TPopupMenu); override;
  254. end;
  255. TfrPictureView = class(TfrView)
  256. private
  257. procedure P1Click(Sender: TObject);
  258. procedure P2Click(Sender: TObject);
  259. protected
  260. procedure GetBlob(b: TfrTField); override;
  261. public
  262. Picture: TPicture;
  263. constructor Create; override;
  264. destructor Destroy; override;
  265. procedure Assign(From: TfrView); override;
  266. procedure Draw(Canvas: TCanvas); override;
  267. procedure LoadFromStream(Stream: TStream); override;
  268. procedure SaveToStream(Stream: TStream); override;
  269. procedure SaveToFR3Stream(Stream: TStream); override;
  270. procedure DefinePopupMenu(Popup: TPopupMenu); override;
  271. end;
  272. TfrLineView = class(TfrView)
  273. public
  274. constructor Create; override;
  275. procedure Draw(Canvas: TCanvas); override;
  276. procedure DefinePopupMenu(Popup: TPopupMenu); override;
  277. function GetClipRgn(rt: TfrRgnType): HRGN; override;
  278. procedure SaveToFR3Stream(Stream: TStream); override;
  279. end;
  280. TfrBand = class(TObject)
  281. private
  282. Parent: TfrPage;
  283. View: TfrView;
  284. Flags: Word;
  285. Next, Prev: TfrBand;
  286. SubIndex, MaxY: Integer;
  287. EOFReached: Boolean;
  288. EOFArr: Array[0..31] of Boolean;
  289. Positions: Array[TfrDatasetPosition] of Integer;
  290. LastGroupValue: Variant;
  291. HeaderBand, FooterBand, LastBand: TfrBand;
  292. Values: TStringList;
  293. Count: Integer;
  294. DisableInit: Boolean;
  295. CalculatedHeight: Integer;
  296. procedure InitDataSet(Desc: String);
  297. procedure DoError;
  298. function CalcHeight: Integer;
  299. procedure StretchObjects(MaxHeight: Integer);
  300. procedure UnStretchObjects;
  301. procedure DrawObject(t: TfrView);
  302. procedure PrepareSubReports;
  303. procedure DoSubReports;
  304. function DrawObjects: Boolean;
  305. procedure DrawCrossCell(Parnt: TfrBand; CurX: Integer);
  306. procedure DrawCross;
  307. function CheckPageBreak(y, dy: Integer; PBreak: Boolean): Boolean;
  308. procedure DrawPageBreak;
  309. function HasCross: Boolean;
  310. function DoCalcHeight: Integer;
  311. procedure DoDraw;
  312. function Draw: Boolean;
  313. procedure InitValues;
  314. procedure DoAggregate;
  315. public
  316. x, y, dx, dy, maxdy: Integer;
  317. Typ: TfrBandType;
  318. PrintIfSubsetEmpty, NewPageAfter, Stretched, PageBreak, Visible: Boolean;
  319. Objects: TList;
  320. Memo, Script: TStringList;
  321. DataSet: TfrDataSet;
  322. IsVirtualDS: Boolean;
  323. VCDataSet: TfrDataSet;
  324. IsVirtualVCDS: Boolean;
  325. GroupCondition: String;
  326. ForceNewPage, ForceNewColumn: Boolean;
  327. constructor Create(ATyp: TfrBandType; AParent: TfrPage);
  328. destructor Destroy; override;
  329. end;
  330. TfrValue = class
  331. public
  332. Typ: TfrValueType;
  333. OtherKind: Integer; // for vtOther - typ, for vtDBField - format
  334. DataSet: String; // for vtDBField
  335. Field: String; // here is an expression for vtOther
  336. DSet: TfrTDataSet;
  337. end;
  338. TfrValues = class(TPersistent)
  339. private
  340. FItems: TStringList;
  341. function GetValue(Index: Integer): TfrValue;
  342. public
  343. constructor Create; virtual;
  344. destructor Destroy; override;
  345. function AddValue: Integer;
  346. function FindVariable(const s: String): TfrValue;
  347. procedure ReadBinaryData(Stream: TStream);
  348. procedure WriteBinaryData(Stream: TStream);
  349. procedure Clear;
  350. property Items: TStringList read FItems write FItems;
  351. property Objects[Index: Integer]: TfrValue read GetValue;
  352. end;
  353. TfrPage = class(TObject)
  354. private
  355. Bands: Array[TfrBandType] of TfrBand;
  356. Skip, InitFlag: Boolean;
  357. CurColumn, LastStaticColumnY, XAdjust: Integer;
  358. List: TList;
  359. Mode: TfrPageMode;
  360. PlayFrom: Integer;
  361. LastBand: TfrBand;
  362. ColPos, CurPos: Integer;
  363. procedure InitReport;
  364. procedure DoneReport;
  365. procedure TossObjects;
  366. procedure PrepareObjects;
  367. procedure FormPage;
  368. procedure DoAggregate(a: Array of TfrBandType);
  369. procedure AddRecord(b: TfrBand; rt: TfrBandRecType);
  370. procedure ClearRecList;
  371. function PlayRecList: Boolean;
  372. procedure DrawPageFooters;
  373. function BandExists(b: TfrBand): Boolean;
  374. procedure AfterPrint;
  375. procedure LoadFromStream(Stream: TStream);
  376. procedure SaveToStream(Stream: TStream);
  377. procedure ShowBand(b: TfrBand);
  378. public
  379. pgSize, pgWidth, pgHeight: Integer;
  380. pgMargins: TRect;
  381. pgOr: TPrinterOrientation;
  382. PrintToPrevPage, UseMargins: WordBool;
  383. PrnInfo: TfrPrnInfo;
  384. ColCount, ColWidth, ColGap: Integer;
  385. Objects, RTObjects: TList;
  386. CurY, CurBottomY: Integer;
  387. constructor Create(ASize, AWidth, AHeight: Integer; AOr: TPrinterOrientation);
  388. destructor Destroy; override;
  389. function TopMargin: Integer;
  390. function BottomMargin: Integer;
  391. function LeftMargin: Integer;
  392. function RightMargin: Integer;
  393. procedure Clear;
  394. procedure Delete(Index: Integer);
  395. function FindObjectByID(ID: Integer): Integer;
  396. function FindObject(Name: String): TfrView;
  397. function FindRTObject(Name: String): TfrView;
  398. procedure ChangePaper(ASize, AWidth, AHeight: Integer; AOr: TPrinterOrientation);
  399. procedure ShowBandByName(s: String);
  400. procedure ShowBandByType(bt: TfrBandType);
  401. procedure NewPage;
  402. procedure NewColumn(Band: TfrBand);
  403. end;
  404. TfrPages = class(TObject)
  405. private
  406. FPages: TList;
  407. Parent: TfrReport;
  408. function GetCount: Integer;
  409. function GetPages(Index: Integer): TfrPage;
  410. public
  411. constructor Create(AParent: TfrReport);
  412. destructor Destroy; override;
  413. procedure Clear;
  414. procedure Add;
  415. procedure Delete(Index: Integer);
  416. procedure LoadFromStream(Stream: TStream);
  417. procedure SaveToStream(Stream: TStream);
  418. property Pages[Index: Integer]: TfrPage read GetPages; default;
  419. property Count: Integer read GetCount;
  420. end;
  421. TfrEMFPages = class(TObject)
  422. private
  423. FPages: TList;
  424. Parent: TfrReport;
  425. function GetCount: Integer;
  426. function GetPages(Index: Integer): PfrPageInfo;
  427. procedure ExportData(Index: Integer);
  428. procedure PageToObjects(Index: Integer);
  429. procedure ObjectsToPage(Index: Integer);
  430. public
  431. constructor Create(AParent: TfrReport);
  432. destructor Destroy; override;
  433. procedure Clear;
  434. procedure Draw(Index: Integer; Canvas: TCanvas; DrawRect: TRect);
  435. procedure Add(APage: TfrPage);
  436. procedure Insert(Index: Integer; APage: TfrPage);
  437. procedure Delete(Index: Integer);
  438. procedure LoadFromStream(AStream: TStream);
  439. procedure SaveToStream(AStream: TStream);
  440. property Pages[Index: Integer]: PfrPageInfo read GetPages; default;
  441. property Count: Integer read GetCount;
  442. end;
  443. TfrReport = class(TComponent)
  444. private
  445. FPages: TfrPages;
  446. FEMFPages: TfrEMFPages;
  447. FVars: TStrings;
  448. FVal: TfrValues;
  449. FDataset: TfrDataset;
  450. FGrayedButtons: Boolean;
  451. FReportType: TfrReportType;
  452. FTitle: String;
  453. FShowProgress: Boolean;
  454. FModalPreview: Boolean;
  455. FModifyPrepared: Boolean;
  456. FStoreInDFM: Boolean;
  457. FPreview: TfrPreview;
  458. FPreviewButtons: TfrPreviewButtons;
  459. FInitialZoom: TfrPreviewZoom;
  460. FOnBeginDoc: TBeginDocEvent;
  461. FOnEndDoc: TEndDocEvent;
  462. FOnBeginPage: TBeginPageEvent;
  463. FOnEndPage: TEndPageEvent;
  464. FOnBeginBand: TBeginBandEvent;
  465. FOnEndBand: TEndBandEvent;
  466. FOnGetValue: TDetailEvent;
  467. FOnEnterRect: TEnterRectEvent;
  468. FOnProgress: TProgressEvent;
  469. FOnFunction: TFunctionEvent;
  470. FOnBeginColumn: TBeginColumnEvent;
  471. FOnPrintColumn: TPrintColumnEvent;
  472. FOnManualBuild: TManualBuildEvent;
  473. FCurrentFilter: TfrExportFilter;
  474. FPageNumbers: String;
  475. FCopies: Integer;
  476. FCurPage: TfrPage;
  477. function FormatValue(V: Variant; Format: Integer;
  478. const FormatStr: String): String;
  479. procedure OnGetParsFunction(const name: String; p1, p2, p3: Variant;
  480. var val: String);
  481. procedure PrepareDataSets;
  482. procedure BuildBeforeModal(Sender: TObject);
  483. procedure ExportBeforeModal(Sender: TObject);
  484. procedure PrintBeforeModal(Sender: TObject);
  485. function DoPrepareReport: Boolean;
  486. procedure DoBuildReport; virtual;
  487. procedure DoPrintReport(PageNumbers: String; Copies: Integer);
  488. procedure SetPrinterTo(PrnName: String);
  489. procedure SetVars(Value: TStrings);
  490. protected
  491. procedure DefineProperties(Filer: TFiler); override;
  492. procedure ReadBinaryData(Stream: TStream);
  493. procedure WriteBinaryData(Stream: TStream);
  494. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  495. public
  496. CanRebuild: Boolean; // true, if report can be rebuilded
  497. Terminated: Boolean;
  498. PrintToDefault, DoublePass: WordBool;
  499. FinalPass: Boolean;
  500. FileName: String;
  501. FR3Stream: Boolean;
  502. constructor Create(AOwner: TComponent); override;
  503. destructor Destroy; override;
  504. // service methods
  505. function FindVariable(Variable: String): Integer;
  506. procedure GetVariableValue(const s: String; var v: Variant);
  507. procedure GetVarList(CatNo: Integer; List: TStrings);
  508. procedure GetCategoryList(List: TStrings);
  509. function FindObject(Name: String): TfrView;
  510. // internal events used through report building
  511. procedure InternalOnEnterRect(Memo: TStringList; View: TfrView);
  512. procedure InternalOnExportData(View: TfrView);
  513. procedure InternalOnExportText(x, y: Integer; const text: String; View: TfrView);
  514. procedure InternalOnGetValue(ParName: String; var ParValue: String);
  515. procedure InternalOnProgress(Percent: Integer);
  516. procedure InternalOnBeginColumn(Band: TfrBand);
  517. procedure InternalOnPrintColumn(ColNo: Integer; var ColWidth: Integer);
  518. procedure FillQueryParams;
  519. // load/save methods
  520. procedure LoadFromStream(Stream: TStream);
  521. procedure SaveToStream(Stream: TStream);
  522. procedure LoadFromFile(FName: String);
  523. procedure SaveToFile(FName: String);
  524. procedure SaveToFR3File(FName: String);
  525. {$IFDEF IBO}
  526. procedure LoadFromDB(Table: TIB_DataSet; DocN: Integer);
  527. procedure SaveToDB(Table: TIB_DataSet; DocN: Integer);
  528. {$ELSE}
  529. procedure LoadFromDB(Table: TDataSet; DocN: Integer);
  530. procedure SaveToDB(Table: TDataSet; DocN: Integer);
  531. {$ENDIF}
  532. procedure LoadTemplate(fname: String; comm: TStrings;
  533. Bmp: TBitmap; Load: Boolean);
  534. procedure SaveTemplate(fname: String; comm: TStrings; Bmp: TBitmap);
  535. procedure LoadPreparedReport(FName: String);
  536. procedure SavePreparedReport(FName: String);
  537. // report manipulation methods
  538. procedure DesignReport;
  539. function PrepareReport: Boolean;
  540. procedure ExportTo(Filter: TClass; FileName: String);
  541. procedure ShowReport;
  542. procedure ShowPreparedReport;
  543. procedure PrintPreparedReport(PageNumbers: String; Copies: Integer);
  544. function ChangePrinter(OldIndex, NewIndex: Integer): Boolean;
  545. procedure EditPreparedReport(PageIndex: Integer);
  546. //
  547. property Pages: TfrPages read FPages;
  548. property EMFPages: TfrEMFPages read FEMFPages write FEMFPages;
  549. property Variables: TStrings read FVars write SetVars;
  550. property Values: TfrValues read FVal write FVal;
  551. published
  552. property Dataset: TfrDataset read FDataset write FDataset;
  553. property GrayedButtons: Boolean read FGrayedButtons write FGrayedButtons default False;
  554. property InitialZoom: TfrPreviewZoom read FInitialZoom write FInitialZoom;
  555. property ModalPreview: Boolean read FModalPreview write FModalPreview default True;
  556. property ModifyPrepared: Boolean read FModifyPrepared write FModifyPrepared default True;
  557. property Preview: TfrPreview read FPreview write FPreview;
  558. property PreviewButtons: TfrPreviewButtons read FPreviewButtons write FPreviewButtons;
  559. property ReportType: TfrReportType read FReportType write FReportType default rtSimple;
  560. property ShowProgress: Boolean read FShowProgress write FShowProgress default True;
  561. property StoreInDFM: Boolean read FStoreInDFM write FStoreInDFM default False;
  562. property Title: String read FTitle write FTitle;
  563. property OnBeginDoc: TBeginDocEvent read FOnBeginDoc write FOnBeginDoc;
  564. property OnEndDoc: TEndDocEvent read FOnEndDoc write FOnEndDoc;
  565. property OnBeginPage: TBeginPageEvent read FOnBeginPage write FOnBeginPage;
  566. property OnEndPage: TEndPageEvent read FOnEndPage write FOnEndPage;
  567. property OnBeginBand: TBeginBandEvent read FOnBeginBand write FOnBeginBand;
  568. property OnEndBand: TEndBandEvent read FOnEndBand write FOnEndBand;
  569. property OnGetValue: TDetailEvent read FOnGetValue write FOnGetValue;
  570. property OnEnterRect: TEnterRectEvent read FOnEnterRect write FOnEnterRect;
  571. property OnUserFunction: TFunctionEvent read FOnFunction write FOnFunction;
  572. property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
  573. property OnBeginColumn: TBeginColumnEvent read FOnBeginColumn write FOnBeginColumn;
  574. property OnPrintColumn: TPrintColumnEvent read FOnPrintColumn write FOnPrintColumn;
  575. property OnManualBuild: TManualBuildEvent read FOnManualBuild write FOnManualBuild;
  576. end;
  577. TfrCompositeReport = class(TfrReport)
  578. private
  579. procedure DoBuildReport; override;
  580. public
  581. Reports: TList;
  582. constructor Create(AOwner: TComponent); override;
  583. destructor Destroy; override;
  584. end;
  585. TfrReportDesigner = class(TForm)
  586. public
  587. Page: TfrPage;
  588. Modified: Boolean;
  589. procedure RegisterObject(ButtonBmp: TBitmap; const ButtonHint: String;
  590. ButtonTag: Integer); virtual; abstract;
  591. procedure RegisterTool(MenuCaption: String; ButtonBmp: TBitmap;
  592. OnClick: TNotifyEvent); virtual; abstract;
  593. procedure BeforeChange; virtual; abstract;
  594. procedure AfterChange; virtual; abstract;
  595. procedure RedrawPage; virtual; abstract;
  596. end;
  597. TfrDataManager = class(TObject)
  598. public
  599. procedure LoadFromStream(Stream: TStream); virtual; abstract;
  600. procedure SaveToStream(Stream: TStream); virtual; abstract;
  601. procedure BeforePreparing; virtual; abstract;
  602. procedure AfterPreparing; virtual; abstract;
  603. procedure PrepareDataSet(ds: TfrTDataSet); virtual; abstract;
  604. function ShowParamsDialog: Boolean; virtual; abstract;
  605. procedure AfterParamsDialog; virtual; abstract;
  606. end;
  607. TfrObjEditorForm = class(TForm)
  608. public
  609. procedure ShowEditor(t: TfrView); virtual;
  610. end;
  611. TfrExportFilter = class(TObject)
  612. protected
  613. Stream: TStream;
  614. Lines: TList;
  615. procedure ClearLines;
  616. public
  617. constructor Create(AStream: TStream); virtual;
  618. destructor Destroy; override;
  619. procedure OnBeginDoc; virtual;
  620. procedure OnEndDoc; virtual;
  621. procedure OnBeginPage; virtual;
  622. procedure OnEndPage; virtual;
  623. procedure OnData(x, y: Integer; View: TfrView); virtual;
  624. procedure OnText(x, y: Integer; const text: String; View: TfrView); virtual;
  625. end;
  626. TfrFunctionLibrary = class(TObject)
  627. public
  628. List: TStringList;
  629. constructor Create; virtual;
  630. destructor Destroy; override;
  631. function OnFunction(const FName: String; p1, p2, p3: Variant;
  632. var val: String): Boolean;
  633. procedure DoFunction(FNo: Integer; p1, p2, p3: Variant; var val: String);
  634. virtual; abstract;
  635. end;
  636. TfrCompressor = class(TObject)
  637. public
  638. Enabled: Boolean;
  639. procedure Compress(StreamIn, StreamOut: TStream); virtual;
  640. procedure DeCompress(StreamIn, StreamOut: TStream); virtual;
  641. end;
  642. function frCreateObject(Typ: Byte; const ClassName: String): TfrView;
  643. procedure frRegisterObject(ClassRef: TClass; ButtonBmp: TBitmap;
  644. const ButtonHint: String; EditorForm: TfrObjEditorForm);
  645. procedure frRegisterExportFilter(ClassRef: TClass;
  646. const FilterDesc, FilterExt: String);
  647. procedure frRegisterFunctionLibrary(ClassRef: TClass);
  648. procedure frRegisterTool(MenuCaption: String; ButtonBmp: TBitmap; OnClick: TNotifyEvent);
  649. function GetDefaultDataSet: TfrTDataSet;
  650. const
  651. frCurrentVersion = 23; // this is current version (2.3)
  652. frSpecCount = 9;
  653. frSpecFuncs: Array[0..frSpecCount - 1] of String = ('PAGE#', '',
  654. 'DATE', 'TIME', 'LINE#', 'LINETHROUGH#', 'COLUMN#', 'CURRENT#', 'TOTALPAGES');
  655. frColors: Array[0..15] of TColor =
  656. (clWhite, clBlack, clMaroon, clGreen, clOlive, clNavy, clPurple, clTeal,
  657. clGray, clSilver, clRed, clLime, clYellow, clBlue, clFuchsia, clAqua);
  658. type
  659. PfrTextRec = ^TfrTextRec;
  660. TfrTextRec = record
  661. Next: PfrTextRec;
  662. X: Integer;
  663. Text: String[255];
  664. FontName: String[32];
  665. FontSize, FontStyle, FontColor, FontCharset, FillColor: Integer;
  666. end;
  667. TfrAddInObjectInfo = record
  668. ClassRef: TClass;
  669. EditorForm: TfrObjEditorForm;
  670. ButtonBmp: TBitmap;
  671. ButtonHint: String;
  672. end;
  673. TfrExportFilterInfo = record
  674. ClassRef: TClass;
  675. FilterDesc, FilterExt: String;
  676. end;
  677. TfrFunctionInfo = record
  678. FunctionLibrary: TfrFunctionLibrary;
  679. end;
  680. TfrToolsInfo = record
  681. Caption: String;
  682. ButtonBmp: TBitmap;
  683. OnClick: TNotifyEvent;
  684. end;
  685. var
  686. frDesigner: TfrReportDesigner; // designer reference
  687. frDataManager: TfrDataManager; // data manager reference
  688. frParser: TfrParser; // parser reference
  689. frInterpretator: TfrInterpretator; // interpretator reference
  690. frVariables: TfrVariables; // report variables reference
  691. frCompressor: TfrCompressor; // compressor reference
  692. CurReport: TfrReport; // currently proceeded report
  693. MasterReport: TfrReport; // reference to main composite report
  694. CurView: TfrView; // currently proceeded view
  695. CurBand: TfrBand; // currently proceeded band
  696. CurPage: TfrPage; // currently proceeded page
  697. DocMode: (dmDesigning, dmPrinting); // current mode
  698. DisableDrawing: Boolean;
  699. frAddIns: Array[0..31] of TfrAddInObjectInfo; // add-in objects
  700. frAddInsCount: Integer;
  701. frFilters: Array[0..31] of TfrExportFilterInfo; // export filters
  702. frFiltersCount: Integer;
  703. frFunctions: Array[0..31] of TfrFunctionInfo; // function libraries
  704. frFunctionsCount: Integer;
  705. frTools: Array[0..31] of TfrToolsInfo; // tools
  706. frToolsCount: Integer;
  707. PageNo: Integer; // current page number in Building mode
  708. frCharset: 0..255;
  709. frBandNames: Array[0..21] of String;
  710. frSpecArr: Array[0..frSpecCount - 1] of String;
  711. frDateFormats, frTimeFormats: Array[0..3] of String;
  712. frVersion: Byte; // version of currently loaded report
  713. SMemo: TStringList; // temporary memo used during TfrView drawing
  714. ShowBandTitles: Boolean = True;
  715. (*
  716. FRE_COMPATIBLEREAD variable added for migrating from older versions
  717. of FreeReport and will be removed in next releases as soon as possible.
  718. *)
  719. {$IFDEF FREEREP2217READ}
  720. FRE_COMPATIBLE_READ: Boolean = False;
  721. {$ENDIF}
  722. implementation
  723. uses
  724. FR_Fmted, FR_Prntr, FR_Progr, FR_Utils, FR_Const
  725. {$IFDEF JPEG}, JPEG {$ENDIF};
  726. {$R FR_Lng1.RES}
  727. type
  728. TfrStdFunctionLibrary = class(TfrFunctionLibrary)
  729. public
  730. constructor Create; override;
  731. procedure DoFunction(FNo: Integer; p1, p2, p3: Variant; var val: String); override;
  732. end;
  733. TInterpretator = class(TfrInterpretator)
  734. public
  735. procedure GetValue(const Name: String; var Value: Variant); override;
  736. procedure SetValue(const Name: String; Value: Variant); override;
  737. procedure DoFunction(const name: String; p1, p2, p3: Variant;
  738. var val: String); override;
  739. end;
  740. var
  741. VHeight: Integer; // used for height calculation of TfrMemoView
  742. SBmp: TBitmap; // small bitmap used by TfrBandView drawing
  743. TempBmp: TBitmap; // temporary bitmap used by TfrMemoView
  744. CurDate, CurTime: TDateTime; // date/time of report starting
  745. CurValue: Variant; // used for highlighting
  746. AggrBand: TfrBand; // used for aggregate functions
  747. CurVariable: String;
  748. IsColumns: Boolean;
  749. SavedAllPages: Integer; // number of pages in entire report
  750. ErrorFlag: Boolean; // error occured through TfrView drawing
  751. ErrorStr: String; // error description
  752. SubValue: String; // used in GetValue event handler
  753. ObjID: Integer = 0;
  754. BoolStr: Array[0..3] of String;
  755. HookList: TList;
  756. // variables used through report building
  757. PrevY, PrevBottomY, ColumnXAdjust: Integer;
  758. Append, WasPF: Boolean;
  759. CompositeMode: Boolean;
  760. {----------------------------------------------------------------------------}
  761. function frCreateObject(Typ: Byte; const ClassName: String): TfrView;
  762. var
  763. i: Integer;
  764. begin
  765. Result := nil;
  766. case Typ of
  767. gtMemo: Result := TfrMemoView.Create;
  768. gtPicture: Result := TfrPictureView.Create;
  769. gtBand: Result := TfrBandView.Create;
  770. gtSubReport: Result := TfrSubReportView.Create;
  771. gtLine: Result := TfrLineView.Create;
  772. gtAddIn:
  773. begin
  774. for i := 0 to frAddInsCount - 1 do
  775. if frAddIns[i].ClassRef.ClassName = ClassName then
  776. begin
  777. Result := TfrView(frAddIns[i].ClassRef.NewInstance);
  778. Result.Create;
  779. Result.Typ := gtAddIn;
  780. break;
  781. end;
  782. if Result = nil then
  783. raise EClassNotFound.Create('Íå íàéäåí êëàññ ' + ClassName);
  784. end;
  785. end;
  786. if Result <> nil then
  787. begin
  788. Result.ID := ObjID;
  789. Inc(ObjID);
  790. end;
  791. end;
  792. procedure frRegisterObject(ClassRef: TClass; ButtonBmp: TBitmap;
  793. const ButtonHint: String; EditorForm: TfrObjEditorForm);
  794. begin
  795. frAddIns[frAddInsCount].ClassRef := ClassRef;
  796. frAddIns[frAddInsCount].EditorForm := EditorForm;
  797. frAddIns[frAddInsCount].ButtonBmp := ButtonBmp;
  798. frAddIns[frAddInsCount].ButtonHint := ButtonHint;
  799. if frDesigner <> nil then
  800. frDesigner.RegisterObject(ButtonBmp, ButtonHint,
  801. Integer(gtAddIn) + frAddInsCount);
  802. Inc(frAddInsCount);
  803. end;
  804. procedure frRegisterExportFilter(ClassRef: TClass;
  805. const FilterDesc, FilterExt: String);
  806. begin
  807. frFilters[frFiltersCount].ClassRef := ClassRef;
  808. frFilters[frFiltersCount].FilterDesc := FilterDesc;
  809. frFilters[frFiltersCount].FilterExt := FilterExt;
  810. Inc(frFiltersCount);
  811. end;
  812. procedure frRegisterFunctionLibrary(ClassRef: TClass);
  813. begin
  814. frFunctions[frFunctionsCount].FunctionLibrary :=
  815. TfrFunctionLibrary(ClassRef.NewInstance);
  816. frFunctions[frFunctionsCount].FunctionLibrary.Create;
  817. Inc(frFunctionsCount);
  818. end;
  819. procedure frRegisterTool(MenuCaption: String; ButtonBmp: TBitmap; OnClick: TNotifyEvent);
  820. begin
  821. frTools[frToolsCount].Caption := MenuCaption;
  822. frTools[frToolsCount].ButtonBmp := ButtonBmp;
  823. frTools[frToolsCount].OnClick := OnClick;
  824. if frDesigner <> nil then
  825. frDesigner.RegisterTool(MenuCaption, ButtonBmp, OnClick);
  826. Inc(frToolsCount);
  827. end;
  828. function Create90Font(Font: TFont): HFont;
  829. var
  830. F: TLogFont;
  831. begin
  832. GetObject(Font.Handle, SizeOf(TLogFont), @F);
  833. F.lfEscapement := 900;
  834. F.lfOrientation := 900;
  835. Result := CreateFontIndirect(F);
  836. end;
  837. function GetDefaultDataSet: TfrTDataSet;
  838. var
  839. Res: TfrDataset;
  840. begin
  841. Result := nil; Res := nil;
  842. if CurBand <> nil then
  843. case CurBand.Typ of
  844. btMasterData, btReportSummary, btMasterFooter,
  845. btGroupHeader, btGroupFooter:
  846. Res := CurPage.Bands[btMasterData].DataSet;
  847. btDetailData, btDetailFooter:
  848. Res := CurPage.Bands[btDetailData].DataSet;
  849. btSubDetailData, btSubDetailFooter:
  850. Res := CurPage.Bands[btSubDetailData].DataSet;
  851. btCrossData, btCrossFooter:
  852. Res := CurPage.Bands[btCrossData].DataSet;
  853. end;
  854. if (Res <> nil) and (Res is TfrDBDataset) then
  855. Result := TfrDBDataSet(Res).GetDataSet;
  856. end;
  857. function ReadString(Stream: TStream): String;
  858. begin
  859. if frVersion >= 23 then
  860. {$IFDEF FREEREP2217READ}
  861. Result := frReadString(Stream) // load in current format
  862. else
  863. if (frVersion = 22) and FRE_COMPATIBLE_READ then
  864. Result := frReadString2217(Stream) // load in bad format
  865. else
  866. {$ELSE}
  867. Result := frReadString(Stream) else
  868. {$ENDIF}
  869. Result := frReadString22(Stream);
  870. end;
  871. procedure ReadMemo(Stream: TStream; Memo: TStrings);
  872. begin
  873. if frVersion >= 23 then
  874. {$IFDEF FREEREP2217READ}
  875. frReadMemo(Stream, Memo) // load in current format
  876. else
  877. if (frVersion = 22) and FRE_COMPATIBLE_READ then
  878. Memo.Text := frReadString2217(Stream) // load in bad format
  879. else
  880. {$ELSE}
  881. frReadMemo(Stream, Memo) else
  882. {$ENDIF}
  883. frReadMemo22(Stream, Memo);
  884. end;
  885. procedure CreateDS(Desc: String; var DataSet: TfrDataSet; var IsVirtualDS: Boolean);
  886. begin
  887. if (Desc <> '') and (Desc[1] in ['1'..'9']) then
  888. begin
  889. DataSet := TfrUserDataSet.Create(nil);
  890. DataSet.RangeEnd := reCount;
  891. DataSet.RangeEndCount := StrToInt(Desc);
  892. IsVirtualDS := True;
  893. end
  894. else
  895. DataSet := frFindComponent(CurReport.Owner, Desc) as TfrDataSet;
  896. if DataSet <> nil then
  897. DataSet.Init;
  898. end;
  899. {----------------------------------------------------------------------------}
  900. constructor TfrView.Create;
  901. begin
  902. inherited Create;
  903. Parent := nil;
  904. Memo := TStringList.Create;
  905. Memo1 := TStringList.Create;
  906. Script := TStringList.Create;
  907. FrameWidth := 1;
  908. FrameColor := clBlack;
  909. FillColor := clNone;
  910. Format := 2*256 + Ord(DecimalSeparator);
  911. BaseName := 'View';
  912. Visible := True;
  913. StreamMode := smDesigning;
  914. ScaleX := 1; ScaleY := 1;
  915. OffsX := 0; OffsY := 0;
  916. Flags := flStretched;
  917. end;
  918. destructor TfrView.Destroy;
  919. begin
  920. Memo.Free;
  921. Memo1.Free;
  922. Script.Free;
  923. inherited Destroy;
  924. end;
  925. procedure TfrView.Assign(From: TfrView);
  926. begin
  927. Name := From.Name;
  928. Typ := From.Typ;
  929. Selected := From.Selected;
  930. x := From.x; y := From.y; dx := From.dx; dy := From.dy;
  931. Flags := From.Flags;
  932. FrameTyp := From.FrameTyp;
  933. FrameWidth := From.FrameWidth;
  934. FrameColor := From.FrameColor;
  935. FrameStyle := From.FrameStyle;
  936. FillColor := From.FillColor;
  937. Format := From.Format;
  938. FormatStr := From.FormatStr;
  939. Visible := From.Visible;
  940. Memo.Assign(From.Memo);
  941. Script.Assign(From.Script);
  942. end;
  943. procedure TfrView.CalcGaps;
  944. var
  945. bx, by, bx1, by1, wx1, wx2, wy1, wy2: Integer;
  946. begin
  947. SaveX := x; SaveY := y; SaveDX := dx; SaveDY := dy;
  948. SaveFW := FrameWidth;
  949. if DocMode = dmDesigning then
  950. begin
  951. ScaleX := 1; ScaleY := 1;
  952. OffsX := 0; OffsY := 0;
  953. end;
  954. x := Round(x * ScaleX) + OffsX;
  955. y := Round(y * ScaleY) + OffsY;
  956. dx := Round(dx * ScaleX);
  957. dy := Round(dy * ScaleY);
  958. wx1 := Round((FrameWidth * ScaleX - 1) / 2);
  959. wx2 := Round(FrameWidth * ScaleX / 2);
  960. wy1 := Round((FrameWidth * ScaleY - 1) / 2);
  961. wy2 := Round(FrameWidth * ScaleY / 2);
  962. FrameWidth := FrameWidth * ScaleX;
  963. gapx := wx2 + 2; gapy := wy2 div 2 + 1;
  964. bx := x;
  965. by := y;
  966. bx1 := Round((SaveX + SaveDX) * ScaleX + OffsX);
  967. by1 := Round((SaveY + SaveDY) * ScaleY + OffsY);
  968. if (FrameTyp and $1) <> 0 then Dec(bx1, wx2);
  969. if (FrameTyp and $2) <> 0 then Dec(by1, wy2);
  970. if (FrameTyp and $4) <> 0 then Inc(bx, wx1);
  971. if (FrameTyp and $8) <> 0 then Inc(by, wy1);
  972. DRect := Rect(bx, by, bx1 + 1, by1 + 1);
  973. end;
  974. procedure TfrView.RestoreCoord;
  975. begin
  976. x := SaveX;
  977. y := SaveY;
  978. dx := SaveDX;
  979. dy := SaveDY;
  980. FrameWidth := SaveFW;
  981. end;
  982. procedure TfrView.ShowBackground;
  983. var
  984. fp: TColor;
  985. begin
  986. if DisableDrawing then Exit;
  987. if (DocMode = dmPrinting) and (FillColor = clNone) then Exit;
  988. fp := FillColor;
  989. if (DocMode = dmDesigning) and (fp = clNone) then
  990. fp := clWhite;
  991. Canvas.Brush.Color := fp;
  992. if DocMode = dmDesigning then
  993. Canvas.FillRect(DRect) else
  994. Canvas.FillRect(Rect(x, y,
  995. // use calculating coords instead of dx, dy - for best view
  996. Round((SaveX + SaveDX) * ScaleX + OffsX), Round((SaveY + SaveDY) * ScaleY + OffsY)));
  997. end;
  998. procedure TfrView.ShowFrame;
  999. var
  1000. x1, y1: Integer;
  1001. procedure Line(x, y, dx, dy: Integer);
  1002. begin
  1003. Canvas.MoveTo(x, y);
  1004. Canvas.LineTo(x + dx, y + dy);
  1005. end;
  1006. procedure Line1(x, y, x1, y1: Integer);
  1007. var
  1008. i, w: Integer;
  1009. begin
  1010. if Canvas.Pen.Style = psSolid then
  1011. begin
  1012. if FrameStyle <> 5 then
  1013. begin
  1014. Canvas.MoveTo(x, y);
  1015. Canvas.LineTo(x1, y1);
  1016. end
  1017. else
  1018. begin
  1019. if x = x1 then
  1020. begin
  1021. Canvas.MoveTo(x - Round(FrameWidth), y);
  1022. Canvas.LineTo(x1 - Round(FrameWidth), y1);
  1023. Canvas.Pen.Color := FillColor;
  1024. Canvas.MoveTo(x, y);
  1025. Canvas.LineTo(x1, y1);
  1026. Canvas.Pen.Color := FrameColor;
  1027. Canvas.MoveTo(x + Round(FrameWidth), y);
  1028. Canvas.LineTo(x1 + Round(FrameWidth), y1);
  1029. end
  1030. else
  1031. begin
  1032. Canvas.MoveTo(x, y - Round(FrameWidth));
  1033. Canvas.LineTo(x1, y1 - Round(FrameWidth));
  1034. Canvas.Pen.Color := FillColor;
  1035. Canvas.MoveTo(x, y);
  1036. Canvas.LineTo(x1, y1);
  1037. Canvas.Pen.Color := FrameColor;
  1038. Canvas.MoveTo(x, y + Round(FrameWidth));
  1039. Canvas.LineTo(x1, y1 + Round(FrameWidth));
  1040. end;
  1041. end
  1042. end
  1043. else
  1044. begin
  1045. Canvas.Brush.Color := FillColor;
  1046. w := Canvas.Pen.Width;
  1047. Canvas.Pen.Width := 1;
  1048. if x = x1 then
  1049. for i := 0 to w - 1 do
  1050. begin
  1051. Canvas.MoveTo(x - w div 2 + i, y);
  1052. Canvas.LineTo(x - w div 2 + i, y1);
  1053. end
  1054. else
  1055. for i := 0 to w - 1 do
  1056. begin
  1057. Canvas.MoveTo(x, y - w div 2 + i);
  1058. Canvas.LineTo(x1, y - w div 2 + i);
  1059. end;
  1060. Canvas.Pen.Width := w;
  1061. end;
  1062. end;
  1063. begin
  1064. if DisableDrawing then Exit;
  1065. if (DocMode = dmPrinting) and ((FrameTyp and $F) = 0) then Exit;
  1066. with Canvas do
  1067. begin
  1068. Brush.Style := bsClear;
  1069. Pen.Style := psSolid;
  1070. if (dx > 0) and (dy > 0) and (DocMode = dmDesigning) then
  1071. begin
  1072. Pen.Color := clBlack;
  1073. Pen.Width := 1;
  1074. Line(x, y + 3, 0, -3); Line(x, y, 4, 0);
  1075. Line(x, y + dy - 3, 0, 3); Line(x, y + dy, 4, 0);
  1076. Line(x + dx - 3, y, 3, 0); Line(x + dx, y, 0, 4);
  1077. Line(x + dx - 3, y + dy, 3, 0); Line(x + dx, y + dy, 0, -4);
  1078. end;
  1079. Pen.Color := FrameColor;
  1080. Pen.Width := Round(FrameWidth);
  1081. if FrameStyle <> 5 then
  1082. Pen.Style := TPenStyle(FrameStyle);
  1083. // use calculating coords instead of dx, dy - for best view
  1084. x1 := Round((SaveX + SaveDX) * ScaleX + OffsX);
  1085. y1 := Round((SaveY + SaveDY) * ScaleY + OffsY);
  1086. if ((FrameTyp and $F) = $F) and (FrameStyle = 0) then
  1087. Rectangle(x, y, x1 + 1, y1 + 1)
  1088. else
  1089. begin
  1090. if (FrameTyp and $1) <> 0 then Line1(x1, y, x1, y1);
  1091. if (FrameTyp and $4) <> 0 then Line1(x, y, x, y1);
  1092. if (FrameTyp and $2) <> 0 then Line1(x, y1, x1, y1);
  1093. if (FrameTyp and $8) <> 0 then Line1(x, y, x1, y);
  1094. end;
  1095. end;
  1096. end;
  1097. procedure TfrView.BeginDraw(ACanvas: TCanvas);
  1098. begin
  1099. Canvas := ACanvas;
  1100. CurView := Self;
  1101. end;
  1102. procedure TfrView.Print(Stream: TStream);
  1103. begin
  1104. BeginDraw(Canvas);
  1105. Memo1.Assign(Memo);
  1106. CurReport.InternalOnEnterRect(Memo1, Self);
  1107. frInterpretator.DoScript(Script);
  1108. if not Visible then Exit;
  1109. Stream.Write(Typ, 1);
  1110. if Typ = gtAddIn then
  1111. frWriteString(Stream, ClassName);
  1112. SaveToStream(Stream);
  1113. end;
  1114. procedure TfrView.ExportData;
  1115. begin
  1116. CurReport.InternalOnExportData(Self);
  1117. end;
  1118. procedure TfrView.LoadFromStream(Stream: TStream);
  1119. var
  1120. w: Integer;
  1121. begin
  1122. with Stream do
  1123. begin
  1124. if StreamMode = smDesigning then
  1125. if frVersion >= 23 then
  1126. Name := ReadString(Stream) else
  1127. CreateUniqueName;
  1128. Read(x, 30); // this is equal to, but much faster:
  1129. { Read(x, 4); Read(y, 4); Read(dx, 4); Read(dy, 4);
  1130. Read(Flags, 2);
  1131. Read(FrameTyp, 2);
  1132. Read(FrameWidth, 4);
  1133. Read(FrameColor, 4);
  1134. Read(FrameStyle, 2);}
  1135. Read(FillColor, 4);
  1136. if StreamMode = smDesigning then
  1137. begin
  1138. Read(Format, 4);
  1139. FormatStr := ReadString(Stream);
  1140. end;
  1141. ReadMemo(Stream, Memo);
  1142. if (frVersion >= 23) and (StreamMode = smDesigning) then
  1143. begin
  1144. ReadMemo(Stream, Script);
  1145. Read(Visible, 2);
  1146. end;
  1147. w := PInteger(@FrameWidth)^;
  1148. if w <= 10 then
  1149. w := w * 1000;
  1150. FrameWidth := w / 1000;
  1151. end;
  1152. end;
  1153. procedure TfrView.SaveToStream(Stream: TStream);
  1154. var
  1155. w: Integer;
  1156. f: Single;
  1157. begin
  1158. f := FrameWidth;
  1159. if f <> Int(f) then
  1160. w := Round(FrameWidth * 1000) else
  1161. w := Round(f);
  1162. PInteger(@FrameWidth)^ := w;
  1163. with Stream do
  1164. begin
  1165. if StreamMode = smDesigning then
  1166. frWriteString(Stream, Name);
  1167. Write(x, 30); // this is equal to, but much faster:
  1168. { Write(x, 4); Write(y, 4); Write(dx, 4); Write(dy, 4);
  1169. Write(Flags, 2);
  1170. Write(FrameTyp, 2);
  1171. Write(FrameWidth, 4);
  1172. Write(FrameColor, 4);
  1173. Write(FrameStyle, 2);}
  1174. Write(FillColor, 4);
  1175. if StreamMode = smDesigning then
  1176. begin
  1177. Write(Format, 4);
  1178. frWriteString(Stream, FormatStr);
  1179. frWriteMemo(Stream, Memo);
  1180. end
  1181. else
  1182. frWriteMemo(Stream, Memo1);
  1183. if StreamMode = smDesigning then
  1184. begin
  1185. frWriteMemo(Stream, Script);
  1186. Write(Visible, 2);
  1187. end;
  1188. end;
  1189. FrameWidth := f;
  1190. end;
  1191. procedure TfrView.SaveToFR3Stream(Stream: TStream);
  1192. var
  1193. FTyp: Integer;
  1194. s: String;
  1195. procedure WriteStr(const s: String);
  1196. begin
  1197. Stream.Write(s[1], Length(s));
  1198. end;
  1199. begin
  1200. s := ClassName;
  1201. if Pos('Tfr', s) = 1 then
  1202. begin
  1203. Delete(s, 1, 3);
  1204. s := 'Tfrx' + s;
  1205. if CompareText(s, 'TfrxSubreportView') = 0 then
  1206. s := 'TfrxSubreport';
  1207. end;
  1208. WriteStr('<' + s + ' ');
  1209. WriteStr('Name="' + Name +
  1210. '" Left="' + IntToStr(x) + '" Top="' + IntToStr(y) +
  1211. '" Width="' + IntToStr(dx) + '" Height="' + IntToStr(dy) +
  1212. '" Color="' + IntToStr(FillColor) + '"');
  1213. if not Visible then
  1214. WriteStr(' Visible="False"');
  1215. FTyp := 0;
  1216. if (FrameTyp and frftLeft) <> 0 then
  1217. FTyp := FTyp or 1;
  1218. if (FrameTyp and frftRight) <> 0 then
  1219. FTyp := FTyp or 2;
  1220. if (FrameTyp and frftUp) <> 0 then
  1221. FTyp := FTyp or 4;
  1222. if (FrameTyp and frftDown) <> 0 then
  1223. FTyp := FTyp or 8;
  1224. WriteStr(' Frame.Typ="' + IntToStr(FTyp) +
  1225. '" Frame.Width="' + FloatToStr(FrameWidth) +
  1226. '" Frame.Color="' + IntToStr(FrameColor) +
  1227. '" Frame.Style="' + IntToStr(FrameStyle) +
  1228. '" GapX="' + IntToStr(gapx) + '" GapY="' + IntToStr(gapy) +
  1229. {'" TagStr="' + StrToXML(Tag) + }'" Memo.text="' + StrToXML(Memo.Text) + '"');
  1230. { ba := BandAlign;
  1231. if ba = baRest then
  1232. ba := baWidth
  1233. else if ba = baTop then
  1234. ba := baNone;
  1235. WriteStr(' Align="' + IntToStr(ba) + '"');}
  1236. if Script.Count > 0 then
  1237. WriteStr(' OnBeforePrint="' + Name + 'OnBeforePrint' +
  1238. '" OnClick="' + Name + 'OnBeforePrint' +
  1239. '" OnActivate="' + Name + 'OnBeforePrint"');
  1240. { RTyp := 0;
  1241. if ((Restrictions and frrfDontEditMemo) <> 0) or
  1242. ((Restrictions and frrfDontEditScript) <> 0) or
  1243. ((Restrictions and frrfDontEditContents) <> 0) or
  1244. ((Restrictions and frrfDontModify) <> 0) then
  1245. RTyp := RTyp or 1;
  1246. if (Restrictions and frrfDontSize) <> 0 then
  1247. RTyp := RTyp or 2;
  1248. if (Restrictions and frrfDontMove) <> 0 then
  1249. RTyp := RTyp or 4;
  1250. if (Restrictions and frrfDontDelete) <> 0 then
  1251. RTyp := RTyp or 8;
  1252. WriteStr(' Restrictions="' + IntToStr(RTyp) + '"');}
  1253. end;
  1254. procedure TfrView.Resized;
  1255. begin
  1256. end;
  1257. procedure TfrView.GetBlob(b: TfrTField);
  1258. begin
  1259. end;
  1260. procedure TfrView.OnHook(View: TfrView);
  1261. begin
  1262. end;
  1263. function TfrView.GetClipRgn(rt: TfrRgnType): HRGN;
  1264. var
  1265. bx, by, bx1, by1, w1, w2: Integer;
  1266. begin
  1267. if FrameStyle = 5 then
  1268. begin
  1269. w1 := Round(FrameWidth * 1.5);
  1270. w2 := Round((FrameWidth - 1) / 2 + FrameWidth);
  1271. end
  1272. else
  1273. begin
  1274. w1 := Round(FrameWidth / 2);
  1275. w2 := Round((FrameWidth - 1) / 2);
  1276. end;
  1277. bx := x; by := y; bx1 := x + dx + 1; by1 := y + dy + 1;
  1278. if (FrameTyp and $1) <> 0 then Inc(bx1, w2);
  1279. if (FrameTyp and $2) <> 0 then Inc(by1, w2);
  1280. if (FrameTyp and $4) <> 0 then Dec(bx, w1);
  1281. if (FrameTyp and $8) <> 0 then Dec(by, w1);
  1282. if rt = rtNormal then
  1283. Result := CreateRectRgn(bx, by, bx1, by1) else
  1284. Result := CreateRectRgn(bx - 10, by - 10, bx1 + 10, by1 + 10);
  1285. end;
  1286. procedure TfrView.CreateUniqueName;
  1287. var
  1288. i: Integer;
  1289. begin
  1290. Name := '';
  1291. for i := 1 to 10000 do
  1292. if CurReport.FindObject(BaseName + IntToStr(i)) = nil then
  1293. begin
  1294. Name := BaseName + IntToStr(i);
  1295. Exit;
  1296. end;
  1297. end;
  1298. procedure TfrView.SetBounds(Left, Top, Width, Height: Integer);
  1299. begin
  1300. x := Left;
  1301. y := Top;
  1302. dx := Width;
  1303. dy := Height;
  1304. end;
  1305. procedure TfrView.DefinePopupMenu(Popup: TPopupMenu);
  1306. var
  1307. m: TMenuItem;
  1308. begin
  1309. m := TMenuItem.Create(Popup);
  1310. m.Caption := '-';
  1311. Popup.Items.Add(m);
  1312. m := TMenuItem.Create(Popup);
  1313. m.Caption := LoadStr(SStretched);
  1314. m.OnClick := P1Click;
  1315. m.Checked := (Flags and flStretched) <> 0;
  1316. Popup.Items.Add(m);
  1317. end;
  1318. procedure TfrView.P1Click(Sender: TObject);
  1319. var
  1320. i: Integer;
  1321. t: TfrView;
  1322. begin
  1323. frDesigner.BeforeChange;
  1324. with Sender as TMenuItem do
  1325. begin
  1326. Checked := not Checked;
  1327. for i := 0 to frDesigner.Page.Objects.Count-1 do
  1328. begin
  1329. t := frDesigner.Page.Objects[i];
  1330. if t.Selected then
  1331. t.Flags := (t.Flags and not flStretched) + Word(Checked);
  1332. end;
  1333. end;
  1334. frDesigner.AfterChange;
  1335. end;
  1336. {----------------------------------------------------------------------------}
  1337. constructor TfrMemoView.Create;
  1338. begin
  1339. inherited Create;
  1340. Typ := gtMemo;
  1341. FFont := TFont.Create;
  1342. FFont.Name := 'Arial';
  1343. FFont.Size := 10;
  1344. FFont.Color := clBlack;
  1345. {$IFNDEF Delphi2}
  1346. FFont.Charset := frCharset;
  1347. {$ENDIF}
  1348. Highlight.FontColor := clBlack;
  1349. Highlight.FillColor := clWhite;
  1350. Highlight.FontStyle := 2; // fsBold
  1351. BaseName := 'Memo';
  1352. Flags := flStretched + flWordWrap;
  1353. LineSpacing := 2;
  1354. CharacterSpacing := 0;
  1355. end;
  1356. destructor TfrMemoView.Destroy;
  1357. begin
  1358. FFont.Free;
  1359. inherited Destroy;
  1360. end;
  1361. procedure TfrMemoView.SetFont(Value: TFont);
  1362. begin
  1363. FFont.Assign(Value);
  1364. end;
  1365. procedure TfrMemoView.Assign(From: TfrView);
  1366. begin
  1367. inherited Assign(From);
  1368. Font := TfrMemoView(From).Font;
  1369. Adjust := TfrMemoView(From).Adjust;
  1370. Highlight := TfrMemoView(From).Highlight;
  1371. HighlightStr := TfrMemoView(From).HighlightStr;
  1372. LineSpacing := TfrMemoView(From).LineSpacing;
  1373. end;
  1374. procedure TfrMemoView.ExpandVariables;
  1375. var
  1376. i: Integer;
  1377. s: String;
  1378. procedure GetData(var s: String);
  1379. var
  1380. i, j: Integer;
  1381. s1, s2: String;
  1382. begin
  1383. i := 1;
  1384. repeat
  1385. while (i < Length(s)) and (s[i] <> '[') do Inc(i);
  1386. s1 := GetBrackedVariable(s, i, j);
  1387. if i <> j then
  1388. begin
  1389. Delete(s, i, j - i + 1);
  1390. s2 := '';
  1391. CurReport.InternalOnGetValue(s1, s2);
  1392. Insert(s2, s, i);
  1393. Inc(i, Length(s2));
  1394. j := 0;
  1395. end;
  1396. until i = j;
  1397. end;
  1398. begin
  1399. Memo1.Clear;
  1400. for i := 0 to Memo.Count - 1 do
  1401. begin
  1402. s := Memo[i];
  1403. if Length(s) > 0 then
  1404. begin
  1405. GetData(s);
  1406. Memo1.Text := Memo1.Text + s;
  1407. end
  1408. else
  1409. Memo1.Add('');
  1410. end;
  1411. end;
  1412. procedure TfrMemoView.AssignFont(Canvas: TCanvas);
  1413. begin
  1414. with Canvas do
  1415. begin
  1416. Brush.Style := bsClear;
  1417. Font := Self.Font;
  1418. if not IsPrinting then
  1419. Font.Height := -Round(Font.Size * 96 / 72 * ScaleY);
  1420. end;
  1421. end;
  1422. type
  1423. TWordBreaks = string;
  1424. const
  1425. gl: set of Char = ['À', 'Å', '¨', 'È', 'Î', 'Ó', 'Û', 'Ý', 'Þ', 'ß'];
  1426. r_sogl: set of Char = ['Ú', 'Ü'];
  1427. spaces: set of Char = [' ', '.', ',', '-'];
  1428. function BreakWord(s: String): TWordBreaks;
  1429. var
  1430. i: Integer;
  1431. CanBreak: Boolean;
  1432. begin
  1433. Result := '';
  1434. s := AnsiUpperCase(s);
  1435. if Length(s) > 4 then
  1436. begin
  1437. i := 2;
  1438. repeat
  1439. CanBreak := False;
  1440. if s[i] in gl then
  1441. begin
  1442. if (s[i + 1] in gl) or (s[i + 2] in gl) then CanBreak := True;
  1443. end
  1444. else
  1445. begin
  1446. if not (s[i + 1] in gl) and not (s[i + 1] in r_sogl) and
  1447. (s[i + 2] in gl) then
  1448. CanBreak := True;
  1449. end;
  1450. if CanBreak then
  1451. Result := Result + Chr(i);
  1452. Inc(i);
  1453. until i > Length(s) - 2;
  1454. end;
  1455. end;
  1456. procedure TfrMemoView.WrapMemo;
  1457. var
  1458. size, size1, maxwidth: Integer;
  1459. b: TWordBreaks;
  1460. WCanvas: TCanvas;
  1461. procedure OutLine(const str: String);
  1462. var
  1463. n, w: Word;
  1464. begin
  1465. n := Length(str);
  1466. if (n > 0) and (str[n] = #1) then
  1467. w := WCanvas.TextWidth(Copy(str, 1, n - 1)) else
  1468. w := WCanvas.TextWidth(str);
  1469. SMemo.Add(str + Chr(w div 256) + Chr(w mod 256));
  1470. Inc(size, size1);
  1471. end;
  1472. procedure WrapLine(const s: String);
  1473. var
  1474. i, cur, beg, last: Integer;
  1475. WasB…