frx2xto30.pas
上传用户:cldfzq
上传日期:2008-05-27
资源大小:2956k
文件大小:71k
源码类别:

多国语言处理

开发平台:

MultiPlatform

  1. {******************************************}
  2. {                                          }
  3. {             FastReport v3.0              }
  4. {             FR2.x importer               }
  5. {                                          }
  6. {         Copyright (c) 1998-2005          }
  7. {         by Alexander Tzyganenko,         }
  8. {            Fast Reports Inc.             }
  9. {                                          }
  10. {******************************************}
  11. unit frx2xto30;
  12. interface
  13. {$I frx.inc}
  14. implementation
  15. uses
  16.   SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  17.   StdCtrls, ComCtrls, Printers, TypInfo, Jpeg, DB,
  18.   frxClass, frxVariables, frxPrinter, frxDCtrl, frxBarcode, frxBarcod,
  19.   TeeProcs, TeEngine, Chart, Series, frxChart, frxChBox, frxOLE, frxRich,
  20.   frxCross, frxCrossMatrix, frxDBSet, frxUnicodeUtils, frxUtils, fs_ipascal,
  21.   frxCustomDB, frxBDEComponents, frxADOComponents, frxIBXComponents
  22. {$IFDEF Delphi6}
  23. , Variants
  24. {$ENDIF};
  25. type
  26.   TfrxFR2EventsNew = class(TObject)
  27.   private
  28.     FReport: TfrxReport;
  29.     procedure DoGetValue(const Expr: String; var Value: Variant);
  30.     procedure DoPrepareScript(Sender: TObject);
  31.     function GetScriptValue(Instance: TObject; ClassType: TClass;
  32.       const MethodName: String; var Params: Variant): Variant;
  33.     function DoLoad(Sender: TfrxReport; Stream: TStream): Boolean;
  34.     function DoGetScriptValue(var Params: Variant): Variant;
  35.   end;
  36.   TfrPageType = (ptReport, ptDialog);
  37.   TfrBandType = (btReportTitle, btReportSummary,
  38.                  btPageHeader, btPageFooter,
  39.                  btMasterHeader, btMasterData, btMasterFooter,
  40.                  btDetailHeader, btDetailData, btDetailFooter,
  41.                  btSubDetailHeader, btSubDetailData, btSubDetailFooter,
  42.                  btOverlay, btColumnHeader, btColumnFooter,
  43.                  btGroupHeader, btGroupFooter,
  44.                  btCrossHeader, btCrossData, btCrossFooter,
  45.                  btChild, btNone);
  46.   TfrxFixupItem = class(TObject)
  47.   public
  48.     Obj: TPersistent;
  49.     PropInfo: PPropInfo;
  50.     Value: String;
  51.   end;
  52.   TfrHighlightAttr = packed record
  53.     FontStyle: Word;
  54.     FontColor, FillColor: TColor;
  55.   end;
  56.   TfrBarCodeRec = packed record
  57.     cCheckSum : Boolean;
  58.     cShowText : Boolean;
  59.     cCadr     : Boolean;
  60.     cBarType  : TfrxBarcodeType;
  61.     cModul    : Integer;
  62.     cRatio    : Double;
  63.     cAngle    : Double;
  64.   end;
  65.   TChartOptions = packed record
  66.     ChartType: Byte;
  67.     Dim3D, IsSingle, ShowLegend, ShowAxis, ShowMarks, Colored: Boolean;
  68.     MarksStyle: Byte;
  69.     Top10Num: Integer;
  70.     Reserved: array[0..35] of Byte;
  71.   end;
  72.   TfrRoundRect = packed record
  73.     SdColor: TColor;    // Color of Shadow
  74.     wShadow: Integer;   // Width of shadow
  75.     Cadre  : Boolean;   // Frame On/Off - not used /TZ/
  76.     sCurve : Boolean;   // RoundRect On/Off
  77.     wCurve : Integer;   // Curve size
  78.   end;
  79.   THackControl = class(TControl)
  80.   end;
  81.   TSeriesClass = class of TChartSeries;
  82. const
  83.   gtMemo = 0;
  84.   gtPicture = 1;
  85.   gtBand = 2;
  86.   gtSubReport = 3;
  87.   gtLine = 4;
  88.   gtCross = 5;
  89.   gtAddIn = 10;
  90.   frftNone = 0;
  91.   frftRight = 1;
  92.   frftBottom = 2;
  93.   frftLeft = 4;
  94.   frftTop = 8;
  95.   frtaLeft = 0;
  96.   frtaRight = 1;
  97.   frtaCenter = 2;
  98.   frtaVertical = 4;
  99.   frtaMiddle = 8;
  100.   frtaDown = 16;
  101.   flStretched = 1;
  102.   flWordWrap = 2;
  103.   flWordBreak = 4;
  104.   flAutoSize = 8;
  105.   flTextOnly = $10;
  106.   flSuppressRepeated = $20;
  107.   flHideZeros = $40;
  108.   flUnderlines = $80;
  109.   flRTLReading = $100;
  110.   flBandNewPageAfter = 2;
  111.   flBandPrintifSubsetEmpty = 4;
  112.   flBandBreaked = 8;
  113.   flBandOnFirstPage = $10;
  114.   flBandOnLastPage = $20;
  115.   flBandRepeatHeader = $40;
  116.   flBandPrintChildIfInvisible = $80;
  117.   flPictCenter = 2;
  118.   flPictRatio = 4;
  119.   flWantHook = $8000;
  120.   flDontUndo = $4000;
  121.   flOnePerPage = $2000;
  122.   pkNone = 0;
  123.   pkBitmap = 1;
  124.   pkMetafile = 2;
  125.   pkIcon = 3;
  126.   pkJPEG = 4;
  127. var
  128.   frVersion: Byte;
  129.   Report: TfrxReport;
  130.   Stream: TStream;
  131.   Page: TfrxPage;
  132.   Fixups: TList;
  133.   offsx, offsy: Integer;
  134.   frxFR2EventsNew: TfrxFR2EventsNew;
  135. const
  136.   frSpecCount = 9;
  137.   frSpecFuncs: array[0..frSpecCount - 1] of String =
  138.     ('PAGE#', '', 'DATE', 'TIME', 'LINE#', 'LINETHROUGH#', 'COLUMN#',
  139.      'CURRENT#', 'TOTALPAGES');
  140.   Bands: array[TfrBandType] of TfrxBandClass =
  141.     (TfrxReportTitle, TfrxReportSummary,
  142.      TfrxPageHeader, TfrxPageFooter,
  143.      TfrxHeader, TfrxMasterData, TfrxFooter,
  144.      TfrxHeader, TfrxDetailData, TfrxFooter,
  145.      TfrxHeader, TfrxSubDetailData, TfrxFooter,
  146.      TfrxOverlay, TfrxColumnHeader, TfrxColumnFooter,
  147.      TfrxGroupHeader, TfrxGroupFooter,
  148.      TfrxHeader, TfrxMasterData, TfrxFooter,
  149.      TfrxChild, nil);
  150.   cbDefaultText = '12345678';
  151.   ChartTypes: array[0..5] of TSeriesClass =
  152.     (TLineSeries, TAreaSeries, TPointSeries,
  153.      TBarSeries, THorizBarSeries, TPieSeries);
  154.   frRepInfoCount = 9;
  155.   frRepInfo: array[0..frRepInfoCount-1] of String =
  156.      ('REPORTCOMMENT', 'REPORTNAME', 'REPORTAUTOR',
  157.      'VMAJOR', 'VMINOR', 'VRELEASE', 'VBUILD', 'REPORTDATE', 'REPORTLASTCHANGE');
  158.   ParamTypes: array[0..10] of TFieldType =
  159.     (ftBCD, ftBoolean, ftCurrency, ftDate, ftDateTime, ftInteger,
  160.      ftFloat, ftSmallint, ftString, ftTime, ftWord);
  161. procedure frGetDataSetAndField(ComplexName: String; var DataSet: TDataSet;
  162.   var Field: String); forward;
  163. function frGetFieldValue(F: TField): Variant; forward;
  164. procedure LoadFromFR2Stream(AReport: TfrxReport; AStream: TStream); forward;
  165. function ConvertDatasetAndField(s: String): String; forward;
  166. { ------------------ hack FR events --------------------------------------- }
  167. { TfrxFR2EventsNew }
  168. procedure TfrxFR2EventsNew.DoGetValue(const Expr: String; var Value: Variant);
  169. var
  170.   Dataset: TDataset;
  171.   s, Field: String;
  172.   tf: TField;
  173.   ds: TfrxDataSet;
  174.   fld: String;
  175. begin
  176.   Dataset := nil;
  177.   Field := '';
  178.   if CompareText(Expr, 'COLUMN#') = 0 then
  179.     Value := Report.Engine.CurLine
  180.   else
  181.   begin
  182.     s := Expr;
  183.     if Pos('DialogForm.', s) = 1 then
  184.     begin
  185.       Delete(s, 1, Length('DialogForm.'));
  186.       Report.GetDataSetAndField(s, ds, fld);
  187.       if (ds <> nil) and (fld <> '') then
  188.       begin
  189.         Value := ds.Value[fld];
  190.         if Report.EngineOptions.ConvertNulls and (Value = Null) then
  191.           case ds.FieldType[fld] of
  192.             fftNumeric:
  193.               Value := 0;
  194.             fftString:
  195.               Value := '';
  196.             fftBoolean:
  197.               Value := False;
  198.           end;
  199.         Exit;
  200.       end;
  201.     end;
  202.     frGetDataSetAndField(s, Dataset, Field);
  203.     if (Dataset <> nil) and (Field <> '') then
  204.     begin
  205.       tf := Dataset.FieldByName(Field);
  206.       Value := frGetFieldValue(tf);
  207.     end;
  208.   end;
  209. end;
  210. procedure TfrxFR2EventsNew.DoPrepareScript(Sender: TObject);
  211. var
  212.   i: Integer;
  213. begin
  214.   FReport := TfrxReport(Sender);
  215.   Report := FReport;
  216.   for i := 0 to FReport.Variables.Count - 1 do
  217.     if IsValidIdent(FReport.Variables.Items[i].Name) then
  218.       FReport.Script.AddMethod('function ' + FReport.Variables.Items[i].Name + ': Variant', GetScriptValue);
  219. end;
  220. function TfrxFR2EventsNew.GetScriptValue(Instance: TObject;
  221.   ClassType: TClass; const MethodName: String;
  222.   var Params: Variant): Variant;
  223. var
  224.   i: Integer;
  225.   val: Variant;
  226. begin
  227.   i := FReport.Variables.IndexOf(MethodName);
  228.   if i <> -1 then
  229.   begin
  230.     val := FReport.Variables.Items[i].Value;
  231.     if (TVarData(val).VType = varString) or (TVarData(val).VType = varOleStr) then
  232.     begin
  233.       if Pos(#13#10, val) <> 0 then
  234.         Result := val
  235.       else
  236.         Result := FReport.Calc(val);
  237.     end
  238.     else
  239.       Result := val;
  240.   end;
  241. end;
  242. function TfrxFR2EventsNew.DoLoad(Sender: TfrxReport; Stream: TStream): Boolean;
  243. begin
  244.   Result := False;
  245.   Stream.Read(frVersion, 1);
  246.   Stream.Seek(-1, soFromCurrent);
  247.   if frVersion < 30 then
  248.   begin
  249.     LoadFromFR2Stream(Sender, Stream);
  250.     Result := True;
  251.   end;
  252. end;
  253. function TfrxFR2EventsNew.DoGetScriptValue(var Params: Variant): Variant;
  254. begin
  255.   Result := FReport.Calc('`' + Params[0] + '`', FReport.Script.ProgRunning);
  256. end;
  257. { ------------------ fixups ----------------------------------------------- }
  258. procedure ClearFixups;
  259. begin
  260.   while Fixups.Count > 0 do
  261.   begin
  262.     TfrxFixupItem(Fixups[0]).Free;
  263.     Fixups.Delete(0);
  264.   end;
  265. end;
  266. procedure FixupReferences;
  267. var
  268.   i: Integer;
  269.   Item: TfrxFixupItem;
  270.   Ref: TObject;
  271. begin
  272.   for i := 0 to Fixups.Count - 1 do
  273.   begin
  274.     Item := Fixups[i];
  275.     Ref := Report.FindObject(Item.Value);
  276.     if Ref <> nil then
  277.       SetOrdProp(Item.Obj, Item.PropInfo, Integer(Ref));
  278.   end;
  279.   ClearFixups;
  280. end;
  281. procedure AddFixup(Obj: TPersistent; Name, Value: String);
  282. var
  283.   Item: TfrxFixupItem;
  284. begin
  285.   Item := TfrxFixupItem.Create;
  286.   Item.Obj := Obj;
  287.   Item.PropInfo := GetPropInfo(Obj.ClassInfo, Name);
  288.   Item.Value := Value;
  289.   Fixups.Add(Item);
  290. end;
  291. { ------------------ stream readers -------------------------------------- }
  292. function frSetFontStyle(Style: Integer): TFontStyles;
  293. begin
  294.   Result := [];
  295.   if (Style and $1) <> 0 then Result := Result + [fsItalic];
  296.   if (Style and $2) <> 0 then Result := Result + [fsBold];
  297.   if (Style and $4) <> 0 then Result := Result + [fsUnderLine];
  298.   if (Style and $8) <> 0 then Result := Result + [fsStrikeOut];
  299. end;
  300. procedure frReadMemo(Stream: TStream; l: TStrings);
  301. var
  302.   s: String;
  303.   b: Byte;
  304.   n: Word;
  305. begin
  306.   l.Clear;
  307.   Stream.Read(n, 2);
  308.   if n > 0 then
  309.     repeat
  310.       Stream.Read(n, 2);
  311.       SetLength(s, n);
  312.       if n > 0 then
  313.         Stream.Read(s[1], n);
  314.       l.Add(s);
  315.       Stream.Read(b, 1);
  316.     until b = 0
  317.   else
  318.     Stream.Read(b, 1);
  319. end;
  320. function frReadString(Stream: TStream): String;
  321. var
  322.   s: String;
  323.   n: Word;
  324.   b: Byte;
  325. begin
  326.   Stream.Read(n, 2);
  327.   SetLength(s, n);
  328.   if n > 0 then
  329.     Stream.Read(s[1], n);
  330.   Stream.Read(b, 1);
  331.   Result := s;
  332. end;
  333. procedure frReadMemo22(Stream: TStream; l: TStrings);
  334. var
  335.   s: String;
  336.   i: Integer;
  337.   b: Byte;
  338. begin
  339.   SetLength(s, 4096);
  340.   l.Clear;
  341.   i := 1;
  342.   repeat
  343.     Stream.Read(b,1);
  344.     if (b = 13) or (b = 0) then
  345.     begin
  346.       SetLength(s, i - 1);
  347.       if not ((b = 0) and (i = 1)) then l.Add(s);
  348.       SetLength(s, 4096);
  349.       i := 1;
  350.     end
  351.     else if b <> 0 then
  352.     begin
  353.       s[i] := Chr(b);
  354.       Inc(i);
  355.       if i > 4096 then
  356.         SetLength(s, Length(s) + 4096);
  357.     end;
  358.   until b = 0;
  359. end;
  360. function frReadString22(Stream: TStream): String;
  361. var
  362.   s: String;
  363.   i: Integer;
  364.   b: Byte;
  365. begin
  366.   SetLength(s, 4096);
  367.   i := 1;
  368.   repeat
  369.     Stream.Read(b, 1);
  370.     if b = 0 then
  371.       SetLength(s, i - 1)
  372.     else
  373.     begin
  374.       s[i] := Chr(b);
  375.       Inc(i);
  376.       if i > 4096 then
  377.         SetLength(s, Length(s) + 4096);
  378.     end;
  379.   until b = 0;
  380.   Result := s;
  381. end;
  382. function frReadBoolean(Stream: TStream): Boolean;
  383. begin
  384.   Stream.Read(Result, 1);
  385. end;
  386. function frReadByte(Stream: TStream): Byte;
  387. begin
  388.   Stream.Read(Result, 1);
  389. end;
  390. function frReadWord(Stream: TStream): Word;
  391. begin
  392.   Stream.Read(Result, 2);
  393. end;
  394. function frReadInteger(Stream: TStream): Integer;
  395. begin
  396.   Stream.Read(Result, 4);
  397. end;
  398. procedure frReadFont(Stream: TStream; Font: TFont);
  399. var
  400.   w: Word;
  401. begin
  402.   Font.Name := frReadString(Stream);
  403.   Font.Size := frReadInteger(Stream);
  404.   Font.Style := frSetFontStyle(frReadWord(Stream));
  405.   Font.Color := frReadInteger(Stream);
  406.   w := frReadWord(Stream);
  407.   Font.Charset := w;
  408. end;
  409. function ReadString(Stream: TStream): String;
  410. begin
  411.   if frVersion >= 23 then
  412.     Result := frReadString(Stream) else
  413.     Result := frReadString22(Stream);
  414. end;
  415. procedure ReadMemo(Stream: TStream; Memo: TStrings);
  416. begin
  417.   if frVersion >= 23 then
  418.     frReadMemo(Stream, Memo) else
  419.     frReadMemo22(Stream, Memo);
  420. end;
  421. { --------------------------- utils -------------------------------- }
  422. function frFindComponent(Owner: TComponent; Name: String): TComponent;
  423. var
  424.   n: Integer;
  425.   s1, s2: String;
  426. begin
  427.   Result := nil;
  428.   n := Pos('.', Name);
  429.   try
  430.     if n = 0 then
  431.       Result := Owner.FindComponent(Name)
  432.     else
  433.     begin
  434.       s1 := Copy(Name, 1, n - 1);        // module name
  435.       s2 := Copy(Name, n + 1, 255);      // component name
  436.       Owner := FindGlobalComponent(s1);
  437.       if Owner <> nil then
  438.       begin
  439.         n := Pos('.', s2);
  440.         if n <> 0 then        // frame name - Delphi5
  441.         begin
  442.           s1 := Copy(s2, 1, n - 1);
  443.           s2 := Copy(s2, n + 1, 255);
  444.           Owner := Owner.FindComponent(s1);
  445.           if Owner <> nil then
  446.             Result := Owner.FindComponent(s2);
  447.         end
  448.         else
  449.           Result := Owner.FindComponent(s2);
  450.       end;
  451.     end;
  452.   except
  453.     on Exception do
  454.       raise EClassNotFound.Create('Missing ' + Name);
  455.   end;
  456. end;
  457. function frRemoveQuotes(const s: String): String;
  458. begin
  459.   if (Length(s) > 2) and (s[1] = '"') and (s[Length(s)] = '"') then
  460.     Result := Copy(s, 2, Length(s) - 2) else
  461.     Result := s;
  462. end;
  463. function frRemoveQuotes1(const s: String): String;
  464. begin
  465.   if (Length(s) > 2) and (s[1] = '''') and (s[Length(s)] = '''') then
  466.     Result := Copy(s, 2, Length(s) - 2) else
  467.     Result := s;
  468. end;
  469. procedure frGetFieldNames(DataSet: TDataSet; List: TStrings);
  470. begin
  471.   try
  472.     DataSet.GetFieldNames(List);
  473.   except;
  474.   end;
  475. end;
  476. procedure frGetDataSetAndField(ComplexName: String; var DataSet: TDataSet;
  477.   var Field: String);
  478. var
  479.   i, j, n: Integer;
  480.   f: TComponent;
  481.   sl: TStringList;
  482.   s: String;
  483.   c: Char;
  484.   cn: TControl;
  485.   function FindField(ds: TDataSet; FName: String): String;
  486.   var
  487.     sl: TStringList;
  488.   begin
  489.     Result := '';
  490.     if ds <> nil then
  491.     begin
  492.       sl := TStringList.Create;
  493.       frGetFieldNames(ds, sl);
  494.       if sl.IndexOf(FName) <> -1 then
  495.         Result := FName;
  496.       sl.Free;
  497.     end;
  498.   end;
  499. begin
  500.   Field := '';
  501.   f := Report.Owner;
  502.   sl := TStringList.Create;
  503.   n := 0; j := 1;
  504.   for i := 1 to Length(ComplexName) do
  505.   begin
  506.     c := ComplexName[i];
  507.     if c = '"' then
  508.     begin
  509.       sl.Add(Copy(ComplexName, i, 255));
  510.       j := i;
  511.       break;
  512.     end
  513.     else if c = '.' then
  514.     begin
  515.       sl.Add(Copy(ComplexName, j, i - j));
  516.       j := i + 1;
  517.       Inc(n);
  518.     end;
  519.   end;
  520.   if j <> i then
  521.     sl.Add(Copy(ComplexName, j, 255));
  522.   case n of
  523.     0: // field name only
  524.       begin
  525.         if DataSet <> nil then
  526.         begin
  527.           s := frRemoveQuotes(ComplexName);
  528.           Field := FindField(DataSet, s);
  529.         end;
  530.       end;
  531.     1: // DatasetName.FieldName
  532.       begin
  533.         if sl.Count > 1 then
  534.         begin
  535.           DataSet := TDataSet(frFindComponent(f, sl[0]));
  536.           s := frRemoveQuotes(sl[1]);
  537.           Field := FindField(DataSet, s);
  538.         end;
  539.       end;
  540.     2: // FormName.DatasetName.FieldName
  541.       begin
  542.         f := FindGlobalComponent(sl[0]);
  543.         if f <> nil then
  544.         begin
  545.           DataSet := TDataSet(f.FindComponent(sl[1]));
  546.           s := frRemoveQuotes(sl[2]);
  547.           Field := FindField(DataSet, s);
  548.         end;
  549.       end;
  550.     3: // FormName.FrameName.DatasetName.FieldName - Delphi5
  551.       begin
  552.         f := FindGlobalComponent(sl[0]);
  553.         if f <> nil then
  554.         begin
  555.           cn := TControl(f.FindComponent(sl[1]));
  556.           DataSet := TDataSet(cn.FindComponent(sl[2]));
  557.           s := frRemoveQuotes(sl[3]);
  558.           Field := FindField(DataSet, s);
  559.         end;
  560.       end;
  561.   end;
  562.   sl.Free;
  563. end;
  564. function frGetFieldValue(F: TField): Variant;
  565. begin
  566.   if not F.DataSet.Active then
  567.     F.DataSet.Open;
  568.   if Assigned(F.OnGetText) then
  569.     Result := F.DisplayText
  570.   else if F.DataType in [ftLargeint] then
  571.     Result := F.DisplayText
  572.   else
  573.     Result := F.AsVariant;
  574.   if Result = Null then
  575.     if F.DataType = ftString then
  576.       Result := ''
  577.     else if F.DataType = ftWideString then
  578.       Result := ''
  579.     else if F.DataType = ftBoolean then
  580.       Result := False
  581.     else
  582.       Result := 0;
  583. end;
  584. function FindTfrxDataset(ds: TDataset): TfrxDataset;
  585. var
  586.   i: Integer;
  587.   sl: TStringList;
  588.   ds1: TfrxDataset;
  589. begin
  590.   Result := nil;
  591.   sl := TStringList.Create;
  592.   frxGetDatasetList(sl);
  593.   for i := 0 to sl.Count - 1 do
  594.   begin
  595.     ds1 := TfrxDataset(sl.Objects[i]);
  596.     if (ds1 is TfrxDBDataset) and (TfrxDBDataset(ds1).GetDataSet = ds) then
  597.     begin
  598.       Result := ds1;
  599.       break;
  600.     end;
  601.   end;
  602.   sl.Free;
  603. end;
  604. function GetBrackedVariable(const s: String; var i, j: Integer): String;
  605. var
  606.   c: Integer;
  607.   fl1, fl2: Boolean;
  608. begin
  609.   j := i; fl1 := True; fl2 := True; c := 0;
  610.   Result := '';
  611.   if (s = '') or (j > Length(s)) then Exit;
  612.   Dec(j);
  613.   repeat
  614.     Inc(j);
  615.     if fl1 and fl2 then
  616.       if s[j] = '[' then
  617.       begin
  618.         if c = 0 then i := j;
  619.         Inc(c);
  620.       end
  621.       else if s[j] = ']' then Dec(c);
  622.     if fl1 then
  623.       if s[j] = '"' then fl2 := not fl2;
  624.     if fl2 then
  625.       if s[j] = '''' then fl1 := not fl1;
  626.   until (c = 0) or (j >= Length(s));
  627.   Result := Copy(s, i + 1, j - i - 1);
  628. end;
  629. function Substitute(const ParName: String): String;
  630. begin
  631.   Result := ParName;
  632.   if CompareText(ParName, frRepInfo[0]) = 0 then
  633.     Result := 'Report.ReportOptions.Description'
  634.   else if CompareText(ParName, frRepInfo[1]) = 0 then
  635.     Result := 'Report.ReportOptions.Name'
  636.   else if CompareText(ParName, frRepInfo[2]) = 0 then
  637.     Result := 'Report.ReportOptions.Author'
  638.   else if CompareText(ParName, frRepInfo[3]) = 0 then
  639.     Result := 'Report.ReportOptions.VersionMajor'
  640.   else if CompareText(ParName, frRepInfo[4]) = 0 then
  641.     Result := 'Report.ReportOptions.VersionMinor'
  642.   else if CompareText(ParName, frRepInfo[5]) = 0 then
  643.     Result := 'Report.ReportOptions.VersionRelease'
  644.   else if CompareText(ParName, frRepInfo[6]) = 0 then
  645.     Result := 'Report.ReportOptions.VersionBuild'
  646.   else if CompareText(ParName, frRepInfo[7]) = 0 then
  647.     Result := 'Report.ReportOptions.CreateDate'
  648.   else if CompareText(ParName, frRepInfo[8]) = 0 then
  649.     Result := 'Report.ReportOptions.LastChange'
  650.   else if CompareText(ParName, 'CURY') = 0 then
  651.     Result := 'Engine.CurY'
  652.   else if CompareText(ParName, 'FREESPACE') = 0 then
  653.     Result := 'Engine.FreeSpace'
  654.   else if CompareText(ParName, 'FINALPASS') = 0 then
  655.     Result := 'Engine.FinalPass'
  656.   else if CompareText(ParName, 'PAGEHEIGHT') = 0 then
  657.     Result := 'Engine.PageHeight'
  658.   else if CompareText(ParName, 'PAGEWIDTH') = 0 then
  659.     Result := 'Engine.PageWidth'
  660. end;
  661. procedure DoExpression(const Expr: String; var Value: String);
  662. begin
  663.   Value := Substitute(Expr);
  664.   if ConvertDatasetAndField(Expr) <> Expr then
  665.     Value := ConvertDatasetAndField(Expr);
  666. end;
  667. procedure ExpandVariables(var s: String);
  668. var
  669.   i, j: Integer;
  670.   s1, s2: String;
  671. begin
  672.   i := 1;
  673.   repeat
  674.     while (i < Length(s)) and (s[i] <> '[') do Inc(i);
  675.     s1 := GetBrackedVariable(s, i, j);
  676.     if i <> j then
  677.     begin
  678.       Delete(s, i, j - i + 1);
  679.       s2 := s1;
  680.       DoExpression(s1, s2);
  681.       s2 := '[' + s2 + ']';
  682.       Insert(s2, s, i);
  683.       Inc(i, Length(s2));
  684.       j := 0;
  685.     end;
  686.   until i = j;
  687. end;
  688. procedure ExpandVariables1(var s: String);
  689. var
  690.   i, j: Integer;
  691.   s1, s2: String;
  692. begin
  693.   i := 1;
  694.   repeat
  695.     while (i < Length(s)) and (s[i] <> '[') do Inc(i);
  696.     s1 := GetBrackedVariable(s, i, j);
  697.     if i <> j then
  698.     begin
  699.       Delete(s, i, j - i + 1);
  700.       s2 := s1;
  701.       DoExpression(s1, s2);
  702.       Insert(s2, s, i);
  703.       Inc(i, Length(s2));
  704.       j := 0;
  705.     end;
  706.   until i = j;
  707. end;
  708. procedure ConvertMemoExpressions(m: TfrxCustomMemoView; s: String);
  709. begin
  710.   ExpandVariables(s);
  711.   m.Memo.Text := AnsiToUnicode(s, m.Font.Charset);
  712. end;
  713. { --------------------------- report items -------------------------------- }
  714. var
  715.   Name: String;
  716.   HVersion, LVersion: Byte;
  717.   x, y, dx, dy: Integer;
  718.   Flags: Word;
  719.   FrameTyp: Word;
  720.   FrameWidth: Single;
  721.   FrameColor: TColor;
  722.   FrameStyle: Word;
  723.   FillColor: TColor;
  724.   Format: Integer;
  725.   FormatStr: String;
  726.   Visible: WordBool;
  727.   gapx, gapy: Integer;
  728.   Restrictions: Word;
  729.   Tag: String;
  730.   Memo, Script: TStringList;
  731.   BandAlign: Byte;
  732.   NeedCreateName: Boolean;
  733. procedure AddScript(c: TfrxComponent; const ScriptName: String);
  734. var
  735.   i: Integer;
  736.   vName: String;
  737. begin
  738.   vName := c.Name;
  739.   if Script.Count <> 0 then
  740.   begin
  741.     Report.ScriptText.Add('procedure ' + vName + scriptName);
  742.     Report.ScriptText.Add('begin');
  743.     Report.ScriptText.Add('  with ' + vName + ', Engine do');
  744.     Report.ScriptText.Add('  begin');
  745.     if Script[0] <> 'begin' then
  746.       Report.ScriptText.Add(Script[0]);
  747.     for i := 1 to Script.Count - 2 do
  748.       Report.ScriptText.Add(Script[i]);
  749.     if Script[0] <> 'begin' then
  750.     begin
  751.       if Script.Count <> 1 then
  752.         Report.ScriptText.Add(Script[Script.Count - 1]);
  753.       Report.ScriptText.Add('  end');
  754.       Report.ScriptText.Add('end;');
  755.     end
  756.     else
  757.     begin
  758.       Report.ScriptText.Add('  end');
  759.       Report.ScriptText.Add(Script[Script.Count - 1] + ';');
  760.     end;
  761.     Report.ScriptText.Add('');
  762.     if c is TfrxDialogPage then
  763.       TfrxDialogPage(c).OnShow := vName + 'OnShow'
  764.     else if c is TfrxDialogControl then
  765.       TfrxDialogControl(c).OnClick := vName + 'OnClick'
  766.     else if c is TfrxReportComponent then
  767.       TfrxReportComponent(c).OnBeforePrint := vName + 'OnBeforePrint';
  768.   end;
  769. end;
  770. procedure SetfrxComponent(c: TfrxComponent);
  771.   procedure SetValidIdent(var Ident: string);
  772.   const
  773.     Alpha = ['A'..'Z', 'a'..'z', '_'];
  774.     AlphaNumeric = Alpha + ['0'..'9'];
  775.   var
  776.     I: Integer;
  777.   begin
  778.     if (Length(Ident) > 0) and not (Ident[1] in Alpha) then
  779.       Ident[1] := '_';
  780.     for I := 2 to Length(Ident) do
  781.       if not (Ident[I] in AlphaNumeric) then
  782.         Ident[I] := '_';
  783.   end;
  784. begin
  785.   SetValidIdent(Name);
  786.   c.Name := Name;
  787.   if NeedCreateName then
  788.     c.CreateUniqueName;
  789.   c.Left := x + offsx;
  790.   c.Top := y + offsy;
  791.   c.Width := dx;
  792.   c.Height := dy;
  793.   c.Visible := Visible;
  794. end;
  795. procedure SetfrxView(c: TfrxView);
  796. begin
  797.   if (FrameTyp and frftRight) <> 0 then
  798.     c.Frame.Typ := c.Frame.Typ + [ftRight];
  799.   if (FrameTyp and frftBottom) <> 0 then
  800.     c.Frame.Typ := c.Frame.Typ + [ftBottom];
  801.   if (FrameTyp and frftLeft) <> 0 then
  802.     c.Frame.Typ := c.Frame.Typ + [ftLeft];
  803.   if (FrameTyp and frftTop) <> 0 then
  804.     c.Frame.Typ := c.Frame.Typ + [ftTop];
  805.   c.Frame.Width := FrameWidth;
  806.   c.Frame.Color := FrameColor;
  807.   c.Frame.Style := TfrxFrameStyle(FrameStyle);
  808.   c.Color := FillColor;
  809.   c.Align := TfrxAlign(BandAlign);
  810.   c.TagStr := Tag;
  811.   AddScript(c, 'OnBeforePrint(Sender: TfrxComponent);');
  812. end;
  813. procedure TfrViewLoadFromStream;
  814. var
  815.   w: Integer;
  816. begin
  817.   with Stream do
  818.   begin
  819.     NeedCreateName := False;
  820.     if frVersion >= 23 then
  821.       Name := ReadString(Stream) else
  822.       NeedCreateName := True;
  823.     if frVersion > 23 then
  824.     begin
  825.       Read(HVersion, 1);
  826.       Read(LVersion, 1);
  827.     end;
  828.     Read(x, 4); Read(y, 4); Read(dx, 4); Read(dy, 4);
  829.     Read(Flags, 2); Read(FrameTyp, 2); Read(FrameWidth, 4);
  830.     Read(FrameColor, 4); Read(FrameStyle, 2);
  831.     Read(FillColor, 4);
  832.     Read(Format, 4);
  833.     FormatStr := ReadString(Stream);
  834.     ReadMemo(Stream, Memo);
  835.     if frVersion >= 23 then
  836.     begin
  837.       ReadMemo(Stream, Script);
  838.       Read(Visible, 2);
  839.     end;
  840.     if frVersion >= 24 then
  841.     begin
  842.       Read(Restrictions, 2);
  843.       Tag := ReadString(Stream);
  844.       Read(gapx, 4);
  845.       Read(gapy, 4);
  846.     end;
  847.     w := PInteger(@FrameWidth)^;
  848.     if w <= 10 then
  849.       w := w * 1000;
  850.     if HVersion > 1 then
  851.       Read(BandAlign, 1);
  852.     FrameWidth := w / 1000;
  853.   end;
  854. end;
  855. procedure TfrMemoViewLoadFromStream;
  856. var
  857.   w: Word;
  858.   i: Integer;
  859.   Alignment: Integer;
  860.   Highlight: TfrHighlightAttr;
  861.   HighlightStr: String;
  862.   LineSpacing, CharacterSpacing: Integer;
  863.   m: TfrxMemoView;
  864.   procedure DecodeDisplayFormat;
  865.   var
  866.     LCategory: Byte;
  867.     LType: Byte;
  868.     LNoOfDecimals: Byte;
  869.     LSeparator: Char;
  870.   begin
  871.     LCategory := (Format and $0F000000) shr 24;
  872.     LType := (Format and $00FF0000) shr 16;
  873.     LNoOfDecimals := (Format and $0000FF00) shr 8;
  874.     LSeparator := Chr(Format and $000000FF);
  875.     case LCategory of
  876.       0: { text }
  877.         m.DisplayFormat.Kind := fkText;
  878.       1: { number }
  879.       begin
  880.         m.DisplayFormat.Kind := fkNumeric;
  881.         m.DisplayFormat.DecimalSeparator := LSeparator;
  882.         case LType of
  883.           0: m.DisplayFormat.FormatStr := '%2.' + IntToStr(LNoOfDecimals) + 'g';
  884.           1: m.DisplayFormat.FormatStr := '%g';
  885.           2: m.DisplayFormat.FormatStr := '%2.' + IntToStr(LNoOfDecimals) + 'f';
  886.           3: m.DisplayFormat.FormatStr := '%2.' + IntToStr(LNoOfDecimals) + 'n';
  887.           else
  888.            m.DisplayFormat.FormatStr := '%g' { can't convert custom format string };
  889.         end;
  890.       end;
  891.       2: { date }
  892.       begin
  893.         m.DisplayFormat.Kind := fkDateTime;
  894.         case LType of
  895.           0: m.DisplayFormat.FormatStr := 'dd.mm.yy';
  896.           1: m.DisplayFormat.FormatStr := 'dd.mm.yyyy';
  897.           2: m.DisplayFormat.FormatStr := 'd mmm yyyy';
  898.           3: m.DisplayFormat.FormatStr := LongDateFormat;
  899.           4: m.DisplayFormat.FormatStr := FormatStr;
  900.         end;
  901.       end;
  902.       3: { time }
  903.       begin
  904.         m.DisplayFormat.Kind := fkDateTime;
  905.         case LType of
  906.           0: m.DisplayFormat.FormatStr := 'hh:nn:ss';
  907.           1: m.DisplayFormat.FormatStr := 'h:nn:ss';
  908.           2: m.DisplayFormat.FormatStr := 'hh:nn';
  909.           3: m.DisplayFormat.FormatStr := 'h:nn';
  910.           4: m.DisplayFormat.FormatStr := FormatStr;
  911.         end;
  912.       end;
  913.       4: { boolean }
  914.       begin
  915.         m.DisplayFormat.Kind := fkBoolean;
  916.         case LType of
  917.           0: m.DisplayFormat.FormatStr := '0,1';
  918.           1: m.DisplayFormat.FormatStr := '崶