LazReport: fix potential AV on execute script for dialog pages

Increased speed of report template import from a spreadsheet
fix compile with latest Lazarus
fix AV after destroy report designer
fix create CrossTab report on multiple pages
fix editing prepared report

from Aleksey Lagunov, issue #31457

git-svn-id: trunk@54576 -
This commit is contained in:
jesus 2017-04-08 15:58:09 +00:00
parent 4005ada739
commit b96124b3dc
7 changed files with 125 additions and 57 deletions

View File

@ -1490,21 +1490,26 @@ var
FSaveView:TfrView; FSaveView:TfrView;
FSavePage:TfrPage; FSavePage:TfrPage;
CmdList, ErrorList:TStringList; CmdList, ErrorList:TStringList;
FSaveBand: TfrBand;
begin begin
if (DocMode = dmPrinting) and (Script.Count>0) and (Trim(Script.Text)<>'') and (Assigned(CurReport))then if (DocMode = dmPrinting) and (Script.Count>0) and (Trim(Script.Text)<>'') and (Assigned(CurReport))then
begin begin
FSaveView:=CurView; FSaveView:=CurView;
FSavePage:=CurPage; FSavePage:=CurPage;
FSaveBand:=CurBand;
CmdList:=TStringList.Create; CmdList:=TStringList.Create;
ErrorList:=TStringList.Create; ErrorList:=TStringList.Create;
try try
CurView := Self; CurView := Self;
CurPage:=OwnerPage; CurPage:=OwnerPage;
CurBand:=nil;
frInterpretator.PrepareScript(Script, CmdList, ErrorList); frInterpretator.PrepareScript(Script, CmdList, ErrorList);
frInterpretator.DoScript(CmdList); frInterpretator.DoScript(CmdList);
finally finally
CurPage:=FSavePage; CurPage:=FSavePage;
CurView := FSaveView; CurView := FSaveView;
CurBand:=FSaveBand;
FreeAndNil(CmdList); FreeAndNil(CmdList);
FreeAndNil(ErrorList); FreeAndNil(ErrorList);
end; end;

View File

@ -147,7 +147,7 @@ type
end; end;
implementation implementation
uses Forms, LR_Utils, LazUTF8, Printers, FPReadBMP, FPReadPNG, FPReadJPEG; uses LazFileUtils, Forms, LR_Utils, LazUTF8, Printers, FPReadBMP, FPReadPNG, FPReadJPEG;
const const
cInchToMM = 25.4; cInchToMM = 25.4;

View File

@ -1,19 +1,19 @@
object lrSpreadSheetImportForm: TlrSpreadSheetImportForm object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
Left = 699 Left = 699
Height = 200 Height = 201
Top = 384 Top = 384
Width = 520 Width = 520
Caption = 'Import from spreadsheet' Caption = 'Import from spreadsheet'
ClientHeight = 200 ClientHeight = 201
ClientWidth = 520 ClientWidth = 520
OnClose = FormClose OnClose = FormClose
Position = poScreenCenter Position = poScreenCenter
LCLVersion = '1.3' LCLVersion = '1.7'
object Label1: TLabel object Label1: TLabel
AnchorSideLeft.Control = Owner AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner AnchorSideTop.Control = Owner
Left = 6 Left = 6
Height = 21 Height = 20
Top = 6 Top = 6
Width = 62 Width = 62
BorderSpacing.Around = 6 BorderSpacing.Around = 6
@ -22,8 +22,8 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
end end
object ButtonPanel1: TButtonPanel object ButtonPanel1: TButtonPanel
Left = 6 Left = 6
Height = 41 Height = 46
Top = 153 Top = 149
Width = 508 Width = 508
OKButton.Name = 'OKButton' OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True OKButton.DefaultCaption = True
@ -43,8 +43,8 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 12 Left = 12
Height = 31 Height = 37
Top = 33 Top = 32
Width = 502 Width = 502
FilterIndex = 0 FilterIndex = 0
HideDirectories = False HideDirectories = False
@ -60,9 +60,9 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideBottom.Control = Edit1 AnchorSideBottom.Control = Edit1
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 6 Left = 6
Height = 21 Height = 20
Top = 80 Top = 122
Width = 46 Width = 45
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Left up' Caption = 'Left up'
@ -72,12 +72,12 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
object Edit1: TEdit object Edit1: TEdit
AnchorSideLeft.Control = Label3 AnchorSideLeft.Control = Label3
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = FileNameEdit1 AnchorSideTop.Control = CheckBox1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 86 Left = 85
Height = 31 Height = 37
Top = 70 Top = 105
Width = 80 Width = 82
BorderSpacing.Around = 6 BorderSpacing.Around = 6
TabOrder = 2 TabOrder = 2
Visible = False Visible = False
@ -85,12 +85,12 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
object Edit2: TEdit object Edit2: TEdit
AnchorSideLeft.Control = Edit1 AnchorSideLeft.Control = Edit1
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = FileNameEdit1 AnchorSideTop.Control = CheckBox1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 172 Left = 173
Height = 31 Height = 37
Top = 70 Top = 105
Width = 80 Width = 82
BorderSpacing.Around = 6 BorderSpacing.Around = 6
TabOrder = 3 TabOrder = 3
Visible = False Visible = False
@ -100,9 +100,9 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideBottom.Control = Edit3 AnchorSideBottom.Control = Edit3
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 6 Left = 6
Height = 21 Height = 20
Top = 117 Top = 165
Width = 74 Width = 73
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'Right down' Caption = 'Right down'
@ -114,10 +114,10 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Edit1 AnchorSideTop.Control = Edit1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 86 Left = 85
Height = 31 Height = 37
Top = 107 Top = 148
Width = 80 Width = 82
BorderSpacing.Around = 6 BorderSpacing.Around = 6
TabOrder = 4 TabOrder = 4
Visible = False Visible = False
@ -127,10 +127,10 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Edit2 AnchorSideTop.Control = Edit2
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 172 Left = 173
Height = 31 Height = 37
Top = 107 Top = 148
Width = 80 Width = 82
BorderSpacing.Around = 6 BorderSpacing.Around = 6
TabOrder = 5 TabOrder = 5
Visible = False Visible = False
@ -140,9 +140,9 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideBottom.Control = Edit5 AnchorSideBottom.Control = Edit5
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 258 Left = 261
Height = 21 Height = 20
Top = 117 Top = 165
Width = 31 Width = 31
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 6 BorderSpacing.Left = 6
@ -155,12 +155,24 @@ object lrSpreadSheetImportForm: TlrSpreadSheetImportForm
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = Edit2 AnchorSideTop.Control = Edit2
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 295 Left = 298
Height = 31 Height = 37
Top = 107 Top = 148
Width = 80 Width = 82
BorderSpacing.Around = 6 BorderSpacing.Around = 6
TabOrder = 6 TabOrder = 6
Visible = False Visible = False
end end
object CheckBox1: TCheckBox
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = FileNameEdit1
AnchorSideTop.Side = asrBottom
Left = 6
Height = 24
Top = 75
Width = 374
BorderSpacing.Around = 6
Caption = 'Use not standart object names (improve import speed)'
TabOrder = 7
end
end end

