FastReport_FMX_2.8.12/LibD28/FMX.frxExportRTF.pas
2024-07-06 22:41:12 +02:00

992 lines
30 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport v4.0 }
{ RTF export filter }
{ }
{ Copyright (c) 1998-2008 }
{ by Alexander Fediachov, }
{ Fast Reports Inc. }
{ }
{******************************************}
unit FMX.frxExportRTF;
interface
{$I fmx.inc}
{$I frx.inc}
{$I fmx.inc}
uses
System.SysUtils, System.Classes, FMX.Types, System.UITypes, FMX.Controls, FMX.Forms, FMX.Dialogs,
FMX.frxClass, FMX.frxExportMatrix, FMX.frxProgress, fmx.frxImageConverter, System.UIConsts,
System.Variants, FMX.Edit, FMX.ListBox, FMX.frxGraphicUtils, FMX.frxBaseModalForm
{$IFDEF DELPHI18}
,FMX.StdCtrls
{$ENDIF}
{$IFDEF DELPHI19}
, FMX.Graphics
{$ENDIF};
type
TfrxHeaderFooterMode = (hfText, hfPrint, hfNone);
TfrxRTFExportDialog = class(TfrxForm)
OkB: TButton;
CancelB: TButton;
GroupPageRange: TGroupBox;
DescrL: TLabel;
AllRB: TRadioButton;
CurPageRB: TRadioButton;
PageNumbersRB: TRadioButton;
PageNumbersE: TEdit;
GroupQuality: TGroupBox;
WCB: TCheckBox;
PageBreaksCB: TCheckBox;
PicturesCB: TCheckBox;
OpenCB: TCheckBox;
SaveDialog1: TSaveDialog;
ContinuousCB: TCheckBox;
HeadFootL: TLabel;
PColontitulCB: TComboBox;
ListBoxItem1: TListBoxItem;
ListBoxItem2: TListBoxItem;
ListBoxItem3: TListBoxItem;
procedure FormCreate(Sender: TObject);
procedure PageNumbersEChange(Sender: TObject);
procedure PageNumbersEKeyDown(Sender: TObject; var Key: Word;
var KeyChar: WideChar; Shift: TShiftState);
procedure FormKeyDown(Sender: TObject; var Key: Word;
var KeyChar: WideChar; Shift: TShiftState);
end;
{$I frxFMX_PlatformsAttribute.inc}
TfrxRTFExport = class(TfrxCustomExportFilter)
private
FColorTable: TStringList;
FCurrentPage: Integer;
FDataList: TList;
FExportPageBreaks: Boolean;
FExportPictures: Boolean;
FFirstPage: Boolean;
FFontTable: TStringList;
FCharsetTable: TStringList;
FMatrix: TfrxIEMatrix;
FOpenAfterExport: Boolean;
FProgress: TfrxProgress;
FWysiwyg: Boolean;
FCreator: String;
FHeaderFooterMode: TfrxHeaderFooterMode;
FAutoSize: Boolean;
FPictureType: TfrxPictureType;
function TruncReturns(const Str: WideString): WideString;
function GetRTFBorders(const Style: TfrxIEMStyle): string;
function GetRTFColor(const c: TAlphaColor): string;
function GetRTFFontStyle(const f: TFontStyles): String;
function GetRTFFontColor(const f: String): String;
function GetRTFFontName(const f: String; const charset: Integer): String;
function GetRTFHAlignment(const HAlign: TfrxHAlign) : String;
function GetRTFVAlignment(const VAlign: TfrxVAlign) : String;
function StrToRTFSlash(const Value: WideString): WideString;
function StrToRTFUnicodeEx(const Value: WideString): String;
function StrToRTFUnicode(const Value: WideString): String;
procedure ExportPage(const Stream: TStream);
procedure PrepareExport;
procedure SaveGraphic(Graphic: TBitmap; Stream: TStream;
Width, Height: Extended; PicType: TfrxPictureType);
public
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
function ShowModal: TModalResult; override;
function Start: boolean; override;
procedure Finish; override;
procedure FinishPage(Page: TfrxReportPage; Index: Integer); override;
procedure StartPage(Page: TfrxReportPage; Index: Integer); override;
procedure ExportObject(Obj: TfrxComponent); override;
published
property PictureType: TfrxPictureType read FPictureType write FPictureType;
property ExportPageBreaks: Boolean read FExportPageBreaks write FExportPageBreaks default True;
property ExportPictures: Boolean read FExportPictures write FExportPictures default True;
property OpenAfterExport: Boolean read FOpenAfterExport write FOpenAfterExport default False;
property Wysiwyg: Boolean read FWysiwyg write FWysiwyg;
property Creator: String read FCreator write FCreator;
property SuppressPageHeadersFooters;
property HeaderFooterMode: TfrxHeaderFooterMode read FHeaderFooterMode write FHeaderFooterMode;
property AutoSize: Boolean read FAutoSize write FAutoSize;
property OverwritePrompt;
end;
implementation
uses
FMX.frxUtils, FMX.frxRes, FMX.frxrcExports, FMX.frxFMX
{$IFDEF MSWINDOWS}
, Winapi.ShellAPI
{$ENDIF}
{$IFDEF LINUX}
,FMUX.Api
{$ENDIF}
{$IFDEF MACOS}
, Posix.Stdlib
{$ENDIF};
{$R *.fmx}
const
Xdivider = 15.05;
Ydivider = 15;
Ydivider_last = 14.5;
PageDivider = 15.02;
MargDivider = 56.48;
FONT_DIVIDER = 15;
IMAGE_DIVIDER = 25.3;
SW_SHOW = 5;
{ TfrxRTFExport }
constructor TfrxRTFExport.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ShowDialog := True;
FExportPageBreaks := True;
FExportPictures := True;
FWysiwyg := True;
FHeaderFooterMode := hfText;
FAutoSize := False;
FCreator := 'FastReport';
FilterDesc := frxGet(8504);
DefaultExt := frxGet(8505);
end;
class function TfrxRTFExport.GetDescription: String;
begin
Result := frxResources.Get('RTFexport');
end;
function TfrxRTFExport.TruncReturns(const Str: WideString): WideString;
var
l: Integer;
begin
l := Length(Str);
if (l > 1) and (Str[l - 1] = #13) and (Str[l] = #10) then
Result := Copy(Str, 1, l - 2)
else
Result := Str;
end;
function TfrxRTFExport.StrToRTFSlash(const Value: WideString): WideString;
var
i: integer;
begin
result := '';
for i := 1 to Length(Value) do
begin
if Value[i] = '\' then
result := result + '\\'
else if Value[i] = '{' then
result := result + '\{'
else if Value[i] = '}' then
result := result + '\}'
else if (Value[i] = #13) and (i < (Length(Value) - 1)) and (Value[i + 1] = #10) then
result := result + '\line'#13
else
result := result + Value[i];
end;
end;
function TfrxRTFExport.StrToRTFUnicodeEx(const Value: WideString): String;
var
s: WideString;
begin
s := StrToRTFSlash(Value);
Result := StrToRTFUnicode(s);
end;
function TfrxRTFExport.StrToRTFUnicode(const Value: WideString): String;
var
i: integer;
pwc: ^Word;
begin
result := '';
for i := 1 to Length(Value) do
begin
pwc := @Value[i];
if pwc^ > 127 then
result := result + '\u' + IntToStr(pwc^) + '\''3f'
else
result := result + Chr(pwc^);
end;
end;
function TfrxRTFExport.GetRTFBorders(const Style: TfrxIEMStyle): string;
var
brdrw: String;
brdrc: String;
brdrs: String;
begin
{$IFNDEF FR_DEBUG}
Result := '';
brdrw := '\brdrs\brdrw' + IntToStr(Round(Style.FrameWidth * 20));
brdrc := '\brdrcf' + GetRTFFontColor(GetRTFColor(Style.FrameColor));
if Style.FrameStyle = fsDouble then
brdrs := '\brdrdb'
else if Style.FrameStyle <> fsSolid then
brdrs := '\brdrdashsm'
else brdrs := '';
if ftTop in Style.FrameTyp then
Result := Result + '\clbrdrt' + brdrw + brdrc + brdrs;
if ftLeft in Style.FrameTyp then
Result := Result + '\clbrdrl' + brdrw + brdrc + brdrs;
if ftBottom in Style.FrameTyp then
Result := Result + '\clbrdrb' + brdrw + brdrc + brdrs;
if ftRight in Style.FrameTyp then
Result := Result + '\clbrdrr' + brdrw + brdrc + brdrs;
{$ELSE}
Result := '';
brdrw := '\brdrs\brdrw' + IntToStr(Round(Style.FrameWidth * 20));
brdrc := '\brdrcf' + GetRTFFontColor(GetRTFColor(Style.FrameColor));
brdrs := '';
Result := Result + '\clbrdrt' + brdrw + brdrc + brdrs;
Result := Result + '\clbrdrl' + brdrw + brdrc + brdrs;
Result := Result + '\clbrdrb' + brdrw + brdrc + brdrs;
Result := Result + '\clbrdrr' + brdrw + brdrc + brdrs;
{$ENDIF}
end;
function TfrxRTFExport.GetRTFColor(const c: TAlphaColor): string;
begin
if c = claNull then
Result := '\red255\green255\blue255;'
else
Result := '\red' + IntToStr(TAlphaColorRec(c).R) +
'\green' + IntToStr(TAlphaColorRec(c).G) +
'\blue' + IntToStr(TAlphaColorRec(c).B) + ';'
end;
function TfrxRTFExport.GetRTFFontStyle(const f: TFontStyles): String;
begin
Result := '';
if fsItalic in f then Result := '\i';
if fsBold in f then Result := Result + '\b';
if fsUnderline in f then Result := Result + '\ul';
end;
function TfrxRTFExport.GetRTFFontColor(const f: String): String;
var
i: Integer;
begin
i := FColorTable.IndexOf(f);
if i <> -1 then
Result := IntToStr(i + 1)
else
begin
FColorTable.Add(f);
Result := IntToStr(FColorTable.Count);
end;
end;
function TfrxRTFExport.GetRTFFontName(const f: String; const Charset: Integer): String;
var
i: Integer;
begin
i := FFontTable.IndexOf(f);
if i <> -1 then
Result := IntToStr(i)
else
begin
FFontTable.Add(f);
FCharsetTable.Add(IntToStr(charset));
Result := IntToStr(FFontTable.Count - 1);
end;
end;
function TfrxRTFExport.GetRTFHAlignment(const HAlign: TfrxHAlign) : String;
begin
case HAlign of
haLeft: Result := '\ql';
haRight: Result := '\qr';
haCenter: Result := '\qc';
haBlock: Result := '\qj';
else Result := '\ql';
end;
end;
function TfrxRTFExport.GetRTFVAlignment(const VAlign: TfrxVAlign) : String;
begin
if (VAlign = vaTop) then Result := '\clvertalt'
else if (VAlign = vaCenter) then Result := '\clvertalc'
else if (VAlign = vaBottom) then Result := '\clvertalb'
else Result := '\clvertalt';
end;
procedure TfrxRTFExport.PrepareExport;
var
i: Integer;
Obj: TfrxIEMObject;
begin
for i := 0 to FMatrix.GetObjectsCount - 1 do
begin
Obj := FMatrix.GetObjectById(i);
Obj.Counter := -1;
GetRTFFontColor(GetRTFColor(Obj.Style.Color));
GetRTFFontColor(GetRTFColor(Obj.Style.FrameColor));
if Obj.IsText then
begin
GetRTFFontColor(GetRTFColor(Obj.Style.Font.Color));
GetRTFFontName(Obj.Style.Font.Name, Obj.Style.Charset);
end;
end;
end;
procedure TfrxRTFExport.ExportPage(const Stream: TStream);
var
i, j, x, y, fx, fy, dx, dy, n1, pbk: Integer;
YDiv: Extended;
dcol, drow, xoffs: Integer;
buff, s, s1, s2: String;
st, st1: WideString;
CellsLine: AnsiString;
Obj: TfrxIEMObject;
ObjBounds: TfrxRect;
ObjWidth, ObjHeight: Extended;
Graphic: TBitmap;
// Str,
CellsStream: TStream;
// bArr: array[0..1023] of Byte;
FMode: Integer; // 3 - header, 2 - footer, 1 - body, 0 - stop
FHTMLTags: TfrxHTMLTagsList;
Tag: TfrxHTMLTag;
TagFColor: TAlphaColor;
TagFStyleB, TagFStyleU, TagFStyleI: Integer;
procedure WriteExpLn(const str: string);
var
TemsStr: AnsiString;
begin
TemsStr := AnsiString(str);
if Length(TemsStr) > 0 then
begin
Stream.Write(TemsStr[1], Length(TemsStr));
Stream.Write(AnsiString(#13#10), 2);
end;
end;
procedure SetPageProp(Page: Integer);
var
s: String;
begin
s := '\pgwsxn' + IntToStr(Round(FMatrix.GetPageWidth(Page) * PageDivider)) +
'\pghsxn' + IntToStr(Round(FMatrix.GetPageHeight(Page) * PageDivider)) +
'\marglsxn' + IntToStr(Round(FMatrix.GetPageLMargin(Page) * MargDivider)) +
'\margrsxn' + IntToStr(Round(FMatrix.GetPageRMargin(Page) * MargDivider)) +
'\margtsxn' + IntToStr(Round(FMatrix.GetPageTMargin(Page) * MargDivider)) +
'\margbsxn' + IntToStr(Round(FMatrix.GetPageBMargin(Page) * MargDivider));
WriteExpLn(s);
if FMatrix.GetPageOrientation(Page) = poLandscape then
WriteExpLn('\lndscpsxn');
end;
begin
PrepareExport;
WriteExpLn('{\rtf1\ansi');
s := '{\fonttbl';
for i := 0 to FFontTable.Count - 1 do
begin
s1 := '{\f' + IntToStr(i) + '\fcharset' + FCharsetTable[i] + ' ' + FFontTable[i] + '}';
if Length(s + s1) < 255 then
s := s + s1
else
begin
WriteExpLn(s);
s := s1;
end;
end;
s := s + '}';
WriteExpLn(s);
s := '{\colortbl;';
for i := 0 to FColorTable.Count - 1 do
begin
s1 := FColorTable[i];
if Length(s + s1) < 255 then
s := s + s1
else
begin
WriteExpLn(s);
s := s1;
end;
end;
s := s + '}';
WriteExpLn(s);
WriteExpLn('{\info{\title ' + StrToRTFUnicodeEx(Report.ReportOptions.Name) +
'}{\author ' + StrToRTFUnicodeEx(FCreator) +
'}{\creatim\yr' + FormatDateTime('yyyy', CreationTime) +
'\mo' + FormatDateTime('mm', CreationTime) +
'\dy' + FormatDateTime('dd', CreationTime) +
'\hr' + FormatDateTime('hh', CreationTime) +
'\min' + FormatDateTime('nn', CreationTime) + '}}');
if ShowProgress then
FProgress.Execute(FMatrix.Height - 1, frxResources.Get('ProgressWait'), True, True);
pbk := 0;
SetPageProp(pbk);
if FHeaderFooterMode = hfPrint then
FMode := 3
else
FMode := 1;
///
YDiv := Ydivider;
while FMode > 0 do
begin
if FMode = 3 then
WriteExpLn('{\header ')
else if FMode = 2 then
WriteExpLn('{\footer ');
if FMatrix.PagesCount = 1 then
YDiv := Ydivider_last;
for y := 0 to FMatrix.Height - 2 do
begin
if ShowProgress then
begin
FProgress.Tick;
if FProgress.Terminated then
break;
end;
if FExportPageBreaks and (FMode = 1) then
if pbk < FMatrix.PagesCount then
if FMatrix.GetPageBreak(pbk) <= FMatrix.GetYPosById(y) then
begin
WriteExpLn('\pard\sect');
Inc(pbk);
if pbk < FMatrix.PagesCount then
SetPageProp(pbk);
if pbk = FMatrix.PagesCount - 1 then
YDiv := Ydivider_last;
continue;
end;
drow := Round((FMatrix.GetYPosById(y + 1) - FMatrix.GetYPosById(y)) * YDiv);
if FAutoSize then
buff := '\trrh'
else
buff := '\trrh-';
buff := buff + IntToStr(drow) + '\trgaph15';
CellsStream := TMemoryStream.Create;
try
xoffs := Round(FMatrix.GetXPosById(0)) + Round(FMatrix.GetPageLMargin(pbk) * MargDivider / Xdivider);
for x := 1 to FMatrix.Width - 2 do
begin
i := FMatrix.GetCell(x, y);
if (i <> -1) then
begin
Obj := FMatrix.GetObjectById(i);
ObjBounds := FMatrix.GetObjectBounds(Obj);
ObjWidth := ObjBounds.Right - ObjBounds.Left;
ObjHeight := ObjBounds.Bottom - ObjBounds.Top;
if (FMode = 3) and (not Obj.Header) then
Continue;
if (FMode = 2) and (not Obj.Footer) then
Continue;
if (FMode = 1) and (Obj.Header or Obj.Footer) and
((FHeaderFooterMode = hfPrint) or
(FHeaderFooterMode = hfNone)) then
Continue;
FMatrix.GetObjectPos(i, fx, fy, dx, dy);
if Obj.Counter = -1 then
begin
if dy > 1 then
buff := buff + '\clvmgf';
if (obj.Style.Color mod 16777216) <> $FFFFFF then
buff := buff + '\clcbpat' + GetRTFFontColor(GetRTFColor(Obj.Style.Color));
buff := buff + GetRTFVAlignment(Obj.Style.VAlign) + GetRTFBorders(Obj.Style) + '\cltxlrtb';
dcol := Round((ObjBounds.Right - xoffs) * Xdivider);
buff := buff + '\cellx' + IntToStr(dcol);
if Obj.IsText then
begin
s := '\f' + GetRTFFontName(Obj.Style.Font.Name, Obj.Style.Charset);
s := s + '\fs' + IntToStr(Round(Obj.Style.Font.Size * 2));
s := s + GetRTFFontStyle(Obj.Style.Font.Style);
s := s + '\cf' + GetRTFFontColor(GetRTFColor(Obj.Style.Font.Color));
// export HTML tags
if Obj.HTMLTags then
begin
FHTMLTags := TfrxHTMLTagsList.Create;
try
FHTMLTags.SetDefaults(Obj.Style.Font.Color, Round(Obj.Style.Font.Size), Obj.Style.Font.Style);
FHTMLTags.AllowTags := True;
st := StrToRTFSlash(TruncReturns(Obj.Memo.Text));
st1 := st;
s1 := '';
TagFColor := Obj.Style.Color;
TagFStyleB := 0;
TagFStyleU := 0;
TagFStyleI := 0;
FHTMLTags.ExpandHTMLTags(st);
for i := 0 to FHTMLTags.Count - 1 do
for j := 0 to FHTMLTags[i].Count - 1 do
begin
Tag := FHTMLTags[i].Items[j];
// bold tags
if (fsBold in Tag.Style) and (TagFStyleB = 0) then
begin
Inc(TagFStyleB);
s1 := s1 + '\b ';
end;
if (TagFStyleB > 0) and (not (fsBold in Tag.Style)) then
begin
Dec(TagFStyleB);
s1 := s1 + '\b0 ';
end;
// italic tags
if (fsItalic in Tag.Style) and (TagFStyleI = 0) then
begin
Inc(TagFStyleI);
s1 := s1 + '\i ';
end;
if (TagFStyleI > 0) and (not (fsItalic in Tag.Style)) then
begin
Dec(TagFStyleI);
s1 := s1 + '\i0 ';
end;
// underline tags
if (fsUnderline in Tag.Style) and (TagFStyleU = 0) then
begin
Inc(TagFStyleU);
s1 := s1 + '\ul ';
end;
if (TagFStyleU > 0) and (not (fsUnderline in Tag.Style)) then
begin
Dec(TagFStyleU);
s1 := s1 + '\ul0 ';
end;
// color tags
if (Tag.Color <> Obj.Style.Font.Color) and (Tag.Color <> TagFColor) then
begin
TagFColor := Tag.Color;
s1 := s1 + '\cf' + GetRTFFontColor(GetRTFColor(TagFColor)) + ' ';
end;
if (Tag.Color <> TagFColor) then
begin
TagFColor := Tag.Color;
s1 := s1 + '\cf' + GetRTFFontColor(GetRTFColor(TagFColor)) + ' ';
end;
s1 := s1 + StrToRTFUnicode(st1[Tag.Position]);
end;
s1 := s1 + '\plain';
finally
FHTMLTags.Free;
end;
end
else
s1 := StrToRTFUnicodeEx(TruncReturns(Obj.Memo.Text));
if Trim(s1) <> '' then
begin
s2 := '';
if not Obj.IsRichText then
begin
j := Round(Obj.Style.CharSpacing * FONT_DIVIDER);
if (Obj.Style.GapY + Obj.Style.LineSpacing - 1) > 0 then
n1 := Round((Obj.Style.GapY + Obj.Style.LineSpacing - 1) * YDiv)
else
n1 := 0;
s2 := '\sb' + IntToStr(n1) +
'\li' + IntToStr(Round((Obj.Style.GapX / 2) * Xdivider)) +
'\fi' + IntToStr(Round((Obj.Style.ParagraphGap) * Xdivider)) +
'\expnd' + IntToStr(j div 5) + '\expndtw' + IntToStr(j) +
'\sl-' + IntToStr(Round((Obj.Style.Font.Size * 96 / 72 + Obj.Style.LineSpacing) * YDiv * 0.98)) +
'\slmult0';
if Obj.Style.WordBreak then
s2 := s2 + '\hyphauto1\hyphcaps1';
end
end;
CellsLine := AnsiString(GetRTFHAlignment(Obj.Style.HAlign) +
'{' + s + s2 + ' ' + s1 + '\cell}');
s := '\par'#13#10'\cell';
while Pos(AnsiString(s), CellsLine) > 0 do
CellsLine := AnsiString(StringReplace(String(CellsLine), s, '\cell', []));
CellsStream.Write(CellsLine[1], Length(CellsLine));
end
else if FExportPictures then
begin
Graphic := Obj.Image;
if (Graphic <> nil) and (Graphic.Width <> 0) and (Graphic.Height <> 0) then
SaveGraphic(Graphic, CellsStream, ObjWidth, ObjHeight, PictureType)
end;
Obj.Counter := y + 1;
end
else
begin
if (dy > 1) and (Obj.Counter <> (y + 1)) then
begin
buff := buff + '\clvmrg';
buff := buff + GetRTFBorders(Obj.Style) + '\cltxlrtb';
dcol := Round((ObjBounds.Right - xoffs) * Xdivider);
buff := buff + '\cellx' + IntToStr(dcol);
j := drow div FONT_DIVIDER;
if j > 20 then
j := 20;
CellsLine := '{\fs' + AnsiString(IntToStr(j)) + '\cell}';
CellsStream.Write(CellsLine[1], Length(CellsLine));
Obj.Counter := y + 1;
end;
end
end
end;
if CellsStream.Size > 0 then
begin
s := '\trowd' + buff + '\pard\intbl';
WriteExpLn(s);
Stream.CopyFrom(CellsStream, 0);
WriteExpLn('\pard\intbl{\trowd' + buff + '\row}');
end;
finally
CellsStream.Free;
end;
end;
if FMode in [2, 3] then
WriteExpLn('}');
Dec(FMode);
end;
WriteExpLn('}');
end;
procedure TfrxRTFExport.SaveGraphic(Graphic: TBitmap; Stream: TStream;
Width, Height: Extended; PicType: TfrxPictureType);
var
Blip: TStream;
CellsLine: AnsiString;
n1, n, j: Integer;
s: AnsiString;
bArr: array[0..1023] of Byte;
BlipType: AnsiString;
begin
Blip := TMemoryStream.Create;
try
case PicType of
gpJPG:
begin
BlipType := 'jpegblip';
SaveGraphicAs(Graphic, Blip, gpJPG);
end
else
begin
BlipType := 'pngblip';
SaveGraphicAs(Graphic, Blip, gpPNG);
end;
end;
CellsLine := '{\sb0\li0\sl0\slmult0 {\pict\picw' +
AnsiString(FloatToStr(Round(Width * IMAGE_DIVIDER))) +
'\pich' +
AnsiString(FloatToStr(Round(Height * IMAGE_DIVIDER))) +
'\picscalex98\picscaley98\piccropl0\piccropr0\piccropt0\piccropb0\' +
BlipType +
#13#10;
Stream.Write(CellsLine[1], Length(CellsLine));
{ todo: Rewrite slow code.
This code splits the Blip stream into 64-byte chunks,
converts each byte to 2 hex-dgits, appends each chunk with CRLF
and writes them all to Stream. }
Blip.Position := 0;
n1 := 0; s := '';
repeat
n := Blip.Read(bArr[0], 1024);
for j := 0 to n - 1 do
begin
s := s + AnsiString(IntToHex(bArr[j], 2));
Inc(n1);
if n1 > 63 then
begin
n1 := 0;
CellsLine := s + AnsiString(#13#10);
Stream.Write(CellsLine[1], Length(CellsLine));
s := '';
end;
end;
until n < 1024;
if n1 <> 0 then
begin
CellsLine := s + AnsiString(#13#10);
Stream.Write(CellsLine[1], Length(CellsLine));
end;
CellsLine := '}\cell}' + #13#10;
Stream.Write(CellsLine[1], Length(CellsLine));
finally
Blip.Free
end;
end;
function TfrxRTFExport.ShowModal: TModalResult;
begin
if not Assigned(Stream) then
begin
with TfrxRTFExportDialog.Create(nil) do
begin
OpenCB.Visible := not SlaveExport;
if OverwritePrompt then
SaveDialog1.Options := SaveDialog1.Options + [TOpenOption.ofOverwritePrompt];
if SlaveExport then
FOpenAfterExport := False;
if (FileName = '') and (not SlaveExport) then
SaveDialog1.FileName := ChangeFileExt(ExtractFileName(frxUnixPath2WinPath(Report.FileName)), SaveDialog1.DefaultExt)
else
SaveDialog1.FileName := FileName;
ContinuousCB.IsChecked := SuppressPageHeadersFooters;
PicturesCB.IsChecked := FExportPictures;
PageBreaksCB.IsChecked := FExportPageBreaks;
WCB.IsChecked := FWysiwyg;
OpenCB.IsChecked := FOpenAfterExport;
if PageNumbers <> '' then
begin
PageNumbersE.Text := PageNumbers;
PageNumbersRB.IsChecked := True;
end;
if FHeaderFooterMode = hfText then
PColontitulCB.ItemIndex := 0
else if FHeaderFooterMode = hfPrint then
PColontitulCB.ItemIndex := 1
else
PColontitulCB.ItemIndex := 2;
Result := ShowModal;
PeekLastModalResult;
if Result = mrOk then
begin
if PColontitulCB.ItemIndex = 0 then
FHeaderFooterMode := hfText
else if PColontitulCB.ItemIndex = 1 then
FHeaderFooterMode := hfPrint
else
FHeaderFooterMode := hfNone;
PageNumbers := '';
CurPage := False;
if CurPageRB.IsChecked then
CurPage := True
else if PageNumbersRB.IsChecked then
PageNumbers := PageNumbersE.Text;
SuppressPageHeadersFooters := ContinuousCB.IsChecked;
if FHeaderFooterMode = hfPrint then
SuppressPageHeadersFooters := True;
FExportPictures := PicturesCB.IsChecked;
FExportPageBreaks := PageBreaksCB.IsChecked;
FWysiwyg := WCB.IsChecked;
FOpenAfterExport := OpenCB.IsChecked;
if not SlaveExport then
begin
if DefaultPath <> '' then
SaveDialog1.InitialDir := DefaultPath;
if SaveDialog1.Execute then
FileName := SaveDialog1.FileName
else
Result := mrCancel;
PeekLastModalResult;
end
end;
Free;
end;
end else
Result := mrOk;
end;
function TfrxRTFExport.Start: Boolean;
begin
if SlaveExport then
begin
if Report.FileName <> '' then
FileName := ChangeFileExt(GetTemporaryFolder + ExtractFileName(Report.FileName), frxGet(8505))
else
FileName := ChangeFileExt(GetTempFile, frxGet(8505))
end;
if (FileName <> '') or Assigned(Stream) then
begin
if (ExtractFilePath(FileName) = '') and (DefaultPath <> '') then
FileName := DefaultPath + '\' + FileName;
FFirstPage := True;
FCurrentPage := 0;
FMatrix := TfrxIEMatrix.Create(UseFileCache, Report.EngineOptions.TempDir);
FMatrix.ShowProgress := ShowProgress;
if FWysiwyg then
FMatrix.Inaccuracy := 0.5
else
FMatrix.Inaccuracy := 10;
FMatrix.RotatedAsImage := True;
FMatrix.RichText := True;
FMatrix.PlainRich := False;
FMatrix.AreaFill := True;
FMatrix.CropAreaFill := True;
FMatrix.DeleteHTMLTags := False;
FMatrix.BackgroundImage := False;
FMatrix.Background := False;
FMatrix.Printable := ExportNotPrintable;
FMatrix.EMFPictures := PictureType <> gpBMP;
FFontTable := TStringList.Create;
FCharsetTable := TStringList.Create;
FColorTable := TStringList.Create;
FDataList := TList.Create;
Result := True
end
else
Result := False;
end;
procedure TfrxRTFExport.StartPage(Page: TfrxReportPage; Index: Integer);
begin
Inc(FCurrentPage);
if FFirstPage then
FFirstPage := False;
end;
procedure TfrxRTFExport.ExportObject(Obj: TfrxComponent);
begin
if (Obj is TfrxPageHeader) and (ExportNotPrintable or TfrxView(Obj).Printable) then
FMatrix.SetPageHeader(TfrxBand(Obj))
else if (Obj is TfrxPageFooter) and (ExportNotPrintable or TfrxView(Obj).Printable) then
FMatrix.SetPageFooter(TfrxBand(Obj))
else if (Obj is TfrxView) and (ExportNotPrintable or TfrxView(Obj).Printable) then
begin
if (Obj is TfrxCustomMemoView) or
(FExportPictures and (not (Obj is TfrxCustomMemoView))) then
FMatrix.AddObject(TfrxView(Obj))
end;
end;
procedure TfrxRTFExport.FinishPage(Page: TfrxReportPage; Index: Integer);
begin
FMatrix.AddPage(Page.Orientation, Page.Width, Page.Height, Page.LeftMargin,
Page.TopMargin, Page.RightMargin, Page.BottomMargin, Page.MirrorMargins, Index);
end;
procedure TfrxRTFExport.Finish;
var
Exp: TStream;
begin
FMatrix.Prepare;
if ShowProgress then
FProgress := TfrxProgress.Create(nil);
try
if Assigned(Stream) then
Exp := Stream
else
Exp := TFileStream.Create(FileName, fmCreate);
try
ExportPage(Exp);
finally
if not Assigned(Stream) then
Exp.Free;
end;
if FOpenAfterExport and (not Assigned(Stream)) then
{$IFDEF MSWINDOWS}
ShellExecute(0, 'open', PChar(FileName), '', '', 5);
{$ENDIF}
{$IFDEF LINUX}
FmuxOpenFile(PChar(FileName));
{$ENDIF}
{$IFDEF MACOS}
ShellExecute(FileName);
{$ENDIF}
except
on e: Exception do
case Report.EngineOptions.NewSilentMode of
simSilent: Report.Errors.Add(e.Message);
simMessageBoxes: frxErrorMsg(e.Message);
simReThrow: raise;
end;
end;
FMatrix.Clear;
FMatrix.Free;
FFontTable.Free;
FCharsetTable.Free;
FColorTable.Free;
FDataList.Free;
if ShowProgress then
FProgress.Free;
end;
{ TfrxRTFExportDialog }
procedure TfrxRTFExportDialog.FormCreate(Sender: TObject);
begin
Caption := frxGet(8500);
OkB.Text := frxGet(1);
CancelB.Text := frxGet(2);
GroupPageRange.Text := frxGet(7);
AllRB.Text := frxGet(3);
CurPageRB.Text := frxGet(4);
PageNumbersRB.Text := frxGet(5);
DescrL.Text := frxGet(9);
GroupQuality.Text := frxGet(8);
ContinuousCB.Text := frxGet(8950);
PicturesCB.Text := frxGet(8501);
PageBreaksCB.Text := frxGet(6);
WCB.Text := frxGet(8502);
OpenCB.Text := frxGet(8503);
SaveDialog1.Filter := frxGet(8504);
SaveDialog1.DefaultExt := frxGet(8505);
HeadFootL.Text := frxGet(8951);
PColontitulCB.Items[0] := frxGet(8952);
PColontitulCB.Items[1] := frxGet(8953);
PColontitulCB.Items[2] := frxGet(8954);
{$IFDEF LINUX}
BorderStyleSizeable(Self);
{$ENDIF}
end;
procedure TfrxRTFExportDialog.PageNumbersEChange(Sender: TObject);
begin
PageNumbersRB.IsChecked := True;
end;
procedure TfrxRTFExportDialog.PageNumbersEKeyDown(Sender: TObject;var Key: Word;
var KeyChar: WideChar; Shift: TShiftState);
begin
case KeyChar of
'0'..'9':;
#8, '-', ',':;
else
key := 0;
end;
end;
procedure TfrxRTFExportDialog.FormKeyDown(Sender: TObject; var Key: Word;
var KeyChar: WideChar; Shift: TShiftState);
begin
if Key = VK_F1 then
frxResources.Help(Self);
end;
end.