📄 frxpreviewpages.pas
字号:
end;
procedure TfrxPreviewPages.AddObject(Obj: TfrxComponent);
procedure DoAdd(c: TfrxComponent; Item: TfrxXMLItem);
var
i: Integer;
begin
if not c.Visible then Exit;
{ do not put out subreports, cross-tabs and dialog components }
if not ((c is TfrxSubReport) or (CompareText(c.ClassName, 'TfrxCrossView') = 0) or
(CompareText(c.ClassName, 'TfrxDBCrossView') = 0) or (c is TfrxDialogComponent)) then
with THackComponent(c) do
begin
Item := Item.Add;
{ the component that was created after report has been started }
if FOriginalComponent = nil then
begin
Item.Name := ClassName;
Item.Text := AllDiff(nil);
end
else
begin
{ the component that exists in the report template }
Item.Name := FAliasName;
if Engine.FinalPass then
begin
if DefaultDiff then
Item.Text := AllDiff(FOriginalComponent) else
Item.Text := Diff(FOriginalComponent);
end
else
{ we don't need to output all info on the first pass, only coordinates }
Item.Text := InternalDiff(FOriginalComponent);
end;
Inc(FXMLSize, Length(Item.Name) + Length(Item.Text) + Item.InstanceSize + 16);
end;
for i := 0 to c.Objects.Count - 1 do
DoAdd(c.Objects[i], Item);
end;
begin
DoAdd(Obj, CurXMLPage);
end;
procedure TfrxPreviewPages.AddPage(Page: TfrxReportPage);
var
xi: TfrxXMLItem;
procedure UnloadPages;
var
i: Integer;
begin
if Report.EngineOptions.UseFileCache then
if FXMLSize > Report.EngineOptions.MaxMemSize * 1024 * 1024 then
begin
for i := xi.Count - 2 downto 0 do
if xi[i].Loaded then
FXMLDoc.UnloadItem(xi[i]) else
break;
FXMLSize := 0;
end;
end;
function GetSourceNo(Page: TfrxReportPage): Integer;
var
i: Integer;
begin
Result := -1;
for i := 0 to FSourcePages.Count - 1 do
if THackComponent(FSourcePages[i]).FOriginalComponent = Page then
begin
Result := i;
break;
end;
end;
begin
FPagesItem := FXMLDoc.Root.FindItem('previewpages');
xi := FPagesItem;
UnloadPages;
CurPage := CurPage + 1;
if (CurPage >= Count) or (AddPageAction = apAdd) then
begin
xi := xi.Add;
xi.Name := 'page' + IntToStr(GetSourceNo(Page));
if Count > 2 then
xi.Unloadable := True;
Report.InternalOnProgress(ptRunning, CurPage + 1);
AddPageAction := apWriteOver;
CurPage := Count - 1;
end;
end;
procedure TfrxPreviewPages.AddSourcePage(Page: TfrxReportPage);
var
p: TfrxReportPage;
xs: TfrxXMLSerializer;
i: Integer;
originals, copies: TList;
c1, c2: TfrxComponent;
s: String;
function EnumObjects(Parent, Parent1: TfrxComponent): TfrxComponent;
var
i: Integer;
c: TfrxComponent;
begin
Result := nil;
if (CompareText(Parent.ClassName, 'TfrxCrossView') = 0) or
(CompareText(Parent.ClassName, 'TfrxDBCrossView') = 0) or
(Parent is TfrxDialogComponent) then Exit;
c := TfrxComponent(Parent.NewInstance);
c.Create(Parent1);
c.Assign(Parent);
c.Name := Parent.Name;
originals.Add(Parent);
copies.Add(c);
for i := 0 to Parent.Objects.Count - 1 do
EnumObjects(Parent.Objects[i], c);
Result := c;
end;
begin
xs := TfrxXMLSerializer.Create(nil);
originals := TList.Create;
copies := TList.Create;
try
p := TfrxReportPage(EnumObjects(Page, nil));
THackComponent(p).FOriginalComponent := Page;
FSourcePages.Add(p);
for i := 1 to copies.Count - 1 do
begin
c1 := copies[i];
c2 := originals[i];
THackComponent(c2).FOriginalComponent := c1;
THackComponent(c1).FOriginalComponent := c2;
if c1 is TfrxBand then
s := 'b' else
s := LowerCase(c1.BaseName[1]);
s := FDictionary.AddUnique(s, 'Page' + IntToStr(FSourcePages.Count - 1) +
'.' + c1.Name, c1);
if c1.DefaultDiff then
THackComponent(c1).FBaseName := c1.ClassName else
THackComponent(c1).FBaseName := xs.WriteComponentStr(c1);
THackComponent(c1).FAliasName := s;
THackComponent(c2).FAliasName := s;
end;
finally
originals.Free;
copies.Free;
xs.Free;
end;
end;
procedure TfrxPreviewPages.AddToSourcePage(Obj: TfrxComponent);
var
NewObj: TfrxComponent;
Page: TfrxReportPage;
s: String;
xs: TfrxXMLSerializer;
begin
xs := TfrxXMLSerializer.Create(nil);
Page := FSourcePages[FSourcePages.Count - 1];
NewObj := TfrxComponent(Obj.NewInstance);
NewObj.Create(Page);
NewObj.Assign(Obj);
NewObj.CreateUniqueName;
s := FDictionary.AddUnique(LowerCase(NewObj.BaseName[1]),
'Page' + IntToStr(FSourcePages.Count - 1) + '.' + NewObj.Name, NewObj);
if NewObj.DefaultDiff then
THackComponent(NewObj).FBaseName := NewObj.ClassName else
THackComponent(NewObj).FBaseName := xs.WriteComponentStr(NewObj);
THackComponent(Obj).FOriginalComponent := NewObj;
THackComponent(Obj).FAliasName := s;
THackComponent(NewObj).FAliasName := s;
xs.Free;
end;
procedure TfrxPreviewPages.Finish;
var
i: Integer;
begin
ClearPageCache;
{ avoid bug with multiple PrepareReport(False) }
for i := 0 to FSourcePages.Count - 1 do
THackComponent(FSourcePages[i]).FOriginalComponent := nil;
Report.InternalOnProgressStop(ptRunning);
end;
function TfrxPreviewPages.BandExists(Band: TfrxBand): Boolean;
var
i: Integer;
c: TfrxComponent;
begin
Result := False;
for i := 0 to CurXMLPage.Count - 1 do
begin
c := GetObject(CurXMLPage[i].Name);
if c <> nil then
if (THackComponent(c).FOriginalComponent = Band) or
((Band is TfrxPageFooter) and (c is TfrxPageFooter)) or
((Band is TfrxColumnFooter) and (c is TfrxColumnFooter)) then
begin
Result := True;
break;
end;
end;
end;
function TfrxPreviewPages.GetLastY: Extended;
var
i: Integer;
c: TfrxComponent;
s: String;
y: Extended;
begin
Result := 0;
for i := 0 to CurXMLPage.Count - 1 do
begin
c := GetObject(CurXMLPage[i].Name);
if c is TfrxBand then
if not (c is TfrxPageFooter) and not (c is TfrxOverlay) then
begin
s := CurXMLPage[i].Prop['t'];
if s <> '' then
y := frxStrToFloat(s) else
y := c.Top;
s := CurXMLPage[i].Prop['h'];
if s <> '' then
y := y + frxStrToFloat(s) else
y := y + c.Height;
if y > Result then
Result := y;
end;
end;
end;
procedure TfrxPreviewPages.CutObjects(APosition: Integer);
var
xi: TfrxXMLItem;
begin
xi := FXMLDoc.Root.FindItem('cutted');
while APosition < CurXMLPage.Count do
xi.AddItem(CurXMLPage[APosition]);
end;
procedure TfrxPreviewPages.PasteObjects(X, Y: Extended);
var
xi: TfrxXMLItem;
LeftX, TopY, CorrX, CorrY: Extended;
procedure CorrectX(xi: TfrxXMLItem);
var
X: Extended;
begin
if xi.Prop['l'] <> '' then
X := frxStrToFloat(xi.Prop['l']) else
X := 0;
X := X + CorrX;
xi.Prop['l'] := FloatToStr(X);
end;
procedure CorrectY(xi: TfrxXMLItem);
var
Y: Extended;
begin
if xi.Prop['t'] <> '' then
Y := frxStrToFloat(xi.Prop['t']) else
Y := 0;
Y := Y + CorrY;
xi.Prop['t'] := FloatToStr(Y);
end;
begin
xi := FXMLDoc.Root.FindItem('cutted');
if xi.Count > 0 then
begin
if xi[0].Prop['l'] <> '' then
LeftX := frxStrToFloat(xi[0].Prop['l']) else
LeftX := 0;
CorrX := X - LeftX;
if xi[0].Prop['t'] <> '' then
TopY := frxStrToFloat(xi[0].Prop['t']) else
TopY := 0;
CorrY := Y - TopY;
while xi.Count > 0 do
begin
CorrectX(xi[0]);
CorrectY(xi[0]);
CurXMLPage.AddItem(xi[0]);
end;
end;
xi.Free;
end;
procedure TfrxPreviewPages.DoLoadFromStream;
var
Compressor: TfrxCustomCompressor;
begin
Compressor := nil;
if frxCompressorClass <> nil then
begin
FAllowPartialLoading := False;
Compressor := TfrxCustomCompressor(frxCompressorClass.NewInstance);
Compressor.Create(nil);
Compressor.Report := Report;
Compressor.IsFR3File := False;
try
Compressor.CreateStream;
Compressor.Decompress(FTempStream);
FTempStream := Compressor.Stream;
except
Compressor.Free;
Report.Errors.Add(frxResources.Get('clDecompressError'));
frxCommonErrorHandler(Report, frxResources.Get('clErrors') + #13#10 + Report.Errors.Text);
Exit;
end;
end;
FXMLDoc.LoadFromStream(FTempStream, FAllowPartialLoading);
AfterLoad;
if Compressor <> nil then
Compressor.Free;
end;
procedure TfrxPreviewPages.DoSaveToStream;
var
Compressor: TfrxCustomCompressor;
StreamTo: TStream;
begin
StreamTo := FTempStream;
Compressor := nil;
if Report.ReportOptions.Compressed and (frxCompressorClass <> nil) then
begin
Compressor := TfrxCustomCompressor(frxCompressorClass.NewInstance);
Compressor.Create(nil);
Compressor.Report := Report;
Compressor.IsFR3File := False;
Compressor.CreateStream;
StreamTo := Compressor.Stream;
end;
try
BeforeSave;
FXMLDoc.SaveToStream(StreamTo);
finally
if Compressor <> nil then
begin
try
Compressor.Compress(FTempStream);
finally
Compressor.Free;
end;
end;
end;
end;
procedure TfrxPreviewPages.LoadFromStream(Stream: TStream;
AllowPartialLoading: Boolean = False);
begin
Clear;
FTempStream := Stream;
FAllowPartialLoading := AllowPartialLoading;
{$IFNDEF FR_COM}
// if Report.EngineOptions.ReportThread <> nil then
// THackThread(Report.EngineOptions.ReportThread).Synchronize(DoLoadFromStream)
// else
{$ENDIF}
DoLoadFromStream;
end;
procedure TfrxPreviewPages.SaveToStream(Stream: TStream);
begin
FTempStream := Stream;
{$IFNDEF FR_COM}
// if Report.EngineOptions.ReportThread <> nil then
// THackThread(Report.EngineOptions.ReportThread).Synchronize(DoSaveToStream)
// else
{$ENDIF}
DoSaveToStream;
end;
function TfrxPreviewPages.LoadFromFile(const FileName: String;
ExceptionIfNotFound: Boolean): Boolean;
var
Stream: TFileStream;
begin
Result := FileExists(FileName);
if Result or ExceptionIfNotFound then
begin
Stream := TFileStream.Create(FileName, fmOpenRead + fmShareDenyWrite);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
{ Clear;
FXMLDoc.LoadFromFile(FileName);
AfterLoad;}
end;
end;
procedure TfrxPreviewPages.SaveToFile(const FileName: String);
var
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
SaveToStream(Stream);
finally
Stream.Free;
end;
{ BeforeSave;
FXMLDoc.SaveToFile(FileName);
ClearPageCache;
AfterLoad;}
end;
procedure TfrxPreviewPages.AfterLoad;
var
i: Integer;
xs: TfrxXMLSerializer;
xi: TfrxXMLItem;
p: TfrxReportPage;
{ store source objects' properties in the FBaseName to get it later in the GetPage }
procedure DoProps(p: TfrxReportPage);
var
i: Integer;
l: TList;
c: THackComponent;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -