|
@@ -608,11 +608,17 @@ type
|
|
FRTLayout: TFPReportLayout;
|
|
FRTLayout: TFPReportLayout;
|
|
FOnBeforePrint: TFPReportBeforePrintEvent;
|
|
FOnBeforePrint: TFPReportBeforePrintEvent;
|
|
FStretchMode: TFPReportStretchMode;
|
|
FStretchMode: TFPReportStretchMode;
|
|
|
|
+ FVisibleExpr: String;
|
|
function GetReport: TFPCustomReport;
|
|
function GetReport: TFPCustomReport;
|
|
procedure SetFrame(const AValue: TFPReportFrame);
|
|
procedure SetFrame(const AValue: TFPReportFrame);
|
|
procedure SetLayout(const AValue: TFPReportLayout);
|
|
procedure SetLayout(const AValue: TFPReportLayout);
|
|
procedure SetVisible(const AValue: boolean);
|
|
procedure SetVisible(const AValue: boolean);
|
|
|
|
+ procedure SetVisibleExpr(AValue: String);
|
|
protected
|
|
protected
|
|
|
|
+ function GetDateTimeFormat: String; virtual;
|
|
|
|
+ function ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString; virtual;
|
|
|
|
+ function GetReportBand: TFPReportCustomBand; virtual;
|
|
|
|
+ function GetReportPage: TFPReportCustomPage; virtual;
|
|
Procedure SaveDataToNames; virtual;
|
|
Procedure SaveDataToNames; virtual;
|
|
Procedure RestoreDataFromNames; virtual;
|
|
Procedure RestoreDataFromNames; virtual;
|
|
function CreateFrame: TFPReportFrame; virtual;
|
|
function CreateFrame: TFPReportFrame; virtual;
|
|
@@ -627,6 +633,8 @@ type
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
{ triggers OnBeforePrint event }
|
|
{ triggers OnBeforePrint event }
|
|
procedure BeforePrint; virtual;
|
|
procedure BeforePrint; virtual;
|
|
|
|
+ function EvaluateExpression(const AExpr: String; out Res: TFPExpressionResult): Boolean;
|
|
|
|
+ function EvaluateExpressionAsText(const AExpr: String): String;
|
|
{ this is run against the runtime (RT) version of this element, and before BeforePrint is called. }
|
|
{ this is run against the runtime (RT) version of this element, and before BeforePrint is called. }
|
|
procedure RecalcLayout; virtual; abstract;
|
|
procedure RecalcLayout; virtual; abstract;
|
|
property StretchMode: TFPReportStretchMode read FStretchMode write FStretchMode default smDontStretch;
|
|
property StretchMode: TFPReportStretchMode read FStretchMode write FStretchMode default smDontStretch;
|
|
@@ -641,6 +649,7 @@ type
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure BeginUpdate;
|
|
procedure BeginUpdate;
|
|
procedure EndUpdate;
|
|
procedure EndUpdate;
|
|
|
|
+ function EvaluateVisibility : boolean;
|
|
property Parent: TFPReportElement read FParent write SetParent;
|
|
property Parent: TFPReportElement read FParent write SetParent;
|
|
Property Report : TFPCustomReport read GetReport;
|
|
Property Report : TFPCustomReport read GetReport;
|
|
{ Runtime Layout - populated when layouting of report is calculated. }
|
|
{ Runtime Layout - populated when layouting of report is calculated. }
|
|
@@ -649,6 +658,9 @@ type
|
|
property Layout: TFPReportLayout read FLayout write SetLayout;
|
|
property Layout: TFPReportLayout read FLayout write SetLayout;
|
|
property Frame: TFPReportFrame read FFrame write SetFrame;
|
|
property Frame: TFPReportFrame read FFrame write SetFrame;
|
|
property Visible: boolean read FVisible write SetVisible;
|
|
property Visible: boolean read FVisible write SetVisible;
|
|
|
|
+ property VisibleExpr: String read FVisibleExpr write SetVisibleExpr;
|
|
|
|
+ property Page: TFPReportCustomPage read GetReportPage;
|
|
|
|
+ property Band: TFPReportCustomBand read GetReportBand;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -761,6 +773,10 @@ type
|
|
procedure SetColumnLayout(AValue: TFPReportColumnLayout);
|
|
procedure SetColumnLayout(AValue: TFPReportColumnLayout);
|
|
procedure SetColumnCount(AValue: Byte);
|
|
procedure SetColumnCount(AValue: Byte);
|
|
procedure SetColumnGap(AValue: TFPReportUnits);
|
|
procedure SetColumnGap(AValue: TFPReportUnits);
|
|
|
|
+ function GetReportPage: TFPReportCustomPage; override;
|
|
|
|
+ function GetReportBand: TFPReportCustomBand; override;
|
|
|
|
+ property Band;
|
|
|
|
+ property Page;
|
|
protected
|
|
protected
|
|
Procedure SaveDataToNames; override;
|
|
Procedure SaveDataToNames; override;
|
|
Procedure RestoreDataFromNames; override;
|
|
Procedure RestoreDataFromNames; override;
|
|
@@ -817,7 +833,7 @@ type
|
|
FVisibleOnPage: TFPReportVisibleOnPage;
|
|
FVisibleOnPage: TFPReportVisibleOnPage;
|
|
FFont: TFPReportFont;
|
|
FFont: TFPReportFont;
|
|
function GetFont: TFPReportFont;
|
|
function GetFont: TFPReportFont;
|
|
- function GetReportPage: TFPReportCustomPage;
|
|
|
|
|
|
+ function GetReportPage: TFPReportCustomPage; override;
|
|
function IsStringValueZero(const AValue: string): boolean;
|
|
function IsStringValueZero(const AValue: string): boolean;
|
|
procedure SetChildBand(AValue: TFPReportChildBand);
|
|
procedure SetChildBand(AValue: TFPReportChildBand);
|
|
procedure ApplyStretchMode;
|
|
procedure ApplyStretchMode;
|
|
@@ -828,7 +844,6 @@ type
|
|
function GetReportBandName: string; virtual;
|
|
function GetReportBandName: string; virtual;
|
|
function GetData: TFPReportData; virtual;
|
|
function GetData: TFPReportData; virtual;
|
|
procedure SetDataFromName(AName : String); virtual;
|
|
procedure SetDataFromName(AName : String); virtual;
|
|
- function ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString; virtual;
|
|
|
|
procedure SetParent(const AValue: TFPReportElement); override;
|
|
procedure SetParent(const AValue: TFPReportElement); override;
|
|
procedure CreateRTLayout; override;
|
|
procedure CreateRTLayout; override;
|
|
procedure PrepareObjects; override;
|
|
procedure PrepareObjects; override;
|
|
@@ -847,7 +862,6 @@ type
|
|
Class Function ReportBandType : TFPReportBandType; virtual;
|
|
Class Function ReportBandType : TFPReportBandType; virtual;
|
|
procedure WriteElement(AWriter: TFPReportStreamer; AOriginal: TFPReportElement = nil); override;
|
|
procedure WriteElement(AWriter: TFPReportStreamer; AOriginal: TFPReportElement = nil); override;
|
|
procedure ReadElement(AReader: TFPReportStreamer); override;
|
|
procedure ReadElement(AReader: TFPReportStreamer); override;
|
|
- property Page: TFPReportCustomPage read GetReportPage;
|
|
|
|
end;
|
|
end;
|
|
TFPReportCustomBandClass = Class of TFPReportCustomBand;
|
|
TFPReportCustomBandClass = Class of TFPReportCustomBand;
|
|
|
|
|
|
@@ -1006,8 +1020,11 @@ type
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ { TFPReportCustomGroupHeaderBand }
|
|
|
|
+
|
|
TFPReportCustomGroupHeaderBand = class(TFPReportCustomBandWithData)
|
|
TFPReportCustomGroupHeaderBand = class(TFPReportCustomBandWithData)
|
|
private
|
|
private
|
|
|
|
+ FConditionValue: string;
|
|
FGroupHeader: TFPReportCustomGroupHeaderBand;
|
|
FGroupHeader: TFPReportCustomGroupHeaderBand;
|
|
FChildGroupHeader: TFPReportCustomGroupHeaderBand;
|
|
FChildGroupHeader: TFPReportCustomGroupHeaderBand;
|
|
FGroupFooter: TFPReportCustomGroupFooterBand;
|
|
FGroupFooter: TFPReportCustomGroupFooterBand;
|
|
@@ -1015,6 +1032,7 @@ type
|
|
procedure SetGroupHeader(AValue: TFPReportCustomGroupHeaderBand);
|
|
procedure SetGroupHeader(AValue: TFPReportCustomGroupHeaderBand);
|
|
protected
|
|
protected
|
|
function GetReportBandName: string; override;
|
|
function GetReportBandName: string; override;
|
|
|
|
+ Procedure CalcGroupConditionValue;
|
|
procedure DoWriteLocalProperties(AWriter: TFPReportStreamer; AOriginal: TFPReportElement = nil); override;
|
|
procedure DoWriteLocalProperties(AWriter: TFPReportStreamer; AOriginal: TFPReportElement = nil); override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
{ This property defines the hierarchy of nested groups. For the top most group, this property will be nil. }
|
|
{ This property defines the hierarchy of nested groups. For the top most group, this property will be nil. }
|
|
@@ -1023,6 +1041,8 @@ type
|
|
property GroupFooter: TFPReportCustomGroupFooterBand read FGroupFooter;
|
|
property GroupFooter: TFPReportCustomGroupFooterBand read FGroupFooter;
|
|
{ can be a field name or an expression }
|
|
{ can be a field name or an expression }
|
|
property GroupCondition: string read FCondition write FCondition;
|
|
property GroupCondition: string read FCondition write FCondition;
|
|
|
|
+ { Run-time calculated value }
|
|
|
|
+ property GroupConditionValue : string read FConditionValue write FConditionValue;
|
|
public
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
constructor Create(AOwner: TComponent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
@@ -3782,7 +3802,7 @@ var
|
|
lBand: TFPReportCustomBand;
|
|
lBand: TFPReportCustomBand;
|
|
lMemo: TFPReportCustomMemo;
|
|
lMemo: TFPReportCustomMemo;
|
|
begin
|
|
begin
|
|
- if not self.Visible then
|
|
|
|
|
|
+ if not self.EvaluateVisibility then
|
|
Exit;
|
|
Exit;
|
|
if Parent is TFPReportCustomBand then
|
|
if Parent is TFPReportCustomBand then
|
|
begin
|
|
begin
|
|
@@ -4002,7 +4022,7 @@ var
|
|
lBand: TFPReportCustomBand;
|
|
lBand: TFPReportCustomBand;
|
|
lShape: TFPReportCustomShape;
|
|
lShape: TFPReportCustomShape;
|
|
begin
|
|
begin
|
|
- if not self.Visible then
|
|
|
|
|
|
+ if not self.EvaluateVisibility then
|
|
Exit;
|
|
Exit;
|
|
if Parent is TFPReportCustomBand then
|
|
if Parent is TFPReportCustomBand then
|
|
begin
|
|
begin
|
|
@@ -4171,7 +4191,7 @@ var
|
|
lBand: TFPReportCustomBand;
|
|
lBand: TFPReportCustomBand;
|
|
lImage: TFPReportCustomImage;
|
|
lImage: TFPReportCustomImage;
|
|
begin
|
|
begin
|
|
- if not self.Visible then
|
|
|
|
|
|
+ if not self.EvaluateVisibility then
|
|
Exit;
|
|
Exit;
|
|
if Parent is TFPReportCustomBand then
|
|
if Parent is TFPReportCustomBand then
|
|
begin
|
|
begin
|
|
@@ -4351,7 +4371,7 @@ var
|
|
lBand: TFPReportCustomBand;
|
|
lBand: TFPReportCustomBand;
|
|
lCB: TFPReportCustomCheckbox;
|
|
lCB: TFPReportCustomCheckbox;
|
|
begin
|
|
begin
|
|
- if not self.Visible then
|
|
|
|
|
|
+ if not self.EvaluateVisibility then
|
|
Exit;
|
|
Exit;
|
|
if Parent is TFPReportCustomBand then
|
|
if Parent is TFPReportCustomBand then
|
|
begin
|
|
begin
|
|
@@ -4613,6 +4633,11 @@ begin
|
|
Result := 'GroupHeaderBand';
|
|
Result := 'GroupHeaderBand';
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFPReportCustomGroupHeaderBand.CalcGroupConditionValue;
|
|
|
|
+begin
|
|
|
|
+ GroupConditionValue:=Evaluate;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFPReportCustomGroupHeaderBand.DoWriteLocalProperties(AWriter: TFPReportStreamer; AOriginal: TFPReportElement);
|
|
procedure TFPReportCustomGroupHeaderBand.DoWriteLocalProperties(AWriter: TFPReportStreamer; AOriginal: TFPReportElement);
|
|
begin
|
|
begin
|
|
inherited DoWriteLocalProperties(AWriter, AOriginal);
|
|
inherited DoWriteLocalProperties(AWriter, AOriginal);
|
|
@@ -4648,7 +4673,7 @@ end;
|
|
|
|
|
|
function TFPReportCustomGroupHeaderBand.Evaluate: string;
|
|
function TFPReportCustomGroupHeaderBand.Evaluate: string;
|
|
begin
|
|
begin
|
|
- Result := ExpandMacro(GroupCondition, True);
|
|
|
|
|
|
+ Result := EvaluateExpressionAsText(GroupCondition);
|
|
end;
|
|
end;
|
|
|
|
|
|
class function TFPReportCustomGroupHeaderBand.ReportBandType: TFPReportBandType;
|
|
class function TFPReportCustomGroupHeaderBand.ReportBandType: TFPReportBandType;
|
|
@@ -5190,6 +5215,34 @@ begin
|
|
Result:=TFPReportCustomPage(el).Report;
|
|
Result:=TFPReportCustomPage(el).Report;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFPReportElement.GetReportBand: TFPReportCustomBand;
|
|
|
|
+begin
|
|
|
|
+ if (Self is TFPReportCustomBand) then
|
|
|
|
+ Result := Self as TFPReportCustomBand
|
|
|
|
+ else if (Parent is TFPReportCustomBand) then
|
|
|
|
+ Result := Parent as TFPReportCustomBand
|
|
|
|
+ else
|
|
|
|
+ Result := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TFPReportElement.EvaluateVisibility: boolean;
|
|
|
|
+
|
|
|
|
+var
|
|
|
|
+ Res : TFPExpressionResult;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result := Visible;
|
|
|
|
+ if Result and (FVisibleExpr <> '') then
|
|
|
|
+ begin
|
|
|
|
+ if EvaluateExpression(FVisibleExpr,res) then
|
|
|
|
+ if (res.ResultType=rtBoolean) then // We may need to change this.
|
|
|
|
+ Result:= Res.ResBoolean;
|
|
|
|
+ {$ifdef gdebug}
|
|
|
|
+ writeln('TFPReportElement.EvaluateVisibility: VisibleExpr=' , FVisibleExpr , '=' , Res.ResultType,' : ',Res.ResBoolean);
|
|
|
|
+ {$endif}
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFPReportElement.SetLayout(const AValue: TFPReportLayout);
|
|
procedure TFPReportElement.SetLayout(const AValue: TFPReportLayout);
|
|
begin
|
|
begin
|
|
if FLayout = AValue then
|
|
if FLayout = AValue then
|
|
@@ -5227,6 +5280,110 @@ begin
|
|
Changed;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFPReportElement.SetVisibleExpr(AValue: String);
|
|
|
|
+begin
|
|
|
|
+ if FVisibleExpr=AValue then Exit;
|
|
|
|
+ FVisibleExpr:=AValue;
|
|
|
|
+ Changed;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TFPReportElement.ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString;
|
|
|
|
+
|
|
|
|
+var
|
|
|
|
+ pstart: integer;
|
|
|
|
+ pend: integer;
|
|
|
|
+ len: integer;
|
|
|
|
+ m: string; // macro
|
|
|
|
+ mv: string; // macro value
|
|
|
|
+ r: string;
|
|
|
|
+ lFoundMacroInMacro: boolean;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ r := s;
|
|
|
|
+ lFoundMacroInMacro := False;
|
|
|
|
+ pstart := Pos('[', r);
|
|
|
|
+ while (pstart > 0) or lFoundMacroInMacro do
|
|
|
|
+ begin
|
|
|
|
+ if lFoundMacroInMacro then
|
|
|
|
+ begin
|
|
|
|
+ pstart := Pos('[', r);
|
|
|
|
+ lFoundMacroInMacro := False;
|
|
|
|
+ end;
|
|
|
|
+ len := Length(r);
|
|
|
|
+ pend := pstart + 2;
|
|
|
|
+ while pend < len do
|
|
|
|
+ begin
|
|
|
|
+ if r[pend] = '[' then // a macro inside a macro
|
|
|
|
+ begin
|
|
|
|
+ lFoundMacroInMacro := True;
|
|
|
|
+ pstart := pend;
|
|
|
|
+ end;
|
|
|
|
+ if r[pend] = ']' then
|
|
|
|
+ break
|
|
|
|
+ else
|
|
|
|
+ inc(pend);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ m := Copy(r, pstart, (pend-pstart)+1);
|
|
|
|
+ if (m = '[PAGECOUNT]') and Page.Report.TwoPass and Page.Report.IsFirstPass then
|
|
|
|
+ begin
|
|
|
|
+ // replace macro with a non-marco marker. We'll replace the marker in the second pass of the report.
|
|
|
|
+ r := StringReplace(r, m, cPageCountMarker, [rfReplaceAll, rfIgnoreCase]);
|
|
|
|
+ // look for more macros
|
|
|
|
+ pstart := Pos('[', r);
|
|
|
|
+ Continue;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ len := Length(m);
|
|
|
|
+ try
|
|
|
|
+ if Assigned(Band.GetData) then
|
|
|
|
+ begin
|
|
|
|
+ try
|
|
|
|
+ mv := Band.GetData.FieldValues[Copy(m, 2, len-2)];
|
|
|
|
+ except
|
|
|
|
+ on e: EVariantTypeCastError do // maybe we have an expression not data field
|
|
|
|
+ begin
|
|
|
|
+ mv := EvaluateExpressionAsText(Copy(m, 2, len-2));
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin // No Data assigned, but maybe we have an expression
|
|
|
|
+ mv := EvaluateExpressionAsText(Copy(m, 2, len-2));
|
|
|
|
+ end;
|
|
|
|
+ except
|
|
|
|
+ on e: EVariantTypeCastError do // ReportData.OnGetValue did not handle all macros, so handle this gracefully
|
|
|
|
+ mv := SErrUnknownMacro+': '+copy(m,2,len-2);
|
|
|
|
+ on e: EExprParser do
|
|
|
|
+ mv := SErrUnknownMacro+': '+copy(m,2,len-2);
|
|
|
|
+ end;
|
|
|
|
+ r := StringReplace(r, m, mv, [rfReplaceAll, rfIgnoreCase]);
|
|
|
|
+ // look for more macros
|
|
|
|
+ pstart := PosEx('[', r,PStart+Length(mv));
|
|
|
|
+ end;
|
|
|
|
+ { This extra check is mostly for ReportGroupHeader expression processing }
|
|
|
|
+ if (pstart = 0) and Assigned(Band.GetData) and AIsExpr then
|
|
|
|
+ begin
|
|
|
|
+ try
|
|
|
|
+ r := EvaluateExpressionAsText(r);
|
|
|
|
+ except
|
|
|
|
+ on E: Exception do
|
|
|
|
+ begin
|
|
|
|
+ { $ifdef gdebug}
|
|
|
|
+ writeln('ERROR in expression: ', E.Message);
|
|
|
|
+ { $endif}
|
|
|
|
+ // do nothing - move on as we probably handled the expression a bit earlier in this code
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ Result := r;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TFPReportElement.GetReportPage: TFPReportCustomPage;
|
|
|
|
+begin
|
|
|
|
+ Result := Band.Page;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFPReportElement.SaveDataToNames;
|
|
procedure TFPReportElement.SaveDataToNames;
|
|
begin
|
|
begin
|
|
// Do nothing
|
|
// Do nothing
|
|
@@ -5270,7 +5427,7 @@ var
|
|
EL : TFPReportElement;
|
|
EL : TFPReportElement;
|
|
|
|
|
|
begin
|
|
begin
|
|
- if not self.Visible then
|
|
|
|
|
|
+ if not self.EvaluateVisibility then
|
|
Exit;
|
|
Exit;
|
|
if Parent is TFPReportCustomBand then
|
|
if Parent is TFPReportCustomBand then
|
|
begin
|
|
begin
|
|
@@ -5338,11 +5495,49 @@ begin
|
|
FOnBeforePrint(self);
|
|
FOnBeforePrint(self);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFPReportElement.EvaluateExpression(const AExpr: String; Out Res: TFPExpressionResult) : Boolean;
|
|
|
|
+
|
|
|
|
+var
|
|
|
|
+ lExpr: TFPExpressionParser;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:=Assigned(Report);
|
|
|
|
+ if not Result then
|
|
|
|
+ exit;
|
|
|
|
+ lExpr := Report.FExpr;
|
|
|
|
+ lExpr.Expression := AExpr;
|
|
|
|
+ Res:=lExpr.Evaluate;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+Function TFPReportElement.GetDateTimeFormat : String;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:='yyyy-mm-dd';
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TFPReportElement.EvaluateExpressionAsText(const AExpr: String): String;
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ Res : TFPExpressionResult;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Result:='';
|
|
|
|
+ if EvaluateExpression(AExpr,Res) then
|
|
|
|
+ case Res.ResultType of
|
|
|
|
+ rtString : Result := Res.ResString;
|
|
|
|
+ rtInteger : Result := IntToStr(Res.ResInteger);
|
|
|
|
+ rtFloat : Result := FloatToStr(Res.ResFloat);
|
|
|
|
+ rtBoolean : Result := BoolToStr(Res.resBoolean, True);
|
|
|
|
+ rtDateTime : Result := FormatDateTime(GetDateTimeFormat, Res.resDateTime);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
function TFPReportElement.Equals(AElement: TFPReportElement): boolean;
|
|
function TFPReportElement.Equals(AElement: TFPReportElement): boolean;
|
|
begin
|
|
begin
|
|
Result := (AElement = Self) or ((AElement.ClassType = AElement.ClassType) and
|
|
Result := (AElement = Self) or ((AElement.ClassType = AElement.ClassType) and
|
|
(AElement.Frame.Equals(Self.Frame)) and (AElement.Layout.Equals(Self.Layout))
|
|
(AElement.Frame.Equals(Self.Frame)) and (AElement.Layout.Equals(Self.Layout))
|
|
- and (AElement.Visible = Self.Visible));
|
|
|
|
|
|
+ and (AElement.Visible = Self.Visible) and (AElement.VisibleExpr = Self.VisibleExpr));
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPReportElement.WriteElement(AWriter: TFPReportStreamer; AOriginal: TFPReportElement);
|
|
procedure TFPReportElement.WriteElement(AWriter: TFPReportStreamer; AOriginal: TFPReportElement);
|
|
@@ -5379,6 +5574,7 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
AWriter.WriteBoolean('Visible', FVisible);
|
|
AWriter.WriteBoolean('Visible', FVisible);
|
|
|
|
+ AWriter.WriteString('VisibleExpr', FVisibleExpr);
|
|
AWriter.WriteString('StretchMode', StretchModeToString(StretchMode));
|
|
AWriter.WriteString('StretchMode', StretchModeToString(StretchMode));
|
|
DoWriteLocalProperties(AWriter, AOriginal);
|
|
DoWriteLocalProperties(AWriter, AOriginal);
|
|
end;
|
|
end;
|
|
@@ -5409,6 +5605,7 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
FVisible := AReader.ReadBoolean('Visible', Visible);
|
|
FVisible := AReader.ReadBoolean('Visible', Visible);
|
|
|
|
+ FVisibleExpr := AReader.ReadString('VisibleExpr', FVisibleExpr);
|
|
FStretchMode := StringToStretchMode(AReader.ReadString('StretchMode', 'smDontStretch'));
|
|
FStretchMode := StringToStretchMode(AReader.ReadString('StretchMode', 'smDontStretch'));
|
|
// TODO: implement reading OnBeforePrint information
|
|
// TODO: implement reading OnBeforePrint information
|
|
end;
|
|
end;
|
|
@@ -5426,6 +5623,7 @@ begin
|
|
Layout.Assign(E.Layout);
|
|
Layout.Assign(E.Layout);
|
|
FParent := E.Parent;
|
|
FParent := E.Parent;
|
|
Visible := E.Visible;
|
|
Visible := E.Visible;
|
|
|
|
+ VisibleExpr := VisibleExpr;
|
|
StretchMode := E.StretchMode;
|
|
StretchMode := E.StretchMode;
|
|
OnBeforePrint := E.OnBeforePrint;
|
|
OnBeforePrint := E.OnBeforePrint;
|
|
end;
|
|
end;
|
|
@@ -5674,6 +5872,16 @@ begin
|
|
RecalcLayout;
|
|
RecalcLayout;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFPReportCustomPage.GetReportPage: TFPReportCustomPage;
|
|
|
|
+begin
|
|
|
|
+ Result := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TFPReportCustomPage.GetReportBand: TFPReportCustomBand;
|
|
|
|
+begin
|
|
|
|
+ Result := nil;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TFPReportCustomPage.SaveDataToNames;
|
|
procedure TFPReportCustomPage.SaveDataToNames;
|
|
begin
|
|
begin
|
|
inherited ;
|
|
inherited ;
|
|
@@ -6035,7 +6243,7 @@ begin
|
|
for i := ABand.ChildCount-1 downto 0 do
|
|
for i := ABand.ChildCount-1 downto 0 do
|
|
begin
|
|
begin
|
|
e := ABand.Child[i];
|
|
e := ABand.Child[i];
|
|
- if not e.Visible then
|
|
|
|
|
|
+ if not e.EvaluateVisibility then
|
|
begin
|
|
begin
|
|
ABand.RemoveChild(e);
|
|
ABand.RemoveChild(e);
|
|
FreeAndNil(e);
|
|
FreeAndNil(e);
|
|
@@ -6607,7 +6815,7 @@ var
|
|
begin
|
|
begin
|
|
lLastDsgnDataBand := ADsgnBand;
|
|
lLastDsgnDataBand := ADsgnBand;
|
|
CommonRuntimeBandProcessing(ADsgnBand);
|
|
CommonRuntimeBandProcessing(ADsgnBand);
|
|
- if lRTBand.Visible then
|
|
|
|
|
|
+ if lRTBand.EvaluateVisibility then
|
|
begin
|
|
begin
|
|
lLastDataBand := lRTBand;
|
|
lLastDataBand := lRTBand;
|
|
RecalcBandLayout(lRTBand);
|
|
RecalcBandLayout(lRTBand);
|
|
@@ -6637,7 +6845,7 @@ var
|
|
while lDsgnChildBand <> nil do
|
|
while lDsgnChildBand <> nil do
|
|
begin
|
|
begin
|
|
CommonRuntimeBandProcessing(lDsgnChildBand);
|
|
CommonRuntimeBandProcessing(lDsgnChildBand);
|
|
- if lRTBand.Visible then
|
|
|
|
|
|
+ if lRTBand.EvaluateVisibility then
|
|
begin
|
|
begin
|
|
RecalcBandLayout(lRTBand);
|
|
RecalcBandLayout(lRTBand);
|
|
UpdateSpaceRemaining(lRTBand);
|
|
UpdateSpaceRemaining(lRTBand);
|
|
@@ -6685,7 +6893,7 @@ var
|
|
Exit; // nothing further to do
|
|
Exit; // nothing further to do
|
|
|
|
|
|
CommonRuntimeBandProcessing(ADsgnBand);
|
|
CommonRuntimeBandProcessing(ADsgnBand);
|
|
- if lRTBand.Visible then
|
|
|
|
|
|
+ if lRTBand.EvaluateVisibility then
|
|
begin
|
|
begin
|
|
lDataHeaderPrinted := True;
|
|
lDataHeaderPrinted := True;
|
|
UpdateSpaceRemaining(lRTBand);
|
|
UpdateSpaceRemaining(lRTBand);
|
|
@@ -6721,7 +6929,7 @@ var
|
|
procedure ShowDataFooterBand(const ADsgnBand: TFPReportCustomDataFooterBand);
|
|
procedure ShowDataFooterBand(const ADsgnBand: TFPReportCustomDataFooterBand);
|
|
begin
|
|
begin
|
|
CommonRuntimeBandProcessing(ADsgnBand);
|
|
CommonRuntimeBandProcessing(ADsgnBand);
|
|
- if lRTBand.Visible then
|
|
|
|
|
|
+ if lRTBand.EvaluateVisibility then
|
|
begin
|
|
begin
|
|
UpdateSpaceRemaining(lRTBand);
|
|
UpdateSpaceRemaining(lRTBand);
|
|
if NoSpaceRemaining then
|
|
if NoSpaceRemaining then
|
|
@@ -6939,7 +7147,9 @@ begin
|
|
{ group header }
|
|
{ group header }
|
|
if lDsgnBand is TFPReportCustomGroupHeaderBand then
|
|
if lDsgnBand is TFPReportCustomGroupHeaderBand then
|
|
begin
|
|
begin
|
|
|
|
+ // Writeln('Found group with expr: ',TFPReportCustomGroupHeaderBand(lDsgnBand).GroupCondition);
|
|
s := TFPReportCustomGroupHeaderBand(lDsgnBand).Evaluate;
|
|
s := TFPReportCustomGroupHeaderBand(lDsgnBand).Evaluate;
|
|
|
|
+ // Writeln('Group new ? "',lLastGroupCondition,'" <> "', s,'"');
|
|
if (lLastGroupCondition <> s) then
|
|
if (lLastGroupCondition <> s) then
|
|
begin
|
|
begin
|
|
lNewGroupHeader := True;
|
|
lNewGroupHeader := True;
|
|
@@ -6969,8 +7179,8 @@ begin
|
|
ClearDataBandLastTextValues(lLastDsgnDataBand);
|
|
ClearDataBandLastTextValues(lLastDsgnDataBand);
|
|
|
|
|
|
CommonRuntimeBandProcessing(lDsgnBand);
|
|
CommonRuntimeBandProcessing(lDsgnBand);
|
|
- lLastGroupCondition := TFPReportGroupHeaderBand(lRTBand).GroupCondition;
|
|
|
|
- if lDsgnBand.Visible = False then
|
|
|
|
|
|
+ lLastGroupCondition := TFPReportGroupHeaderBand(lRTBand).GroupConditionValue;
|
|
|
|
+ if lDsgnBand.EvaluateVisibility = False then
|
|
begin
|
|
begin
|
|
lRTPage.RemoveChild(lRTBand);
|
|
lRTPage.RemoveChild(lRTBand);
|
|
lRTBand.Free;
|
|
lRTBand.Free;
|
|
@@ -7732,113 +7942,6 @@ begin
|
|
// Do nothing
|
|
// Do nothing
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TFPReportCustomBand.ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString;
|
|
|
|
-var
|
|
|
|
- pstart: integer;
|
|
|
|
- pend: integer;
|
|
|
|
- len: integer;
|
|
|
|
- m: string; // macro
|
|
|
|
- mv: string; // macro value
|
|
|
|
- r: string;
|
|
|
|
- lFoundMacroInMacro: boolean;
|
|
|
|
-
|
|
|
|
- function EvaluateExpression(const AExpr: String): String;
|
|
|
|
- var
|
|
|
|
- lExpr: TFPExpressionParser;
|
|
|
|
- begin
|
|
|
|
- Result := '';
|
|
|
|
- lExpr := Page.Report.FExpr;
|
|
|
|
- lExpr.Expression := AExpr;
|
|
|
|
- case lExpr.ResultType of
|
|
|
|
- rtString : Result := lExpr.AsString;
|
|
|
|
- rtInteger : Result := IntToStr(lExpr.AsInteger);
|
|
|
|
- rtFloat : Result := FloatToStr(lExpr.AsFloat);
|
|
|
|
- rtBoolean : Result := BoolToStr(lExpr.AsBoolean, True);
|
|
|
|
- rtDateTime : Result := FormatDateTime('yyyy-mm-dd', lExpr.AsDateTime);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
-begin
|
|
|
|
- r := s;
|
|
|
|
- lFoundMacroInMacro := False;
|
|
|
|
- pstart := Pos('[', r);
|
|
|
|
- while (pstart > 0) or lFoundMacroInMacro do
|
|
|
|
- begin
|
|
|
|
- if lFoundMacroInMacro then
|
|
|
|
- begin
|
|
|
|
- pstart := Pos('[', r);
|
|
|
|
- lFoundMacroInMacro := False;
|
|
|
|
- end;
|
|
|
|
- len := Length(r);
|
|
|
|
- pend := pstart + 2;
|
|
|
|
- while pend < len do
|
|
|
|
- begin
|
|
|
|
- if r[pend] = '[' then // a macro inside a macro
|
|
|
|
- begin
|
|
|
|
- lFoundMacroInMacro := True;
|
|
|
|
- pstart := pend;
|
|
|
|
- end;
|
|
|
|
- if r[pend] = ']' then
|
|
|
|
- break
|
|
|
|
- else
|
|
|
|
- inc(pend);
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- m := Copy(r, pstart, (pend-pstart)+1);
|
|
|
|
- if (m = '[PAGECOUNT]') and Page.Report.TwoPass and Page.Report.IsFirstPass then
|
|
|
|
- begin
|
|
|
|
- // replace macro with a non-marco marker. We'll replace the marker in the second pass of the report.
|
|
|
|
- r := StringReplace(r, m, cPageCountMarker, [rfReplaceAll, rfIgnoreCase]);
|
|
|
|
- // look for more macros
|
|
|
|
- pstart := Pos('[', r);
|
|
|
|
- Continue;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- len := Length(m);
|
|
|
|
- try
|
|
|
|
- if Assigned(GetData) then
|
|
|
|
- begin
|
|
|
|
- try
|
|
|
|
- mv := GetData.FieldValues[Copy(m, 2, len-2)];
|
|
|
|
- except
|
|
|
|
- on e: EVariantTypeCastError do // maybe we have an expression not data field
|
|
|
|
- begin
|
|
|
|
- mv := EvaluateExpression(Copy(m, 2, len-2));
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- begin // No Data assigned, but maybe we have an expression
|
|
|
|
- mv := EvaluateExpression(Copy(m, 2, len-2));
|
|
|
|
- end;
|
|
|
|
- except
|
|
|
|
- on e: EVariantTypeCastError do // ReportData.OnGetValue did not handle all macros, so handle this gracefully
|
|
|
|
- mv := SErrUnknownMacro+': '+copy(m,2,len-2);
|
|
|
|
- on e: EExprParser do
|
|
|
|
- mv := SErrUnknownMacro+': '+copy(m,2,len-2);
|
|
|
|
- end;
|
|
|
|
- r := StringReplace(r, m, mv, [rfReplaceAll, rfIgnoreCase]);
|
|
|
|
- // look for more macros
|
|
|
|
- pstart := PosEx('[', r,PStart+Length(mv));
|
|
|
|
- end;
|
|
|
|
- { This extra check is mostly for ReportGroupHeader expression processing }
|
|
|
|
- if (pstart = 0) and Assigned(GetData) and AIsExpr then
|
|
|
|
- begin
|
|
|
|
- try
|
|
|
|
- r := EvaluateExpression(r);
|
|
|
|
- except
|
|
|
|
- on E: Exception do
|
|
|
|
- begin
|
|
|
|
- {$ifdef gdebug}
|
|
|
|
- writeln('ERROR in expression: ', E.Message);
|
|
|
|
- {$endif}
|
|
|
|
- // do nothing - move on as we probably handled the expression a bit earlier in this code
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- Result := r;
|
|
|
|
-end;
|
|
|
|
-
|
|
|
|
procedure TFPReportCustomBand.SetParent(const AValue: TFPReportElement);
|
|
procedure TFPReportCustomBand.SetParent(const AValue: TFPReportElement);
|
|
begin
|
|
begin
|
|
if not ((AValue = nil) or (AValue is TFPReportCustomPage)) then
|
|
if not ((AValue = nil) or (AValue is TFPReportCustomPage)) then
|
|
@@ -7853,6 +7956,7 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPReportCustomBand.PrepareObjects;
|
|
procedure TFPReportCustomBand.PrepareObjects;
|
|
|
|
+
|
|
var
|
|
var
|
|
lRTPage: TFPReportCustomPage;
|
|
lRTPage: TFPReportCustomPage;
|
|
i: integer;
|
|
i: integer;
|
|
@@ -7863,6 +7967,7 @@ var
|
|
c: integer;
|
|
c: integer;
|
|
n: TFPExprNode;
|
|
n: TFPExprNode;
|
|
nIdx: integer;
|
|
nIdx: integer;
|
|
|
|
+
|
|
begin
|
|
begin
|
|
i := Page.Report.FRTCurPageIdx;
|
|
i := Page.Report.FRTCurPageIdx;
|
|
if Assigned(Page.Report.RTObjects[i]) then
|
|
if Assigned(Page.Report.RTObjects[i]) then
|
|
@@ -7876,11 +7981,7 @@ begin
|
|
inherited PrepareObjects;
|
|
inherited PrepareObjects;
|
|
|
|
|
|
if self is TFPReportGroupHeaderBand then
|
|
if self is TFPReportGroupHeaderBand then
|
|
- begin
|
|
|
|
- s := TFPReportGroupHeaderBand(Page.Report.FRTCurBand).GroupCondition;
|
|
|
|
- s := ExpandMacro(s, True);
|
|
|
|
- TFPReportCustomGroupHeaderBand(Page.Report.FRTCurBand).GroupCondition := s;
|
|
|
|
- end;
|
|
|
|
|
|
+ TFPReportGroupHeaderBand(Page.Report.FRTCurBand).CalcGroupConditionValue;
|
|
|
|
|
|
if Assigned(FChildren) then
|
|
if Assigned(FChildren) then
|
|
begin
|
|
begin
|