View File

@ -44,6 +44,7 @@ type
TlrSpreadSheetImportForm = class(TForm) TlrSpreadSheetImportForm = class(TForm)
ButtonPanel1: TButtonPanel; ButtonPanel1: TButtonPanel;
CheckBox1: TCheckBox;
Edit1: TEdit; Edit1: TEdit;
Edit2: TEdit; Edit2: TEdit;
Edit3: TEdit; Edit3: TEdit;
@ -127,8 +128,9 @@ var
Cell:PCell; Cell:PCell;
X, Y, DX, DY: Integer; X, Y, DX, DY: Integer;
Row: Integer; Row: Integer;
Col: Integer; Col, DY1, DX1: Integer;
T:TfrMemoView; T:TfrMemoView;
AR1, AC1, AR2, AC2, i: Cardinal;
begin begin
// Create the spreadsheet // Create the spreadsheet
FWorkbook := TsWorkbook.Create; FWorkbook := TsWorkbook.Create;
@ -145,29 +147,58 @@ begin
for Col:=0 to FWorksheet.GetLastColIndex do for Col:=0 to FWorksheet.GetLastColIndex do
begin begin
Cell := FWorksheet.FindCell(Row, Col); Cell := FWorksheet.FindCell(Row, Col);
if Assigned(Cell) then if Assigned(Cell) then
begin begin
if FWorksheet.IsMerged(Cell) then
begin
if not FWorksheet.IsMergeBase(Cell) then
begin
Inc(X, CalcColWidth(FWorksheet.GetColWidth(Col)));
Continue;
end;
FWorksheet.FindMergedRange(Cell, AR1, AC1, AR2, AC2);
DX1:=0;
DY1:=0;
for i:=AC1 to AC2 do
DX1:=DX1 +CalcColWidth(FWorksheet.GetColWidth(I));
for i:=AR1 to AR2 do
DY1:=DY1 +CalcRowHeight(FWorksheet.GetRowHeight(I));
end
else
begin
DX1:=CalcColWidth(FWorksheet.GetColWidth(Col));
DY1:=DY;
end;
T := frCreateObject(gtMemo, '', frDesigner.Page) as TfrMemoView; T := frCreateObject(gtMemo, '', frDesigner.Page) as TfrMemoView;
T.CreateUniqueName;
if not CheckBox1.Checked then
T.CreateUniqueName
else
T.Name:=Format('Memo_Imp_%d_%d', [Col, Row]);
T.x := x; T.x := x;
T.y := y; T.y := y;
T.dx:=CalcColWidth(FWorksheet.GetColWidth(Col)); T.dx:=DX1;
T.dy:=DY; T.dy:=DY1;
T.Alignment:=sHAToA(FWorksheet.ReadHorAlignment(Cell)); // Cell^.HorAlignment); T.Alignment:=sHAToA(FWorksheet.ReadHorAlignment(Cell));
T.Layout:=sVAToL(FWorksheet.ReadVertAlignment(Cell)); // Cell^.VertAlignment); T.Layout:=sVAToL(FWorksheet.ReadVertAlignment(Cell));
T.Frames:=sBorderToBorders(FWorksheet.ReadCellBorders(Cell));
T.Frames:=sBorderToBorders(FWorksheet.ReadCellBorders(Cell)); //Cell^.Border);
// BorderStyles: TsCelLBorderStyles;
{ {
if Cell^.BackgroundColor < FWorkbook.GetPaletteSize then if Cell^.BackgroundColor < FWorkbook.GetPaletteSize then
T.FillColor:=FWorkbook.GetPaletteColor(Cell^.BackgroundColor); T.FillColor:=FWorkbook.GetPaletteColor(Cell^.BackgroundColor);
} }
Convert_sFont_to_Font(FWorksheet.ReadCellFont(Cell), T.Font); //Cell^.FontIndex), T.Font); T.FillColor:=FWorksheet.ReadBackgroundColor(Cell);
Convert_sFont_to_Font(FWorksheet.ReadCellFont(Cell), T.Font);
T.MonitorFontChanges; T.MonitorFontChanges;
T.Memo.Text:=FWorksheet.ReadAsUTF8Text(Cell); T.Memo.Text:=FWorksheet.ReadAsUTF8Text(Cell);
// frDesigner.Page.Objects.Add(t);
end end
else else
@ -212,7 +243,6 @@ begin
if fssItalic in sFont.Style then AFont.Style := AFont.Style + [fsItalic]; if fssItalic in sFont.Style then AFont.Style := AFont.Style + [fsItalic];
if fssUnderline in sFont.Style then AFont.Style := AFont.Style + [fsUnderline]; if fssUnderline in sFont.Style then AFont.Style := AFont.Style + [fsUnderline];
if fssStrikeout in sFont.Style then AFont.Style := AFont.Style + [fsStrikeout]; if fssStrikeout in sFont.Style then AFont.Style := AFont.Style + [fsStrikeout];
//AFont.Color := FWorkbook.GetPaletteColor(sFont.Color);
AFont.Color := sFont.Color; AFont.Color := sFont.Color;
end; end;
end; end;

