diff --git a/components/lazreport/source/addons/ZeosDB/lr_db_zeos.pas b/components/lazreport/source/addons/ZeosDB/lr_db_zeos.pas index ab23c65b6a..dd492e91a8 100644 --- a/components/lazreport/source/addons/ZeosDB/lr_db_zeos.pas +++ b/components/lazreport/source/addons/ZeosDB/lr_db_zeos.pas @@ -103,7 +103,7 @@ implementation {$R lr_zeos_img.res} uses LR_Utils, DBPropEdits, PropEdits, LazarusPackageIntf, ZDbcIntfs, types, - lr_EditParams, Forms, Controls, variants, Dialogs; + lr_EditParams, Forms, Controls, variants, Dialogs, strutils; var lrBMP_ZQuery:TBitmap = nil; @@ -316,6 +316,9 @@ end; procedure TLRZQuery.AfterLoad; var D:TComponent; + SPage: String; + S: String; + Z: TLRZConnection; begin D:=frFindComponent(OwnerForm, DataSource); if Assigned(D) and (D is TDataSource)then @@ -326,6 +329,21 @@ begin begin TZQuery(DataSet).Connection:=TZConnection(D); DataSet.Active:=FActive; + end + else + if Assigned(CurReport) then + begin + S:=FDatabase; + if Pos('.', S)>0 then + SPage:=Copy2SymbDel(S, '.') + else + SPage:=''; + Z:=CurReport.FindObject(S) as TLRZConnection; + if Assigned(Z) then + begin + TZQuery(DataSet).Connection:=Z.FZConnection; + DataSet.Active:=FActive; + end end; end; @@ -339,7 +357,7 @@ begin DataSet.Active:=false; D:=frFindComponent(TZQuery(DataSet).Owner, FDatabase); if Assigned(D) and (D is TZConnection)then - TZQuery(DataSet).Connection:=TZConnection(D); + TZQuery(DataSet).Connection:=TZConnection(D) end; procedure TLRZQuery.ZQueryBeforeOpen(ADataSet: TDataSet); @@ -610,9 +628,31 @@ end; { TLRZQueryDataBaseProperty } procedure TLRZQueryDataBaseProperty.FillValues(const Values: TStringList); +var + i: Integer; + j: Integer; + S: String; begin if (GetComponent(0) is TLRZQuery) then + begin frGetComponents(nil, TZConnection, Values, nil); + + if Assigned(CurReport) then + begin + for i:=0 to CurReport.Pages.Count-1 do + if CurReport.Pages[i] is TfrPageDialog then + begin + for j:=0 to CurReport.Pages[i].Objects.Count-1 do + begin + if TfrObject(CurReport.Pages[i].Objects[j]) is TLRZConnection then + begin + S:=CurReport.Pages[i].Name+'.'+TLRDataSetControl(CurReport.Pages[i].Objects[j]).lrDBDataSet.Name; + Values.Add(S); + end; + end; + end; + end; + end; end; diff --git a/components/lazreport/source/addons/ZeosDB/lr_zeosdb.lpk b/components/lazreport/source/addons/ZeosDB/lr_zeosdb.lpk index 263b9dcfc8..6aff8907fa 100644 --- a/components/lazreport/source/addons/ZeosDB/lr_zeosdb.lpk +++ b/components/lazreport/source/addons/ZeosDB/lr_zeosdb.lpk @@ -1,4 +1,4 @@ - + @@ -8,39 +8,29 @@ - - - - - - - + - - - - - - + + - - + + - + diff --git a/components/lazreport/source/addons/cairoexport/lr_e_cairo.pas b/components/lazreport/source/addons/cairoexport/lr_e_cairo.pas index a5c3f75abd..6631214adf 100644 --- a/components/lazreport/source/addons/cairoexport/lr_e_cairo.pas +++ b/components/lazreport/source/addons/cairoexport/lr_e_cairo.pas @@ -80,6 +80,7 @@ type end; implementation +uses LR_Utils; // missing cairo functions to make shared images posible const @@ -767,7 +768,12 @@ begin if fCairoPrinter.Canvas.Font.Orientation<>0 then fCairoPrinter.Canvas.TextRect(R, nx, R.Bottom, Text, aStyle) else - fCairoPrinter.Canvas.TextRect(R, R.Left, ny, Text, aStyle); + begin + if TfrMemoView_(View).Justify and not TfrMemoView_(View).LastLine then + CanvasTextRectJustify(fCairoPrinter.Canvas, R, nx, R.Right, ny, Text, true) + else + fCairoPrinter.Canvas.TextRect(R, {R.Left} nx, ny, Text, aStyle); + end; // restore previous clipping //if OldClipping then diff --git a/components/lazreport/source/lr_class.pas b/components/lazreport/source/lr_class.pas index c4668627aa..5c6d2cacc8 100644 --- a/components/lazreport/source/lr_class.pas +++ b/components/lazreport/source/lr_class.pas @@ -22,6 +22,9 @@ uses LR_Intrp, LR_DSet, LR_DBSet, LR_DBRel, LR_Const, DbCtrls, LazUtf8Classes, LazLoggerBase; +const + lrMaxBandsInReport = 256; //temp fix. in future need remove this limit + const // object flags flStretched = $01; @@ -396,8 +399,6 @@ type end; - { TfrMemoView } - { TfrCustomMemoView } TfrCustomMemoView = class(TfrStretcheable) @@ -409,6 +410,7 @@ type FOnClick: TfrScriptStrings; FOnMouseEnter: TfrScriptStrings; FOnMouseLeave: TfrScriptStrings; + FParagraphGap: integer; function GetAlignment: TAlignment; function GetAngle: Byte; @@ -471,6 +473,7 @@ type HighlightStr: String; LineSpacing, CharacterSpacing: Integer; LastLine: boolean; // are we painting/exporting the last line? + FirstLine: boolean; constructor Create(AOwnerPage:TfrPage); override; destructor Destroy; override; @@ -502,6 +505,7 @@ type property OnClick : TfrScriptStrings read FOnClick write SetOnClick; property OnMouseEnter : TfrScriptStrings read FOnMouseEnter write SetOnMouseEnter; property OnMouseLeave : TfrScriptStrings read FOnMouseLeave write SetOnMouseLeave; + property ParagraphGap : integer read FParagraphGap write FParagraphGap; end; TfrMemoView = class(TfrCustomMemoView) @@ -527,6 +531,7 @@ type property Format; property FormatStr; property Restrictions; + property ParagraphGap; property OnClick; property OnMouseEnter; property OnMouseLeave; @@ -587,8 +592,13 @@ type { TfrSubReportView } TfrSubReportView = class(TfrView) + private + FSubPageIndex: Integer; //temp var for find page on load + FSubPage : TfrPage; + protected + procedure AfterLoad;override; public - SubPage: Integer; + //SubPage: Integer; constructor Create(AOwnerPage:TfrPage); override; procedure Assign(Source: TPersistent); override; procedure Draw(aCanvas: TCanvas); override; @@ -597,6 +607,7 @@ type procedure SaveToStream(Stream: TStream); override; procedure SaveToXML(XML: TLrXMLConfig; const Path: String); override; procedure DefinePopupMenu({%H-}Popup: TPopupMenu); override; + property SubPage : TfrPage read FSubPage write FSubPage; published property Restrictions; end; @@ -695,8 +706,7 @@ type Flags: Word; Next, Prev: TfrBand; SubIndex, MaxY: Integer; - EOFReached: Boolean; - EOFArr: Array[0..31] of Boolean; + EOFArr: Array[0..lrMaxBandsInReport - 1] of Boolean; Positions: Array[TfrDatasetPosition] of Integer; LastGroupValue: Variant; HeaderBand, FooterBand, LastBand: TfrBand; @@ -729,6 +739,7 @@ type procedure ResetLastValues; function getName: string; public + EOFReached: Boolean; MaxDY: Integer; Typ: TfrBandType; @@ -783,7 +794,6 @@ type TfrPage = class(TfrObject) private - Bands : Array[TfrBandType] of TfrBand; fColCount : Integer; fColGap : Integer; fColWidth : Integer; @@ -799,7 +809,6 @@ type CurColumn : Integer; LastStaticColumnY : Integer; XAdjust : Integer; - List : TFpList; LastBand : TfrBand; ColPos : Integer; CurPos : Integer; @@ -810,11 +819,15 @@ type procedure ClearRecList; procedure DrawPageFooters; function BandExists(b: TfrBand): Boolean; + function GetPageIndex: integer; procedure LoadFromStream(Stream: TStream); procedure SaveToStream(Stream: TStream); + procedure SetPageIndex(AValue: integer); procedure ShowBand(b: TfrBand); protected + List : TFpList; + Bands : Array[TfrBandType] of TfrBand; Mode : TfrPageMode; PlayFrom : Integer; function PlayRecList: Boolean; @@ -878,6 +891,7 @@ type property Script; property Height; property Width; + property PageIndex:integer read GetPageIndex write SetPageIndex; end; TFrPageClass = Class of TfrPage; @@ -949,8 +963,9 @@ type destructor Destroy; override; procedure Clear; - procedure Add(const aClassName : string='TfrPageReport'); + function Add(const aClassName : string='TfrPageReport'):TfrPage; procedure Delete(Index: Integer); + procedure Move(OldIndex, NewIndex: Integer); procedure LoadFromStream(Stream: TStream); procedure LoadFromXML(XML: TLrXMLConfig; const Path: String); procedure SaveToStream(Stream: TStream); @@ -1701,7 +1716,11 @@ begin frObj := CurReport.FindObject(FObjName); if Assigned(frObj) then + begin Result:=GetPropInfo(frObj, PropName); //Retreive property informations + if not Assigned(Result) then + IsCustomProp(PropName, PropIndex); + end; end; end; @@ -2077,7 +2096,7 @@ begin DebugLn('Error: ', e.message,'. Hyphenation support will be disabled'); end; end; - +{ procedure CanvasTextRectJustify(const Canvas:TCanvas; const ARect: TRect; X1, X2, Y: integer; const Text: string; Trimmed: boolean); @@ -2154,7 +2173,7 @@ begin SetLength(Arr, 0); end; - +} { TlrDetailReports } function TlrDetailReports.GetItems(AReportName: string): TlrDetailReport; @@ -3296,6 +3315,7 @@ begin FOnMouseEnter:=TfrScriptStrings.Create; FOnMouseLeave:=TfrScriptStrings.Create; FFindHighlight:=false; + FParagraphGap:=0; Typ := gtMemo; FFont := TFont.Create; @@ -3425,6 +3445,7 @@ begin FOnMouseLeave.Assign(TfrCustomMemoView(Source).FOnMouseLeave); FDetailReport:=TfrCustomMemoView(Source).FDetailReport; FCursor:=TfrCustomMemoView(Source).FCursor; + FParagraphGap:=TfrCustomMemoView(Source).FParagraphGap; end; end; @@ -3557,6 +3578,8 @@ var {$ENDIF} SMemo.Add(str + Chr(w div 256) + Chr(w mod 256)); Inc(size, size1); + //!! + maxWidth := dx - gapx - gapx; end; procedure WrapLine(const s: String); @@ -3704,13 +3727,14 @@ var begin size := y + gapy; size1 := -WCanvas.Font.Height + LineSpacing; - maxWidth := dx - gapx - gapx; +// maxWidth := dx - gapx - gapx; {$IFDEF DebugLR} DebugLn('OutMemo I: Size=%d Size1=%d MaxWidth=%d DIM:%d %d %d %d gapxy:%d %d', [Size,Size1,MaxWidth,x,y,dx,dy,gapx,gapy]); {$ENDIF} for i := 0 to Memo1.Count - 1 do begin + maxWidth := dx - gapx - gapx - FParagraphGap; if (Flags and flWordWrap) <> 0 then WrapLine(Memo1[i]) else @@ -3777,6 +3801,7 @@ var var i: Integer; curyf, thf, linespc: double; + FTmpFL:boolean; function OutLine(st: String): Boolean; var @@ -3803,8 +3828,12 @@ var SetLength(St, n - 2); if Length(St) > 0 then begin + FTmpFL:=false; if St[Length(St)] = #1 then - SetLength(St, Length(St) - 1) + begin + FTmpFL:=true; + SetLength(St, Length(St) - 1); + end else LastLine := false; end; @@ -3847,12 +3876,27 @@ var if not Exporting then begin if Justify and not LastLine then - CanvasTextRectJustify(Canvas, DR, x+gapx, x+dx-1-gapx, round(CurYf), St, true) + begin + if FirstLine then + CanvasTextRectJustify(Canvas, DR, x+gapx + FParagraphGap, x+dx-1-gapx, round(CurYf), St, true) + else + CanvasTextRectJustify(Canvas, DR, x+gapx, x+dx-1-gapx, round(CurYf), St, true) + end else - Canvas.TextRect(DR, CurX, round(curYf), St); + begin + if FirstLine then + Canvas.TextRect(DR, CurX + FParagraphGap, round(curYf), St) + else + Canvas.TextRect(DR, CurX, round(curYf), St); + end; end else - CurReport.InternalOnExportText(X, round(curYf), St, Self); + begin + if FirstLine then + CurReport.InternalOnExportText(X + FParagraphGap, round(curYf), St, Self) + else + CurReport.InternalOnExportText(X, round(curYf), St, Self); + end; Inc(CurStrNo); Result := False; @@ -3861,6 +3905,7 @@ var Result := True; curyf := curyf + thf; + FirstLine:=FTmpFL; end; begin {OutMemo} @@ -3868,7 +3913,8 @@ var begin if Layout=tlCenter then y:=y+(dy-VHeight) div 2 - else if Layout=tlBottom then + else + if Layout=tlBottom then y:=y+dy-VHeight; end; curyf := y + gapy; @@ -3885,6 +3931,9 @@ var [curyf, thf, Canvas.Font.Height, Canvas.Textheight('H'), dbgs(DR), Memo1.Count]); {$ENDIF} CurStrNo := 0; + + FirstLine:=true; + for i := 0 to Memo1.Count - 1 do if OutLine(Memo1[i]) then break; @@ -4356,6 +4405,7 @@ begin frReadMemo(Stream, FOnMouseEnter); frReadMemo(Stream, FOnMouseLeave); FDetailReport:=frReadString(Stream); + Stream.Read(FParagraphGap, SizeOf(FParagraphGap)); end; end; @@ -4393,6 +4443,7 @@ begin FOnMouseLeave.Text:= XML.GetValue(Path+'Data/OnMouseLeave/Value', ''); FDetailReport:= XML.GetValue(Path+'Data/DetailReport/Value', ''); + FParagraphGap:=XML.GetValue(Path+'Data/ParagraphGap/Value', 0); end; procedure TfrCustomMemoView.SaveToStream(Stream: TStream); @@ -4433,6 +4484,7 @@ begin frWriteMemo(Stream, FOnMouseEnter); frWriteMemo(Stream, FOnMouseLeave); frWriteString(Stream, FDetailReport); + Stream.Write(FParagraphGap, SizeOf(FParagraphGap)); end; end; @@ -4463,6 +4515,7 @@ begin XML.SetValue(Path+'Data/OnMouseLeave/Value', FOnMouseLeave.Text); XML.SetValue(Path+'Data/DetailReport/Value', FDetailReport); + XML.SetValue(Path+'Data/ParagraphGap/Value', FParagraphGap); end; procedure TfrCustomMemoView.GetBlob(b: TfrTField); @@ -5258,6 +5311,12 @@ begin Parent.Visible := Avalue; end; +procedure TfrSubReportView.AfterLoad; +begin + inherited AfterLoad; + FSubPage:= CurReport.Pages[FSubPageIndex]; +end; + {----------------------------------------------------------------------------} constructor TfrSubReportView.Create(AOwnerPage: TfrPage); begin @@ -5270,7 +5329,7 @@ procedure TfrSubReportView.Assign(Source: TPersistent); begin inherited Assign(Source); if Source is TfrSubReportView then - SubPage := TfrSubReportView(Source).SubPage; + FSubPage := TfrSubReportView(Source).FSubPage; end; procedure TfrSubReportView.Draw(aCanvas: TCanvas); @@ -5291,8 +5350,7 @@ begin Brush.Color := clWhite; Rectangle(x, y, x + dx + 1, y + dy + 1); Brush.Style := bsClear; - TextRect(DRect, x + 2, y + 2, sSubReportOnPage + ' ' + - IntToStr(SubPage + 1)); + TextRect(DRect, x + 2, y + 2, sSubReportOnPage + ' ' + IntToStr(SubPage.PageIndex + 1)); end; RestoreCoord; end; @@ -5305,13 +5363,13 @@ end; procedure TfrSubReportView.LoadFromStream(Stream: TStream); begin inherited LoadFromStream(Stream); - Stream.Read(SubPage, 4); + Stream.Read(FSubPageIndex, 4); end; procedure TfrSubReportView.LoadFromXML(XML: TLrXMLConfig; const Path: String); begin inherited LoadFromXML(XML, Path); - SubPage := XML.GetValue(Path+'SubPage/Value'{%H-}, 0); // todo chk + FSubPageIndex := XML.GetValue(Path+'SubPage/Value'{%H-}, 0); // todo chk end; procedure TfrSubReportView.SaveToStream(Stream: TStream); @@ -5323,7 +5381,8 @@ end; procedure TfrSubReportView.SaveToXML(XML: TLrXMLConfig; const Path: String); begin inherited SaveToXML(XML, Path); - XML.SetValue(Path+'SubPage/Value'{%H-}, SubPage); + FSubPageIndex:=FSubPage.PageIndex; + XML.SetValue(Path+'SubPage/Value'{%H-}, FSubPageIndex); end; {----------------------------------------------------------------------------} @@ -6220,7 +6279,7 @@ begin t :=TfrView(Objects[i]); if t is TfrSubReportView then begin - Page := CurReport.Pages[(t as TfrSubReportView).SubPage]; + Page := (t as TfrSubReportView).SubPage; Page.Mode := pmBuildList; Page.FormPage; Page.CurY := y + t.y; @@ -6247,7 +6306,7 @@ begin t :=TfrView(Objects[i]); if t is TfrSubReportView then begin - Page := CurReport.Pages[(t as TfrSubReportView).SubPage]; + Page := (t as TfrSubReportView).SubPage; Page.CurY := Parent.CurY; Page.CurBottomY := Parent.CurBottomY; end; @@ -6259,7 +6318,7 @@ begin t :=TfrView(Objects[i]); if (t is TfrSubReportView) and (not EOFArr[i - SubIndex]) then begin - Page := CurReport.Pages[(t as TfrSubReportView).SubPage]; + Page := (t as TfrSubReportView).SubPage; if Page.PlayRecList then EOFReached := False else @@ -6288,7 +6347,7 @@ begin t :=TfrView(Objects[i]); if t is TfrSubReportView then begin - Page := CurReport.Pages[(t as TfrSubReportView).SubPage]; + Page := (t as TfrSubReportView).SubPage; Page.ClearRecList; end; end; @@ -7311,7 +7370,7 @@ var bt, t: TfrView; Bnd, Bnd1: TfrBand; FirstBand, Flag: Boolean; - BArr: Array[0..31] of TfrBand; + BArr: Array[0..lrMaxBandsInReport - 1] of TfrBand; s: String; begin for i := 0 to Objects.Count - 1 do @@ -7337,7 +7396,7 @@ begin t.Parent := nil; frInterpretator.PrepareScript(t.Script, t.Script, SMemo); if t.Typ = gtSubReport then - CurReport.Pages[(t as TfrSubReportView).SubPage].Skip := True; + (t as TfrSubReportView).SubPage.Skip := True; end; Flag := False; for i := 0 to RTObjects.Count - 1 do // search for btCrossXXX bands @@ -7931,7 +7990,7 @@ begin RowStarted := result; end; -procedure TfrPage.DoAggregate(a: Array of TfrBandType); +procedure TfrPage.DoAggregate(a: array of TfrBandType); var i: Integer; procedure DoAggregate1(bt: TfrBandType); @@ -8328,6 +8387,11 @@ begin Result := b.Objects.Count > 0; end; +function TfrPage.GetPageIndex: integer; +begin + Result:=CurReport.Pages.FPages.IndexOf(Self); +end; + procedure TfrPage.AfterPrint; var i: Integer; @@ -8421,6 +8485,12 @@ begin end; end; +procedure TfrPage.SetPageIndex(AValue: integer); +begin + if (AValue>-1) and (AValue < CurReport.Pages.Count) and (GetPageIndex <> AValue) then + CurReport.Pages.Move(GetPageIndex, AValue); +end; + procedure TfrPage.SavetoXML(XML: TLrXMLConfig; const Path: String); begin Inherited SavetoXML(XML,Path); @@ -8472,24 +8542,25 @@ begin FPages.Clear; end; -procedure TfrPages.Add(const aClassName : string='TfrPageReport'); -Var Pg : TFrPage; - Rf : TFrPageClass; +function TfrPages.Add(const aClassName: string): TfrPage; +var + Rf : TFrPageClass; begin - Pg:=nil; - + Result := nil; + Rf:=TFrPageClass(GetClass(aClassName)); if Assigned(Rf) then begin - Pg:=Rf.CreatePage; + Result := Rf.CreatePage; - if Assigned(Pg) then + if Assigned(Result) then begin - Pg.CreateUniqueName; - FPages.Add(Pg); + Result.CreateUniqueName; + FPages.Add(Result); end; end - else showMessage(Format('Class %s not found',[aClassName])) + else + ShowMessage(Format('Class %s not found',[aClassName])) end; procedure TfrPages.Delete(Index: Integer); @@ -8498,6 +8569,11 @@ begin FPages.Delete(Index); end; +procedure TfrPages.Move(OldIndex, NewIndex: Integer); +begin + FPages.Move(OldIndex, NewIndex); +end; + procedure TfrPages.LoadFromStream(Stream: TStream); var b: Byte; diff --git a/components/lazreport/source/lr_crossarray.pas b/components/lazreport/source/lr_crossarray.pas index 8fbcc37abc..0495104d87 100644 --- a/components/lazreport/source/lr_crossarray.pas +++ b/components/lazreport/source/lr_crossarray.pas @@ -39,11 +39,32 @@ uses type + TVariantArray = array of Variant; + + { TVariantList } + + TVariantList = class + private + FItems:TVariantArray; + FCount: integer; + function GetItems(AIndex: integer): Variant; + procedure SetItems(AIndex: integer; AValue: Variant); + public + constructor Create; + destructor Destroy; override; + function Insert(AValue:Variant):integer; + function Find(AValue:Variant; out Index: Integer): Boolean; + function AsString(AIndex: Integer):string; + procedure Clear; + property Count:integer read FCount; + property Items[AIndex:integer]:Variant read GetItems write SetItems; + end; + { TExItem } TExItem = class private - FCelCol:string; + FCelCol:Variant; FValue:Variant; FDataset: TDataset; FBookmark:TBookMark; @@ -59,7 +80,7 @@ type TExRow = class(TFPList) private - FRow:string; + FRow:Variant; function GetCell(ACol: Variant): Variant; function GetCellData(ACol: Variant): TExItem; procedure SetCell(ACol: Variant; AValue: Variant); @@ -77,15 +98,15 @@ type FColCount: integer; FRowCount: integer; FRows:TFPList; - FColHeader:TStringList; - FRowHeader:TStringList; + FRowHeader:TVariantList; + FColHeader:TVariantList; function GetCell(ACol, ARow: variant): variant; function GetCellData(ACol, ARow : variant): TExItem; function GetColCount: integer; - function GetColHeader(ACol: integer): string; + function GetColHeader(ACol: integer): Variant; function GetRowCount: integer; - function GetRowHeader(ARow: integer): string; - procedure SetCell(ACol, ARow: variant; AValue: variant); + function GetRowHeader(ARow: integer): Variant; + procedure SetCell(ACol, ARow: variant; AValue: Variant); function Find(ARow:variant; out Index: Integer): Boolean; public constructor Create; @@ -95,8 +116,8 @@ type property CellData[ACol, ARow : variant]:TExItem read GetCellData; property ColCount:integer read GetColCount; property RowCount:integer read GetRowCount; - property ColHeader[ACol:integer]:string read GetColHeader; - property RowHeader[ARow:integer]:string read GetRowHeader; + property ColHeader[ACol:integer]:Variant read GetColHeader; + property RowHeader[ARow:integer]:Variant read GetRowHeader; end; implementation @@ -104,6 +125,110 @@ uses math, variants; { TExItem } +function CompareVariant(AVal1, AVAl2:Variant):integer; +begin + if AVal1>AVAl2 then + Result := 1 + else + if AVal1=0) and (AIndex < Count) then + Result:=FItems[AIndex] + else + raise Exception.CreateFmt('Index % out of bounds %d:%d', [AIndex, 0, Count-1]); +end; + +procedure TVariantList.SetItems(AIndex: integer; AValue: Variant); +begin + if (AIndex>=0) and (AIndex < Count) then + FItems[AIndex]:=AValue + else + raise Exception.CreateFmt('Index % out of bounds %d:%d', [AIndex, 0, Count-1]); +end; + +constructor TVariantList.Create; +begin + inherited Create; + SetLength(FItems, 10); + FCount:=0; +end; + +destructor TVariantList.Destroy; +begin + Clear; + SetLength(FItems, 0); + inherited Destroy; +end; + +function TVariantList.Insert(AValue: Variant): integer; +var + FIndex: Integer; + i: Integer; +begin + if Length(FItems) = FCount then + SetLength(FItems, FCount + 100); + + if not Find(AValue, FIndex) then + begin + for i:=FCount-1 downto FIndex do + FItems[i+1]:=FItems[i]; + FItems[FIndex]:=AValue; + Inc(FCount); + end; +end; + +function TVariantList.Find(AValue: Variant; out Index: Integer): Boolean; +var + L: Integer; + R: Integer; + I: Integer; + Dir: Integer; +begin + Result := false; + // Use binary search. + L := 0; + R := Count - 1; + while L<=R do + begin + I := (L+R) div 2; + Dir := CompareVariant(FItems[i], AValue); + if Dir < 0 then + L := I+1 + else + begin + R := I-1; + if Dir = 0 then + begin + Result := true; + L := I; + end; + end; + end; + Index := L; +end; + +function TVariantList.AsString(AIndex: Integer): string; +begin + Result:=VarToStr(GetItems(AIndex)); +end; + +procedure TVariantList.Clear; +var + i: Integer; +begin + for i:=0 to FCount-1 do + FItems[i]:=null; + FCount:=0; +end; + procedure TExItem.SaveBookmark(Ds: TDataset); begin if IsBookmarkValid then @@ -165,7 +290,6 @@ end; function TExRow.Find(ACol: Variant; out Index: Integer): Boolean; var I,L,R,Dir: Integer; - S1, S2:string; begin Result := false; // Use binary search. @@ -174,10 +298,7 @@ begin while L<=R do begin I := (L+R) div 2; -// Dir := CompareStr(TExItem(Items[i]).FCelCol, VarToStr(ACol)); - S1:=TExItem(Items[i]).FCelCol; - S2:=VarToStr(ACol); - Dir := CompareStr(S1, S2); + Dir := CompareVariant(TExItem(Items[i]).FCelCol,ACol); if Dir < 0 then L := I+1 else @@ -232,12 +353,12 @@ begin Result:=FColHeader.Count; end; -function TExVarArray.GetColHeader(ACol: integer): string; +function TExVarArray.GetColHeader(ACol: integer): Variant; begin if (ACol>=0) and (ACol=0) and (ARow FPage.PlayFrom then + FPage.NewPage;} + end; FPage.DoneReport; FPage.Free; diff --git a/components/lazreport/source/lr_desgn.lfm b/components/lazreport/source/lr_desgn.lfm index c502f85b7a..be4ed0c72a 100644 --- a/components/lazreport/source/lr_desgn.lfm +++ b/components/lazreport/source/lr_desgn.lfm @@ -23,12 +23,12 @@ object frDesignerForm: TfrDesignerForm OnResize = FormResize OnShow = FormShow ShowHint = True - LCLVersion = '1.3' + LCLVersion = '1.5' WindowState = wsMaximized object StatusBar1: TStatusBar Left = 0 - Height = 25 - Top = 382 + Height = 23 + Top = 384 Width = 695 Panels = < item @@ -120,42 +120,6 @@ object frDesignerForm: TfrDesignerForm Action = FileOpen Align = alLeft Flat = True - Glyph.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000298EDEFF2986DEFF298EDEFF298EDEFF298EDEFF298EDEFF298EDEFF298E - DEFF298EDEFF298EDEFF2986DEFF298EDEFF2986DEFF0000000000000000318E - DEFFDEF7FFFFA5DFF7FF9CDFF7FF94DFF7FF8CDFF7FF84D7F7FF7BD7F7FF7BD7 - F7FF73D7F7FF6BD7F7FF6BCFF7FFC6EFFFFF318EDEFF00000000000000003196 - DEFFEFFFFFFFA5EFFFFF94E7FFFF84E7F7FF73DFF7FF63DFF7FF52D7F7FF42D7 - F7FF39D7F7FF29CFF7FF21CFF7FFCEF7FFFF3196DEFF0000000000000000319E - DEFFF7FFFFFFB5EFFFFFA5EFFFFF94E7FFFF84E7F7FF73DFF7FF63DFF7FF52D7 - F7FF4AD7F7FF39D7F7FF31CFF7FFCEF7FFFF319EDEFF000000000000000031A6 - DEFFF7FFFFFFCEF7FFFFBDEFFFFFADEFFFFF9CEFFFFF8CE7F7FF7BE7F7FF6BDF - F7FF5ADFF7FF4AD7F7FF42D7F7FFD6F7FFFF319EDEFF000000000000000031A6 - DEFFFFFFFFFFFFFFFFFFF7FFFFFFF7FFFFFFF7FFFFFFDEF7FFFF94E7FFFF84E7 - F7FF73DFF7FF6BDFF7FF5ADFF7FFD6F7FFFF31A6DEFF000000000000000031AE - DEFFEFF7FFFF94D7EFFF8CCFEFFF73C7EFFFCEEFF7FFF7FFFFFFF7FFFFFFF7FF - FFFFF7FFFFFFEFFFFFFFEFFFFFFFFFFFFFFF31AEDEFF000000000000000031AE - DEFFF7FFFFFF94DFF7FF94DFF7FF84D7F7FF6BCFEFFF6BCFEFFF84D7EFFF84D7 - EFFF7BD7EFFF73CFEFFF73CFEFFFEFF7FFFF31AEDEFF000000000000000031AE - DEFFF7FFFFFF8CE7FFFF94DFF7FF9CE7F7FFADE7F7FFEFFFFFFFF7FFFFFFF7FF - FFFFF7FFFFFFEFFFFFFFEFFFFFFFFFFFFFFF31AEDEFF000000000000000031B6 - DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF7FFFF6BC7E7FF6BC7 - E7FF6BC7E7FF6BC7E7FF7BCFE7FF73CFE7FF00000000000000000000000031B6 - DEFF5AC7E7FF63C7E7FF63C7E7FF63C7E7FF5AC7E7FF39B6DEFF000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000 - } ShowCaption = False end object FileBtn3: TSpeedButton @@ -167,42 +131,6 @@ object frDesignerForm: TfrDesignerForm Action = FileSave Align = alLeft Flat = True - Glyph.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000BD6931FFBD69 - 31FFBD6931FFB56931FFB56931FFB56531FFB56531FFB56531FFAD6531FFAD61 - 31FFAD6131FFAD6131FFAD6131FFA56131FFA56131FFAD6131FFBD6931FFEFC7 - ADFFEFC7ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFCE9E7BFFC69E7BFFA56131FFBD6931FFEFCF - B5FFE7A67BFFFFFFF7FF63C78CFF63C78CFF63C78CFF63C78CFF63C78CFF63C7 - 8CFF63C78CFF63C78CFFFFFFF7FFCE8E63FFCE9E7BFFA56131FFBD6D39FFEFCF - B5FFE7A67BFFFFFFF7FFBDDFC6FFBDDFC6FFBDDFC6FFBDDFC6FFBDDFC6FFBDDF - C6FFBDDFC6FFBDDFC6FFFFFFF7FFCE966BFFCE9E84FFAD6131FFBD6939FFEFCF - BDFFE7A67BFFFFFFF7FF63C78CFF63C78CFF63C78CFF63C78CFF63C78CFF63C7 - 8CFF63C78CFF63C78CFFFFFFF7FFCE966BFFCEA684FFAD6131FFBD6931FFEFD7 - BDFFE7A67BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFD6966BFFD6A68CFFAD6131FFBD6931FFF7D7 - BDFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFDE9E73FFDE9E - 73FFDE9E73FFDE9E73FFDE9E73FFD69E73FFD6AE8CFFAD6131FFBD6931FFF7D7 - C6FFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFDEA6 - 73FFDE9E73FFDE9E73FFDE9E73FFDE9E73FFDEB694FFAD6531FFBD6931FFF7DF - C6FFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFE7A67BFFDEA6 - 73FFDE9E73FFDE9E73FFDE9E73FFDE9E73FFDEB69CFFB56531FFBD6931FFF7DF - C6FFE7A67BFFCE8E63FFCE8E63FFCE8E63FFCE966BFFCE966BFFCE966BFFCE8E - 63FFCE8E63FFCE8E63FFCE8E63FFDE9E73FFE7BE9CFFB56531FFBD6931FFF7DF - CEFFE7A67BFFFFEFE7FFFFEFE7FFFFEFE7FFFFF7EFFFFFFFF7FFFFF7F7FFFFEF - E7FFF7E7DEFFF7E7DEFFF7E7DEFFDEA673FFE7BEA5FFB56531FFBD6931FFF7DF - CEFFE7AE7BFFFFF7EFFFFFF7EFFFCE8E63FFFFF7EFFFFFFFF7FFFFFFFFFFFFF7 - EFFFFFEFDEFFF7E7DEFFF7E7DEFFE7A67BFFE7C7ADFFB56931FFBD6931FFF7DF - D6FFEFAE7BFFFFF7F7FFFFF7F7FFCE8E63FFFFF7EFFFFFF7EFFFFFFFF7FFFFFF - F7FFFFF7EFFFFFEFDEFFF7E7DEFFE7A67BFFEFD7C6FFB56931FFBD6931FFF7DF - D6FFEFAE84FFFFFFF7FFFFFFF7FFCE8E63FFFFF7EFFFFFF7EFFFFFF7F7FFFFFF - FFFFFFF7F7FFFFEFE7FFFFE7DEFFEFD7BDFFEFD7BDFFBD7139FFBD6931FFF7E7 - D6FFF7E7D6FFFFFFFFFFFFFFF7FFFFFFF7FFFFF7F7FFFFF7EFFFFFF7EFFFFFFF - F7FFFFFFF7FFFFF7EFFFFFEFDEFFEFD7BDFFCE8E5AFF0000000000000000BD69 - 31FFBD6931FFBD6931FFBD6931FFBD6931FFBD6931FFBD6931FFBD6931FFBD6D - 39FFBD6D39FFBD6D39FFBD6939FFBD7139FF0000000000000000 - } ShowCaption = False end object FileBtn4: TSpeedButton @@ -214,42 +142,6 @@ object frDesignerForm: TfrDesignerForm Action = FilePreview Align = alLeft Flat = True - Glyph.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000005A7DADFF5A86B5FF5A86B5FF5A86BDFF5A7D - B5FF5275ADFF0000000000000000000000000000000000000000000000000000 - 0000BDC7CEFF94AEC6FF84AEDEFF8CB6EFFF9CBEEFFFA5C7E7FFA5BEE7FFA5BE - E7FF94B6E7FF6B9EE7FF6386C6FF8496B5FF000000000000000000000000C6CF - DEFF9CBEE7FF9CC7EFFFBDD7EFFFD6DFEFFFE7E7EFFFEFEFEFFFEFEFEFFFEFEF - EFFFEFEFEFFFCED7EFFF94B6E7FF6396E7FF738EBDFF00000000D6DFE7FFADCF - EFFFC6D7EFFFE7E7EFFFEFEFEFFFEFDFD6FFE7BEA5FFDE9E73FFDE9E73FFDEB6 - 94FFEFD7CEFFF7F7F7FFE7EFEFFFB5CFEFFF6396E7FF849EC6FFC6D7E7FFD6E7 - EFFFF7F7F7FFF7F7F7FFF7E7DEFFE7B69CFFE7A67BFFE79E73FFDE9E6BFFDE96 - 63FFE7A67BFFEFDFCEFFF7F7F7FFF7F7F7FFCED7E7FF7BA6DEFFDEE7E7FFEFEF - EFFFF7F7F7FFFFFFFFFFF7D7BDFFEFB68CFFE7AE84FFE7A67BFFE7A673FFE79E - 73FFE7966BFFEFBE9CFFFFFFFFFFF7F7F7FFEFEFEFFF94B6DEFFB5CFDEFFDEE7 - EFFFF7F7F7FFFFFFFFFFF7C7ADFFEFBE9CFFEFB694FF181008FF181008FFE7A6 - 7BFFE79E73FFE7A67BFFFFFFFFFFF7F7F7FFD6DFEFFF6B8ECEFFD6DFE7FFADCF - E7FFBDCFD6FFFFFFFFFFF7CFB5FFEFBEA5FFEFBE9CFF181410FF181408FFEFAE - 84FFEFA67BFFEFAE84FFFFFFFFFFC6D7E7FF7BA6E7FF739ED6FFE7E7E7FFC6D7 - E7FFB5D7EFFF94AEBDFFD6CFC6FFEFC7ADFFEFC7A5FFEFBE9CFFEFB694FFEFB6 - 8CFFEFAE84FFEFC7B5FFA5BEDEFF84AEE7FF84B6F7FFC6D7E7FF00000000E7E7 - E7FFC6D7E7FFBDD7EFFFA5BED6FF8CA6B5FF9CA6ADFFB5AEA5FFB5A6A5FFB5A6 - 9CFF9C9EA5FF849EC6FF94BEEFFF94BEEFFFBDD7EFFF00000000000000000000 - 0000E7E7E7FFCEDFE7FFBDD7EFFFBDD7EFFFB5CFEFFFA5BEDEFF9CBED6FF9CBE - DEFFADCFF7FFA5C7EFFFA5C7EFFFD6DFEFFF0000000000000000000000000000 - 00000000000000000000DEDFE7FFC6D7E7FFBDD7E7FFBDCFE7FFB5CFE7FFB5CF - E7FFB5CFE7FFC6D7E7FF00000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000 - } ShowCaption = False end object CutB: TSpeedButton @@ -2324,7 +2216,7 @@ object frDesignerForm: TfrDesignerForm object E1: TEdit Tag = 6 Left = 4 - Height = 31 + Height = 33 Top = 1 Width = 31 TabOrder = 0 @@ -2389,21 +2281,21 @@ object frDesignerForm: TfrDesignerForm end object frDock2: TPanel Left = 0 - Height = 299 + Height = 301 Top = 83 Width = 27 Align = alLeft - ClientHeight = 299 + ClientHeight = 301 ClientWidth = 27 FullRepaint = False TabOrder = 1 object panForDlg: TPanel Left = 1 - Height = 297 + Height = 299 Top = 1 Width = 25 Align = alClient - ClientHeight = 297 + ClientHeight = 299 ClientWidth = 25 FullRepaint = False TabOrder = 1 @@ -2469,11 +2361,11 @@ object frDesignerForm: TfrDesignerForm end object Panel4: TPanel Left = 1 - Height = 297 + Height = 299 Top = 1 Width = 25 Align = alClient - ClientHeight = 297 + ClientHeight = 299 ClientWidth = 25 FullRepaint = False TabOrder = 0 @@ -2772,7 +2664,7 @@ object frDesignerForm: TfrDesignerForm end object Tab1: TTabControl Left = 27 - Height = 299 + Height = 301 Top = 83 Width = 641 TabStop = False @@ -2786,24 +2678,24 @@ object frDesignerForm: TfrDesignerForm TabOrder = 2 object panTab: TPanel Left = 2 - Height = 267 - Top = 30 + Height = 266 + Top = 33 Width = 637 Align = alClient BevelOuter = bvNone Caption = 'panTab' - ClientHeight = 267 + ClientHeight = 266 ClientWidth = 637 TabOrder = 1 object ScrollBox1: TScrollBox Left = 0 - Height = 267 + Height = 266 Top = 0 Width = 637 HorzScrollBar.Page = 488 VertScrollBar.Page = 174 Align = alClient - ClientHeight = 265 + ClientHeight = 264 ClientWidth = 635 Color = clGray ParentColor = False @@ -4066,12 +3958,12 @@ object frDesignerForm: TfrDesignerForm end object frDock4: TPanel Left = 668 - Height = 299 + Height = 301 Top = 83 Width = 27 Align = alRight Anchors = [akTop, akRight] - ClientHeight = 299 + ClientHeight = 301 ClientWidth = 27 FullRepaint = False TabOrder = 3 diff --git a/components/lazreport/source/lr_desgn.pas b/components/lazreport/source/lr_desgn.pas index 3b580c922e..18b8582645 100644 --- a/components/lazreport/source/lr_desgn.pas +++ b/components/lazreport/source/lr_desgn.pas @@ -43,6 +43,7 @@ type SaveAs: Boolean; var Saved: Boolean) of object; TfrDesignerForm = class; + TlrTabEditControl = class(TCustomTabControl); { TfrDesigner } @@ -623,6 +624,14 @@ type procedure DuplicateView(View: TfrView; Data: PtrInt); procedure ResetDuplicateCount; function lrDesignAcceptDrag(const Source: TObject): TControl; + private + FTabMouseDown:boolean; + FTabsPage:TlrTabEditControl; + procedure TabsEditDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); + procedure TabsEditDragDrop(Sender, Source: TObject; X, Y: Integer); + procedure TabsEditMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure TabsEditMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + procedure TabsEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); protected procedure SetModified(AValue: Boolean);override; function IniFileName:string; @@ -1777,11 +1786,8 @@ var procedure CreateSubReport; begin -{ Objects.Add(TfrSubReportView.Create(FDesigner.Page)); - t := TfrView(Objects.Last);} t:=TfrSubReportView.Create(FDesigner.Page); - (t as TfrSubReportView).SubPage := CurReport.Pages.Count; - CurReport.Pages.Add; + (t as TfrSubReportView).SubPage := CurReport.Pages.Add; end; begin @@ -2907,6 +2913,14 @@ begin StatusBar1.OnDrawPanel := @StatusBar1Drawpanel; Panel7.Visible := false; {$endif} + + FTabsPage:=TlrTabEditControl((Tab1.Tabs as TTabControlNoteBookStrings).NoteBook); + FTabsPage.DragMode:=dmManual; + FTabsPage.OnDragOver:=@TabsEditDragOver; + FTabsPage.OnDragDrop:=@TabsEditDragDrop; + FTabsPage.OnMouseDown:=@TabsEditMouseDown; + FTabsPage.OnMouseMove:=@TabsEditMouseMove; + FTabsPage.OnMouseUp:=@TabsEditMouseUp; end; destructor TfrDesignerForm.Destroy; @@ -3759,30 +3773,28 @@ begin end; procedure TfrDesignerForm.RemovePage(n: Integer); - procedure AdjustSubReports; - var - i, j: Integer; - t: TfrView; + +procedure AdjustSubReports(APage:TfrPage); +var + i, j: Integer; + t: TfrView; +begin + for i := 0 to CurReport.Pages.Count - 1 do begin - with CurReport do - for i := 0 to Pages.Count - 1 do + j := 0; + while j < CurReport.Pages[i].Objects.Count do + begin + t := TfrView(CurReport.Pages[i].Objects[j]); + if (T is TfrSubReportView) and (TfrSubReportView(t).SubPage = APage) then begin - j := 0; - while j < Pages[i].Objects.Count do - begin - t := TfrView(Pages[i].Objects[j]); - if t.Typ = gtSubReport then - if TfrSubReportView(t).SubPage = n then - begin - Pages[i].Delete(j); - Dec(j); - end - else if TfrSubReportView(t).SubPage > n then - Dec(TfrSubReportView(t).SubPage); - Inc(j); - end; + CurReport.Pages[i].Delete(j); + Dec(j); end; + Inc(j); + end; end; +end; + begin fInBuildPage:=True; try @@ -3794,10 +3806,10 @@ begin Pages[n].Clear else begin + AdjustSubReports(Pages[n]); CurReport.Pages.Delete(n); Tab1.Tabs.Delete(n); Tab1.TabIndex := 0; - AdjustSubReports; CurPage := 0; end; end; @@ -3813,37 +3825,35 @@ var i: Integer; s: String; - function IsSubreport(PageN: Integer): Boolean; - var - i, j: Integer; - t: TfrView; - begin - Result := False; - with CurReport do - for i := 0 to Pages.Count - 1 do - for j := 0 to Pages[i].Objects.Count - 1 do - begin - t := TfrView(Pages[i].Objects[j]); - if t.Typ = gtSubReport then - if TfrSubReportView(t).SubPage = PageN then - begin - s := t.Name; - Result := True; - Exit; - end; - end; - end; +function IsSubreport(PageN: Integer): Boolean; +var + i, j: Integer; + t: TfrView; +begin + Result := False; + for i := 0 to CurReport.Pages.Count - 1 do + for j := 0 to CurReport.Pages[i].Objects.Count - 1 do + begin + t := TfrView(CurReport.Pages[i].Objects[j]); + if (T is TfrSubReportView) and (TfrSubReportView(t).SubPage = CurReport.Pages[PageN]) then + begin + s := t.Name; + Result := True; + Exit; + end; + end; +end; begin - if Tab1.Tabs.Count = CurReport.Pages.Count then + if Tab1.Tabs.Count = CurReport.Pages.Count then + begin + for i := 0 to Tab1.Tabs.Count - 1 do begin - for i := 0 to Tab1.Tabs.Count - 1 do - begin - if not IsSubreport(i) then - s := sPg + IntToStr(i + 1); - if Tab1.Tabs[i] <> s then - Tab1.Tabs[i] := s; - end; + if not IsSubreport(i) then + s := sPg + IntToStr(i + 1); + if Tab1.Tabs[i] <> s then + Tab1.Tabs[i] := s; + end; end else begin @@ -4465,6 +4475,52 @@ end; {$endif} +procedure TfrDesignerForm.TabsEditDragOver(Sender, Source: TObject; X, + Y: Integer; State: TDragState; var Accept: Boolean); +begin + Accept:=(Source = FTabsPage) and (FTabsPage.IndexOfTabAt(X, Y) <> Tab1.TabIndex); +end; + +procedure TfrDesignerForm.TabsEditDragDrop(Sender, Source: TObject; X, + Y: Integer); +var + NewIndex: Integer; +begin + NewIndex:=FTabsPage.IndexOfTabAt(X, Y); + //ShowMessageFmt('New index = %d', [NewIndex]); + if (NewIndex>-1) and (NewIndex < CurReport.Pages.Count) then + begin + CurReport.Pages.Move(CurPage, NewIndex); + Tab1.Tabs.Move(CurPage, NewIndex); + SetPageTitles; + + ClearUndoBuffer; + ClearRedoBuffer; + Modified := True; + Tab1.TabIndex:=NewIndex; + RedrawPage; + end; +end; + +procedure TfrDesignerForm.TabsEditMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + FTabMouseDown:=true; +end; + +procedure TfrDesignerForm.TabsEditMouseMove(Sender: TObject; + Shift: TShiftState; X, Y: Integer); +begin + if FTabMouseDown then + FTabsPage.BeginDrag(false); +end; + +procedure TfrDesignerForm.TabsEditMouseUp(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + FTabMouseDown:=false; +end; + procedure TfrDesignerForm.SetModified(AValue: Boolean); begin inherited SetModified(AValue); @@ -5290,7 +5346,7 @@ begin end else if t.Typ = gtSubReport then - CurPage := (t as TfrSubReportView).SubPage + CurPage := (t as TfrSubReportView).SubPage.PageIndex else if t.Typ = gtAddIn then begin @@ -6271,7 +6327,7 @@ var end; begin - Ini:=TIniFile.Create(IniFileName); + Ini:=TIniFile.Create(UTF8ToSys(IniFileName)); Ini.WriteString('frEditorForm', 'ScriptFontName', edtScriptFontName); Ini.WriteInteger('frEditorForm', 'ScriptFontSize', edtScriptFontSize); @@ -6318,7 +6374,7 @@ var begin if FileExistsUTF8(IniFileName) then begin - Ini:=TIniFile.Create(IniFileName); + Ini:=TIniFile.Create(UTF8ToSys(IniFileName)); edtScriptFontName:=Ini.ReadString('frEditorForm', 'ScriptFontName', edtScriptFontName); edtScriptFontSize:=Ini.ReadInteger('frEditorForm', 'ScriptFontSize', edtScriptFontSize); GridSize := Ini.ReadInteger('frEditorForm', rsGridSize, 4); @@ -7634,6 +7690,35 @@ type procedure Edit; override; end; + { TTfrBandViewChildProperty } + + TTfrBandViewChildProperty = class(TStringProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + end; + +{ TTfrBandViewChildProperty } + +function TTfrBandViewChildProperty.GetAttributes: TPropertyAttributes; +begin + Result:=inherited GetAttributes + [paValueList, paSortList]; +end; + +procedure TTfrBandViewChildProperty.GetValues(Proc: TGetStrProc); +var + I: Integer; +begin + if Assigned(frDesigner) and Assigned(frDesigner.Page) then + begin + for i:=0 to frDesigner.Page.Objects.Count-1 do + if TObject(frDesigner.Page.Objects[i]) is TfrBandView then + if (TfrBandView(frDesigner.Page.Objects[i]).BandType = btChild) and + (TfrBandView(GetComponent(0)) <> TfrBandView(frDesigner.Page.Objects[i])) then + Proc(TfrBandView(frDesigner.Page.Objects[i]).Name); + end; +end; + { TfrPictureViewDataFieldProperty } function TfrViewDataFieldProperty.GetAttributes: TPropertyAttributes; @@ -8092,6 +8177,8 @@ initialization RegisterPropertyEditor(TypeInfo(String), TfrCustomMemoView, 'DetailReport', TfrCustomMemoViewDetailReportProperty); RegisterPropertyEditor(TypeInfo(String), TfrView, 'DataField', TfrViewDataFieldProperty); + RegisterPropertyEditor(TypeInfo(String), TfrBandView, 'Child', TTfrBandViewChildProperty); + FlrInternalTools:=TlrInternalTools.Create; finalization If Assigned(frDesigner) then diff --git a/components/lazreport/source/lr_utils.pas b/components/lazreport/source/lr_utils.pas index 4ad4694110..ac862cb4c1 100644 --- a/components/lazreport/source/lr_utils.pas +++ b/components/lazreport/source/lr_utils.pas @@ -20,7 +20,7 @@ uses {$IFDEF WIN32} Windows, {$ENDIF} - LCLType, LCLIntf, LazUTF8, LConvEncoding; + LCLType, LCLIntf, LConvEncoding; type TUTF8Item=packed record @@ -70,6 +70,10 @@ function lrExpandVariables(const S:string):string; procedure lrNormalizeLocaleFloats(DisableLocale: boolean); function lrConfigFolderName(ACreatePath: boolean): string; +procedure CanvasTextRectJustify(const Canvas:TCanvas; + const ARect: TRect; X1, X2, Y: integer; const Text: string; + Trimmed: boolean); + // utf8 tools function UTF8Desc(S:string; var Desc: string): Integer; deprecated; function UTF8Char(S:string; index:Integer; Desc:string): TUTF8Char; deprecated; @@ -83,7 +87,7 @@ function UTF8CountWords(const str:string; out WordCount,SpcCount,SpcSize:Integer implementation uses LR_Class, LR_Const, LR_Pars, FileUtil, LazUtilsStrConsts, LR_DSet, - LR_DBComponent, strutils; + LR_DBComponent, strutils, LazUTF8; var PreviousFormatSettings: TFormatSettings; @@ -1086,4 +1090,81 @@ begin end; end; +procedure CanvasTextRectJustify(const Canvas:TCanvas; + const ARect: TRect; X1, X2, Y: integer; const Text: string; + Trimmed: boolean); +var + WordCount,SpcCount,SpcSize:Integer; + Arr: TArrUTF8Item; + PxSpc,RxSpc,Extra: Integer; + i: Integer; + Cini,Cend: Integer; + SpaceWidth, AvailWidth: Integer; + s:string; +begin + + AvailWidth := (X2-X1); + // count words + Arr := UTF8CountWords(Text, WordCount, SpcCount, SpcSize); + + // handle trimmed text + s := Text; + if (SpcCount>0) then + begin + Cini := 0; + CEnd := Length(Arr)-1; + if Trimmed then + begin + s := UTF8Trim(Text, [u8tKeepStart]); + if Arr[CEnd].Space then + begin + Dec(CEnd); + Dec(SpcCount); + end; + end; + AvailWidth := AvailWidth - Canvas.TextWidth(s); + end; + + // check if long way is needed + if (SpcCount>0) and (AvailWidth>0) then + begin + + SpaceWidth := Canvas.TextWidth(' '); + PxSpc := AvailWidth div SpcCount; + RxSpc := AvailWidth mod SpcCount; + if PxSPC=0 then + begin + PxSPC := 1; + RxSpc := 0; + end; + + for i:=CIni to CEnd do + if Arr[i].Space then + begin + X1 := X1 + Arr[i].Count * SpaceWidth; + if AvailWidth>0 then + begin + Extra := PxSpc; + if RxSpc>0 then + begin + Inc(Extra); + Dec(RxSpc); + end; + X1 := X1 + Extra; + Dec(AvailWidth, Extra); + end; + end + else + begin + s := Copy(Text, Arr[i].Index, Arr[i].Count); + Canvas.TextRect(ARect, X1, Y, s); + X1 := X1 + Canvas.TextWidth(s); + end; + + end else + Canvas.TextRect(ARect, X1, Y, s); + + SetLength(Arr, 0); +end; + end.