| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2022 by Michael van Canneyt and other members of the
- Free Pascal development team
- report data
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$IFNDEF FPC_DOTTEDUNITS}
- unit fpreportdata;
- {$ENDIF FPC_DOTTEDUNITS}
- {$mode objfpc}{$H+}
- interface
- {$IFDEF FPC_DOTTEDUNITS}
- uses
- System.Classes, System.SysUtils, Data.Db, FpJson.Data, FpReport.Report, FpReport.Data.Db;
- {$ELSE FPC_DOTTEDUNITS}
- uses
- Classes, SysUtils, DB, fpjson, fpreport, fpreportdb;
- {$ENDIF FPC_DOTTEDUNITS}
- Type
- EReportDataError = class(EReportError);
- { TFPReportDataHandler }
- TFPReportDataHandler = Class(TObject)
- Public
- Class Procedure RegisterHandler;
- Class Procedure UnRegisterHandler;
- Class Procedure RegisterConfigClass(aClass : TComponentClass);
- // Override this to return a dataset which is owned by AOwner, and configured by AConfig.
- // The dataset must not be opened.
- Function CreateDataset(AOwner : TComponent; AConfig : TJSONObject) : TDataset; virtual; abstract;
- // By default, master-detail is not possible. Let this return 'True' indicate that a dataset allows master-detail.
- Class Function AllowMasterDetail : Boolean; virtual;
- // This is called to set the master dataset on Detail
- Class Procedure SetMasterDataset(ADetail,AMaster : TDataset); virtual;
- // Check if the configuration is valid. Return a string that describes the error(s)
- // If the return is an empty string, the data designer will not close.
- Class Function CheckConfig(AConfig : TJSONObject) : String; virtual;
- // Called before and after rendering of a report in the designer.
- // Can be used to start/stop transactions
- Class Procedure StartRender(ADataset : TDataset); virtual;
- Class Procedure EndRender(ADataset : TDataset); virtual;
- // Configuration component. This is normally a visual class.
- Class Function ConfigFrameClass : TComponentClass; virtual;
- Class Function DataType : String; virtual; abstract;
- Class Function DataTypeDescription : String; virtual;
- end;
- TFPReportDataHandlerClass = Class of TFPReportDataHandler;
- { TFPReportDataDefinitionItem }
- TFPReportDataDefinitionItem = Class(TCollectionItem)
- private
- FConfig: TJSONObject;
- FDataType: String;
- FMaster: String;
- FName: String;
- FReportData: TFPReportDatasetData;
- FRunReportDataItem: TFPReportDataItem;
- function GetJSONConfig: TJSONStringType;
- procedure SetConfig(AValue: TJSONObject);
- procedure SetJSONConfig(AValue: TJSONStringType);
- procedure SetMaster(AValue: String);
- procedure SetName(AValue: String);
- Protected
- // To hold temporary references
- Property RunReportData : TFPReportDatasetData Read FReportData Write FReportData;
- Property RunReportDataItem : TFPReportDataItem Read FRunReportDataItem Write FRunReportDataItem;
- Public
- Constructor Create(ACollection: TCollection); override;
- Destructor Destroy; override;
- Procedure Assign(Source : TPersistent); override;
- Procedure SaveToJSON(O : TJSONObject); virtual;
- procedure LoadFromJSON(O: TJSONObject); virtual;
- // Clone this
- Function Clone(aNewName : String) : TFPReportDataDefinitionItem;
- // Create a dataset.
- Function CreateDataSet(AOwner : TComponent) : TDataset;
- // Check if the configuration is OK.
- Function Check : String;
- Property Config : TJSONObject Read FConfig Write SetConfig;
- Published
- property Name : String Read FName Write SetName;
- Property DataType : String Read FDataType Write FDataType;
- property Master : String Read FMaster Write SetMaster;
- Property JSONConfig : TJSONStringType Read GetJSONConfig Write SetJSONConfig;
- end;
- { TFPReportDataDefinitions }
- TFPReportDataDefinitions = Class(TCollection)
- private
- function GetD(Aindex : Integer): TFPReportDataDefinitionItem;
- procedure SetD(Aindex : Integer; AValue: TFPReportDataDefinitionItem);
- Public
- Function IndexOfRunData(aData : TFPReportDatasetData) : integer;
- Function IndexOfName(const aName : String): Integer;
- Procedure CheckCircularReference(aMasterName : String; aItem : TFPReportDataDefinitionItem);
- Function FindDataByName(const aName : String): TFPReportDataDefinitionItem;
- Function AddData(const aName : String) : TFPReportDataDefinitionItem;
- Procedure SaveToJSON(O : TJSONObject);
- Procedure LoadFromJSON(O : TJSONObject);
- Property Data [Aindex : Integer] : TFPReportDataDefinitionItem Read GetD Write SetD; default;
- end;
- { TFPCustomReportDataManager }
- TFPCustomReportDataManager = class(TComponent)
- private
- Class Var
- FTypesList : TStrings;
- Type
- { THDef }
- THDef = Class(TObject)
- TheClass : TFPReportDataHandlerClass;
- TheConfigClass : TComponentClass;
- Constructor Create(aClass : TFPReportDataHandlerClass; aConfigClass : TComponentClass);
- end;
- procedure ClearReportDatasetReference(aDataset: TFPReportDatasetData);
- Class Function FindDef(aDataType: String) : THDef;
- Class Function GetDef(aDataType: String) : THDef;
- Private
- FDataParent: TComponent;
- FMyParent : TComponent;
- FDefinitions: TFPReportDataDefinitions;
- FReport: TFPReport;
- procedure SetDataParent(AValue: TComponent);
- procedure SetDefinitions(AValue: TFPReportDataDefinitions);
- procedure SetReport(AValue: TFPReport);
- Protected
- Class Function TypeList : TStrings;
- Class procedure RemoveHandler(aDataType: String);
- Class Procedure RegisterHandler(aClass: TFPReportDataHandlerClass); virtual;
- Class Procedure UnRegisterHandler(aClass: TFPReportDataHandlerClass); virtual;
- Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- Function CreateDataDefinitions : TFPReportDataDefinitions; virtual;
- Function GetDatasetParent : TComponent;
- Property DataDefinitions : TFPReportDataDefinitions Read FDefinitions Write SetDefinitions;
- Public
- Class Function GetRegisteredTypes(AList : Tstrings) : Integer;
- Class Procedure RegisterConfigFrameClass(aTypeName : String; aClass : TComponentClass);
- Class Procedure UnRegisterConfigFrameClass(aTypeName : String);
- Class Function GetTypeHandlerClass(aTypeName : String) : TFPReportDataHandlerClass;
- Class Function GetTypeHandler(aTypeName : String) : TFPReportDataHandler;
- Class Function GetConfigFrameClass(aTypeName : String) : TComponentClass;
- Constructor Create(AOwner : TComponent); override;
- Destructor Destroy; override;
- Procedure SaveToJSON(O : TJSONObject);
- Procedure LoadFromJSON(O : TJSONObject);
- procedure RemoveFromReport(aReport: TFPReport);virtual;
- procedure RemoveFromReport;
- procedure ApplyToReport(aReport: TFPReport; Errors: TStrings); virtual;
- Procedure ApplyToReport(Errors : TStrings);
- // call this to start/stop a render, so dataset handlers can do cleanup, refetch data, reset transactions.
- Procedure StartRender;
- Procedure EndRender;
- Property Report : TFPReport Read FReport Write SetReport;
- Property DataParent : TComponent Read FDataParent Write SetDataParent;
- end;
- TFPReportDataManager = Class(TFPCustomReportDataManager)
- Public
- Property DataDefinitions;
- end;
- Resourcestring
- SErrDuplicateData = 'Duplicate data set name: "%s"';
- SErrInvalidDataName = 'Invalid data set name: "%s"';
- SErrNeedName = 'Data set needs a name';
- SErrNeedDataType = 'Data set needs a type';
- SErrInvalidDataType = 'Invalid data type: "%s"';
- SErrInvalidJSONConfig = '%s: Invalid JSON Configuration';
- SErrUnknownDataType = 'Unknown report data type: %s';
- SErrNoMasterDetailSupport = 'No master-detail support for class "%s"';
- SErrOpeningDataset = 'Error opening data "%s" : Exception %s with message %s';
- SErrInvalidDatasourceName = 'Invalid data source name : "%s"';
- SErrCircularReference = 'Invalid master data source "%s", circular references not allowed.';
- implementation
- Const
- DatasetNamePrefix = '__DS__';
- { TFPCustomReportDataManager }
- procedure TFPCustomReportDataManager.SetDefinitions(AValue: TFPReportDataDefinitions);
- begin
- if FDefinitions=AValue then Exit;
- FDefinitions.Assign(AValue);
- end;
- procedure TFPCustomReportDataManager.SetDataParent(AValue: TComponent);
- begin
- if FDataParent=AValue then Exit;
- If Assigned(FDataParent) then
- FDataParent.RemoveFreeNotification(Self);
- FDataParent:=AValue;
- If Assigned(FDataParent) then
- FDataParent.FreeNotification(Self);
- FreeAndNil(FMyParent);
- end;
- class function TFPCustomReportDataManager.FindDef(aDataType: String): THDef;
- var
- I : Integer;
- begin
- I:=TypeList.IndexOf(aDataType);
- if (I<>-1) then
- Result:=TypeList.Objects[i] as THDef
- else
- Result:=Nil;
- end;
- class function TFPCustomReportDataManager.GetDef(aDataType: String): THDef;
- begin
- Result:=FindDef(aDataType);
- if Result=Nil then
- Raise EReportDataError.CreateFmt(SErrUnknownDataType,[aDataType]);
- end;
- procedure TFPCustomReportDataManager.SetReport(AValue: TFPReport);
- begin
- if FReport=AValue then Exit;
- If Assigned(FReport) then
- FReport.RemoveFreeNotification(Self);
- FReport:=AValue;
- If Assigned(FReport) then
- FReport.FreeNotification(Self);
- end;
- class procedure TFPCustomReportDataManager.RegisterHandler(aClass: TFPReportDataHandlerClass);
- Var
- N : String;
- C : TComponentClass;
- begin
- N:=aClass.DataType;
- RemoveHandler(N);
- C:=aClass.ConfigFrameClass;
- TypeList.AddObject(N, THDef.Create(aClass,C));
- end;
- class procedure TFPCustomReportDataManager.RemoveHandler(aDataType : String);
- Var
- I : Integer;
- O : TObject;
- begin
- I:=TypeList.IndexOf(aDataType);
- if (I<>-1) then
- begin
- O:=TypeList.Objects[i];
- TypeList.Delete(I);
- O.Free;
- end;
- end;
- class procedure TFPCustomReportDataManager.UnRegisterHandler(aClass: TFPReportDataHandlerClass);
- begin
- RemoveHandler(aClass.DataType);
- end;
- procedure TFPCustomReportDataManager.ClearReportDatasetReference(aDataset : TFPReportDatasetData);
- Var
- I : Integer;
- begin
- if Assigned(FDefinitions) then
- begin
- I:=FDefinitions.IndexOfRunData(aDataset);
- if (I<>-1) then
- FDefinitions[i].RunReportData:=nil;
- end;
- end;
- procedure TFPCustomReportDataManager.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if Operation=opRemove then
- begin
- if AComponent=FDataParent then
- FDataParent:=Nil
- else if AComponent=FReport then
- FReport:=Nil
- else if (aComponent is TFPReportDatasetData) then
- ClearReportDatasetReference(aComponent as TFPReportDatasetData);
- end;
- end;
- Class function TFPCustomReportDataManager.TypeList: TStrings;
- Var
- SL : TStringList;
- begin
- If (FTypesList=nil) then
- begin
- SL:=TStringList.Create;
- SL.Sorted:=True;
- SL.Duplicates:=dupError;
- SL.OwnsObjects:=True;
- FTypesList:=SL;
- end;
- Result:=FTypesList;
- end;
- function TFPCustomReportDataManager.CreateDataDefinitions: TFPReportDataDefinitions;
- begin
- Result:=TFPReportDataDefinitions.Create(TFPReportDataDefinitionItem);
- end;
- function TFPCustomReportDataManager.GetDatasetParent: TComponent;
- begin
- Result:=FDataParent;
- if Result=Nil then
- begin
- If (FMyParent=Nil) then
- FMyParent:=TComponent.Create(Nil);
- Result:=FMyParent;
- end;
- end;
- constructor TFPCustomReportDataManager.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FDefinitions:=CreateDataDefinitions;
- end;
- destructor TFPCustomReportDataManager.Destroy;
- begin
- FreeAndNil(FDefinitions);
- FreeAndNil(FMyParent);
- inherited Destroy;
- end;
- procedure TFPCustomReportDataManager.SaveToJSON(O: TJSONObject);
- begin
- DataDefinitions.SaveToJSON(O);
- end;
- procedure TFPCustomReportDataManager.LoadFromJSON(O: TJSONObject);
- begin
- DataDefinitions.LoadFromJSON(O);
- end;
- procedure TFPCustomReportDataManager.RemoveFromReport(aReport: TFPReport);
- Var
- DD : TFPReportDataDefinitionItem;
- RD : TFPReportDatasetData;
- D : TDataset;
- I : Integer;
- begin
- aReport.SaveDataToNames;
- For I:=0 to DataDefinitions.Count-1 do
- begin
- DD:=DataDefinitions[i];
- RD:=DD.RunReportData;
- if (RD<>Nil) then
- if (aReport.ReportData.IndexOfReportData(RD)<>-1) then
- begin
- D:=RD.Dataset;
- FreeAndNil(D);
- FreeAndNil(RD); // Should nil due to freenotification...
- DD.RunReportData:=Nil;
- end;
- end;
- end;
- procedure TFPCustomReportDataManager.RemoveFromReport;
- begin
- RemoveFromReport(FReport);
- end;
- procedure TFPCustomReportDataManager.ApplyToReport(Errors: TStrings);
- begin
- ApplyToReport(FReport,Errors);
- end;
- procedure TFPCustomReportDataManager.StartRender;
- Var
- I : integer;
- D : TFPReportDataDefinitionItem;
- H : TFPReportDataHandlerClass;
- begin
- // Create all datasets
- For I:=0 to DataDefinitions.Count-1 do
- begin
- D:=DataDefinitions[i];
- if Assigned(D.RunReportData) then
- begin
- H:=TFPCustomReportDataManager.GetTypeHandlerClass(D.DataType);
- H.StartRender(D.RunReportData.DataSet);
- end;
- end;
- end;
- procedure TFPCustomReportDataManager.EndRender;
- Var
- I : integer;
- D : TFPReportDataDefinitionItem;
- H : TFPReportDataHandlerClass;
- begin
- // Create all datasets
- For I:=0 to DataDefinitions.Count-1 do
- begin
- D:=DataDefinitions[i];
- if Assigned(D.RunReportData) then
- begin
- H:=TFPCustomReportDataManager.GetTypeHandlerClass(D.DataType);
- H.EndRender(D.RunReportData.DataSet);
- end;
- end;
- end;
- procedure TFPCustomReportDataManager.ApplyToReport(aReport : TFPReport; Errors: TStrings);
- Var
- I : Integer;
- MasterD,DesignD : TFPReportDataDefinitionItem;
- DatasetD : TFPReportDatasetData;
- H : TFPReportDataHandlerClass;
- L : TFPList;
- P : TComponent;
- DDS,MDS : TDataset;
- begin
- P:=GetDatasetParent;
- aReport.ReportData.Clear;
- // Create all datasets
- For I:=0 to DataDefinitions.Count-1 do
- begin
- DesignD:=DataDefinitions[i];
- DatasetD:=TFPReportDatasetData.Create(P);
- DesignD.RunReportData:=DatasetD;
- DatasetD.FreeNotification(Self);
- DatasetD.Dataset:=DesignD.CreateDataSet(P);
- Try
- DatasetD.InitFieldDefs;
- except
- On E : Exception do
- If Assigned(Errors) then
- Errors.Add(Format(SErrOpeningDataset, [DesignD.Name, E.ClassName, E.Message]))
- else
- Raise;
- end;
- DatasetD.Name:=DesignD.Name;
- DatasetD.Dataset.Name:=DatasetNamePrefix+DesignD.Name;
- DatasetD.StartDesigning; // set designing flag, or OI will not show reference to it.
- DesignD.RunReportDataItem:=aReport.ReportData.AddReportData(DatasetD);
- end;
- // Set master-detail relations
- For I:=0 to DataDefinitions.Count-1 do
- begin
- DesignD:=DataDefinitions[i];
- if (DesignD.Master<>'') then
- begin
- H:=TFPCustomReportDataManager.GetTypeHandlerClass(DesignD.DataType);
- MasterD:=DataDefinitions.FindDataByName(DesignD.Master);
- DDS:=(DesignD.RunReportDataItem.Data as TFPReportDatasetData).DataSet;
- MDS:=(MasterD.RunReportDataItem.Data as TFPReportDatasetData).DataSet;
- H.SetMasterDataset(DDS,MDS);
- end;
- end;
- end;
- class function TFPCustomReportDataManager.GetRegisteredTypes(AList: Tstrings): Integer;
- begin
- // Don't use assign or addstrings, it will copy the THRefs too, possibly leading to errors
- AList.Text:=TypeList.Text;
- Result:=AList.Count;
- end;
- class procedure TFPCustomReportDataManager.RegisterConfigFrameClass(aTypeName: String; aClass: TComponentClass);
- Var
- H : THDef;
- begin
- H:=GetDef(aTypeName);
- H.TheConfigClass:=aClass;
- end;
- class procedure TFPCustomReportDataManager.UnRegisterConfigFrameClass(aTypeName: String);
- Var
- H : THDef;
- begin
- H:=FindDef(aTypeName);
- if Assigned(H) then
- H.TheConfigClass:=Nil;
- end;
- class function TFPCustomReportDataManager.GetTypeHandlerClass(aTypeName: String): TFPReportDataHandlerClass;
- Var
- H : THDef;
- begin
- H:=GetDef(aTypeName);
- Result:=H.TheClass;
- end;
- class function TFPCustomReportDataManager.GetTypeHandler(aTypeName: String): TFPReportDataHandler;
- begin
- Result:=GetTypeHandlerClass(aTypeName).Create;
- end;
- class function TFPCustomReportDataManager.GetConfigFrameClass(aTypeName: String): TComponentClass;
- Var
- H : THDef;
- begin
- H:=GetDef(aTypeName);
- Result:=H.TheConfigClass;
- end;
- { THDef }
- constructor TFPCustomReportDataManager.THDef.Create(aClass: TFPReportDataHandlerClass; aConfigClass : TComponentClass);
- begin
- TheClass:=AClass;
- TheConfigClass:=aConfigClass;
- end;
- { TFPReportDataDefinitions }
- function TFPReportDataDefinitions.GetD(Aindex : Integer): TFPReportDataDefinitionItem;
- begin
- Result:=Items[Aindex] as TFPReportDataDefinitionItem;
- end;
- procedure TFPReportDataDefinitions.SetD(Aindex : Integer; AValue: TFPReportDataDefinitionItem);
- begin
- Items[Aindex]:=AValue;
- end;
- function TFPReportDataDefinitions.IndexOfRunData(aData: TFPReportDatasetData): integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (GetD(Result).RunReportData<>aData) do
- Dec(Result);
- end;
- function TFPReportDataDefinitions.IndexOfName(const aName: String): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (CompareText(AName,GetD(Result).Name)<>0) do
- Dec(Result);
- end;
- procedure TFPReportDataDefinitions.CheckCircularReference(aMasterName: String; aItem: TFPReportDataDefinitionItem);
- Var
- DD : TFPReportDataDefinitionItem;
- begin
- While (aMasterName<>'') do
- begin
- DD:=FindDataByName(aMasterName);
- if (DD=Nil) then
- raise EReportDataError.CreateFmt(SErrInvalidDatasourceName, [aMasterName]);
- If (DD=aItem) then
- raise EReportDataError.CreateFmt(SErrCircularReference, [aMasterName]);
- aMasterName:=DD.Master;
- end;
- end;
- function TFPReportDataDefinitions.FindDataByName(const aName: String): TFPReportDataDefinitionItem;
- var
- I : Integer;
- begin
- I:=indexOfname(aName);
- if I=-1 then
- Result:=Nil
- else
- Result:=GetD(I);
- end;
- function TFPReportDataDefinitions.AddData(const aName: String): TFPReportDataDefinitionItem;
- begin
- if (IndexOfName(aName)<>-1) then
- raise EReportDataError.CreateFmt(SErrDuplicateData, [aName]);
- Result:=add as TFPReportDataDefinitionItem;
- Result.Name:=aName;
- end;
- procedure TFPReportDataDefinitions.SaveToJSON(O: TJSONObject);
- Var
- A : TJSONArray;
- DS : TJSONObject;
- I : Integer;
- begin
- A:=TJSONArray.Create;
- O.Add('datasets',a);
- For I:=0 to Count-1 do
- begin
- DS:=TJSONObject.Create;
- A.Add(DS);
- Data[i].SaveToJSON(DS);
- end;
- end;
- procedure TFPReportDataDefinitions.LoadFromJSON(O: TJSONObject);
- Var
- A : TJSONArray;
- DS : TFPReportDataDefinitionItem;
- I : Integer;
- begin
- Clear;
- A:=O.Get('datasets',TJSONArray(Nil));
- if Assigned(A) then
- For I:=0 to A.Count-1 do
- if A.Types[i]=jtObject then
- begin
- DS:=Add as TFPReportDataDefinitionItem;
- DS.LoadFromJSON(A.Objects[i]);
- end;
- end;
- class procedure TFPReportDataHandler.RegisterHandler;
- begin
- TFPCustomReportDataManager.RegisterHandler(Self);
- end;
- class procedure TFPReportDataHandler.UnRegisterHandler;
- begin
- TFPCustomReportDataManager.UnRegisterHandler(Self);
- end;
- class procedure TFPReportDataHandler.RegisterConfigClass(aClass: TComponentClass);
- begin
- TFPCustomReportDataManager.RegisterConfigFrameClass(DataType,aClass);
- end;
- class function TFPReportDataHandler.AllowMasterDetail: Boolean;
- begin
- Result:=False;
- end;
- Class procedure TFPReportDataHandler.SetMasterDataset(ADetail, AMaster: TDataset);
- begin
- Raise EReportDataError.CreateFmt(SErrNoMasterDetailSupport,[ADetail.ClassName]);
- end;
- class function TFPReportDataHandler.CheckConfig(AConfig: TJSONObject): String;
- begin
- Result:='';
- end;
- class procedure TFPReportDataHandler.StartRender(ADataset: TDataset);
- begin
- // Do nothing
- end;
- class procedure TFPReportDataHandler.EndRender(ADataset: TDataset);
- begin
- // Do nothing
- end;
- class function TFPReportDataHandler.ConfigFrameClass: TComponentClass;
- begin
- Result:=Nil;
- end;
- class function TFPReportDataHandler.DataTypeDescription: String;
- begin
- Result:=DataType
- end;
- { TFPReportDataDefinitionItem }
- procedure TFPReportDataDefinitionItem.SetConfig(AValue: TJSONObject);
- begin
- if FConfig=AValue then Exit;
- FreeAndNil(FConfig);
- FConfig:=AValue.Clone as TJSONObject;
- end;
- function TFPReportDataDefinitionItem.GetJSONConfig: TJSONStringType;
- begin
- Result:=FConfig.AsJSON;
- end;
- procedure TFPReportDataDefinitionItem.SetJSONConfig(AValue: TJSONStringType);
- Var
- D : TJSONData;
- begin
- D:=GetJSON(aValue);
- if D is TJSONObject then
- begin
- FreeAndNil(FConfig);
- FConfig:=D as TJSONObject;
- end
- else
- begin
- FreeAndNil(D);
- Raise EReportDataError.CreateFmt(SErrInvalidJSONConfig,[Name]);
- end;
- end;
- procedure TFPReportDataDefinitionItem.SetMaster(AValue: String);
- begin
- if FMaster=AValue then Exit;
- FMaster:=AValue;
- end;
- procedure TFPReportDataDefinitionItem.SetName(AValue: String);
- begin
- if FName=AValue then Exit;
- {$IF FPC_FULLVERSION < 30002}
- if Not IsValidIdent(aValue) then
- {$ELSE}
- if Not IsValidIdent(aValue,True,true) then
- {$ENDIF}
- raise EReportDataError.CreateFmt(SErrInvalidDataName, [aValue]);
- if (Collection is TFPReportVariables) then
- If ((Collection as TFPReportVariables).FindVariable(AValue)<>Nil) then
- raise EReportDataError.CreateFmt(SErrDuplicateData, [aValue]);
- FName:=AValue;
- end;
- procedure TFPReportDataDefinitionItem.Assign(Source: TPersistent);
- Var
- D : TFPReportDataDefinitionItem;
- begin
- if (Source is TFPReportDataDefinitionItem) then
- begin
- D:=Source as TFPReportDataDefinitionItem;
- Config:=D.Config;
- Name:=D.Name;
- DataType:=D.DataType;
- Master:=D.Master;
- end
- else
- inherited Assign(Source);
- end;
- procedure TFPReportDataDefinitionItem.SaveToJSON(O: TJSONObject);
- begin
- O.Add('name',Name);
- O.Add('type',DataType);
- O.Add('config',Config.Clone);
- O.Add('master',Master);
- end;
- procedure TFPReportDataDefinitionItem.LoadFromJSON(O: TJSONObject);
- Var
- C : TJSONObject;
- begin
- Name:=O.Get('name',Name);
- DataType:=O.Get('type',DataType);
- C:=O.Get('config',TJSONObject(Nil));
- if Assigned(C) then
- Config:=C;
- Master:=O.Get('master','');
- end;
- function TFPReportDataDefinitionItem.Clone(aNewName: String): TFPReportDataDefinitionItem;
- begin
- Result:=Collection.Add as TFPReportDataDefinitionItem;
- Result.Assign(Self);
- Result.Name:=aNewName;
- end;
- function TFPReportDataDefinitionItem.CreateDataSet(AOwner: TComponent): TDataset;
- Var
- H : TFPReportDataHandler;
- begin
- H:=TFPCustomReportDataManager.GetTypeHandler(DataType);
- try
- Result:=H.CreateDataset(AOwner,Config);
- finally
- H.Free;
- end;
- end;
- function TFPReportDataDefinitionItem.Check: String;
- Var
- H : TFPReportDataHandler;
- begin
- If (Name='') then
- Result:=SErrNeedName
- else if (DataType='') then
- Result:=SErrNeedDataType
- else
- begin
- H:=TFPCustomReportDataManager.GetTypeHandler(DataType);
- try
- if H=Nil then
- Result:=Format(SErrInvalidDataType,[DataType])
- else
- Result:=H.CheckConfig(Config);
- Finally
- H.Free;
- end;
- end;
- end;
- constructor TFPReportDataDefinitionItem.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- FConfig:=TJSONObject.Create;
- end;
- destructor TFPReportDataDefinitionItem.Destroy;
- begin
- FreeAndNil(FConfig);
- inherited Destroy;
- end;
- Finalization
- FreeAndNil(TFPCustomReportDataManager.FTypesList);
- end.
|