View File

@ -7406,7 +7406,8 @@ begin
RTObjects.Free; RTObjects.Free;
List.Free; List.Free;
fMargins.Free; fMargins.Free;
if Assigned(frDesigner) and (frDesigner.Page = Self) then
frDesigner.Page:=nil;
inherited Destroy; inherited Destroy;
end; end;

View File

@ -775,6 +775,8 @@ begin
FPage:=TlrCrossPage.Create(nil); FPage:=TlrCrossPage.Create(nil);
FPage.ChangePaper(OwnerPage.pgSize, OwnerPage.Width, OwnerPage.Height, OwnerPage.Orientation); FPage.ChangePaper(OwnerPage.pgSize, OwnerPage.Width, OwnerPage.Height, OwnerPage.Orientation);
FPage.UseMargins:=OwnerPage.UseMargins;
FPage.Margins.AsRect:=OwnerPage.Margins.AsRect;
if FShowTotalRHCell then if FShowTotalRHCell then
begin begin
@ -912,12 +914,13 @@ begin
FPage.PlayFrom := 0; FPage.PlayFrom := 0;
while FPage.PlayFrom < FPage.List.Count do while FPage.PlayFrom < FPage.List.Count do
begin begin
FPage.PlayRecList; if FPage.PlayRecList then
{ if FPage.List.Count > FPage.PlayFrom then Inc(FPage.PlayFrom);
FPage.NewPage;}
end; end;
FPage.DoneReport; FPage.DoneReport;
if Assigned(FSavePage) then
FSavePage.CurY:=FPage.CurY;
FPage.Free; FPage.Free;
CurPage:=FSavePage; CurPage:=FSavePage;

View File

@ -1536,11 +1536,28 @@ begin
end; end;
procedure TfrPreviewForm.EditBtnClick(Sender: TObject); procedure TfrPreviewForm.EditBtnClick(Sender: TObject);
var
R: TfrReport;
begin begin
if (Doc = nil) or not TfrReport(Doc).ModifyPrepared then Exit; if (Doc = nil) or not TfrReport(Doc).ModifyPrepared then Exit;
ConnectBack; { ConnectBack;
TfrReport(Doc).EditPreparedReport(CurPage - 1); TfrReport(Doc).EditPreparedReport(CurPage - 1);
Connect(Doc); Connect(Doc);}
R:=TfrReport.Create(nil);
R.EMFPages.Free;
R.EMFPages := TfrEMFPages(EMFPages);
EMFPages := nil;
R.EditPreparedReport(CurPage - 1);
if EMFPages <> nil then
TfrEMFPages(EMFPages).Free;
EMFPages := R.EMFPages;
R.EMFPages:=nil;
// TfrReport(Doc).EMFPages := TfrEMFPages.Create(TfrReport(Doc));
R.Free;
RedrawAll; RedrawAll;
end; end;