mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-19 18:06:57 +02:00
435 lines
10 KiB
ObjectPascal
435 lines
10 KiB
ObjectPascal
{
|
|
This file is part of the Free Component Library.
|
|
Copyright (c) 2017 Michael Van Canneyt, member of the Free Pascal development team
|
|
|
|
Form to configure the report loops in a report.
|
|
|
|
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.
|
|
|
|
**********************************************************************}
|
|
unit frmconfigreportdata;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons,
|
|
ButtonPanel, ActnList, ComCtrls, ExtCtrls, EditBtn,
|
|
fpreportdata, fpreportdesignreportdata, fpjson, reportdesignbaseforms;
|
|
|
|
type
|
|
TForm = TBaseReportDataForm;
|
|
{ TReportDataConfigForm }
|
|
|
|
TReportDataConfigForm = class(TForm)
|
|
AAddData: TAction;
|
|
APreview: TAction;
|
|
ADuplicate: TAction;
|
|
ADeleteData: TAction;
|
|
ALReportData: TActionList;
|
|
BPVariables: TButtonPanel;
|
|
CBType: TComboBox;
|
|
CBMaster: TComboBox;
|
|
EName: TEdit;
|
|
ILReportdata: TImageList;
|
|
Label4: TLabel;
|
|
LBReportData: TListBox;
|
|
LENAme: TLabel;
|
|
Label3: TLabel;
|
|
LLBReportData: TLabel;
|
|
PSources: TPanel;
|
|
PData: TPanel;
|
|
SBAdd: TSpeedButton;
|
|
SBDuplicate: TSpeedButton;
|
|
SBDelete: TSpeedButton;
|
|
SBPreview: TSpeedButton;
|
|
Splitter1: TSplitter;
|
|
procedure AAddDataExecute(Sender: TObject);
|
|
procedure ADeleteDataExecute(Sender: TObject);
|
|
procedure ADeleteDataUpdate(Sender: TObject);
|
|
procedure ADuplicateExecute(Sender: TObject);
|
|
procedure ADuplicateUpdate(Sender: TObject);
|
|
procedure APreviewExecute(Sender: TObject);
|
|
procedure APreviewUpdate(Sender: TObject);
|
|
procedure CBMasterChange(Sender: TObject);
|
|
procedure CBTypeChange(Sender: TObject);
|
|
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure LBReportDataSelectionChange(Sender: TObject; User: boolean);
|
|
private
|
|
FCurrentHandler : TFPReportDataHandler;
|
|
FCurrentData : TFPReportDataDefinitionItem;
|
|
FCurrentFrame : TReportDataConfigFrame;
|
|
Protected
|
|
procedure NewItem(CloneFrom: TFPReportDataDefinitionItem); virtual;
|
|
function SaveCurrentItem: Boolean; virtual;
|
|
procedure SetData(AValue: TFPReportDataDefinitions); override;
|
|
procedure ShowData; virtual;
|
|
procedure ShowDataFrame; virtual;
|
|
procedure ShowSelectedItem;virtual;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
Resourcestring
|
|
SDataNotOK = 'Report data source not correctly configured';
|
|
SErrNewData = 'New report data source';
|
|
SNameNewData = 'Enter the name of the data source.';
|
|
SAllowedChars1 = 'Allowed characters are letters, numbers, underscores (_) and dots (.).';
|
|
SAllowedChars2 = 'The first character must be a letter or underscore';
|
|
SErrIllegalDataName = 'The data source name %s is not a legal data source name.';
|
|
SWarnDuplicateDataName = 'The data set name %s already exists.';
|
|
SNone = '(none)';
|
|
|
|
{ TReportDataConfigForm }
|
|
|
|
procedure TReportDataConfigForm.FormCreate(Sender: TObject);
|
|
begin
|
|
TDesignReportDataManager.GetRegisteredTypes(CBType.Items);
|
|
ShowSelectedItem;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.CBTypeChange(Sender: TObject);
|
|
begin
|
|
|
|
ShowDataFrame;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ShowDataFrame;
|
|
|
|
Var
|
|
M : String;
|
|
|
|
begin
|
|
FreeAndNil(FCurrentHandler);
|
|
FreeAndNil(FCurrentFrame);
|
|
if CBType.ItemIndex=-1 then
|
|
exit;
|
|
FCurrentHandler:=TDesignReportDataManager.GetTypeHandler(CBType.Text);
|
|
FCurrentFrame:=TDesignReportDataManager.CreateConfigFrame(FCurrentHandler.DataType,Self);
|
|
FCurrentFrame.Parent:=PData;
|
|
FCurrentFrame.Align:=alClient;
|
|
if Assigned(FCurrentData) then
|
|
FCurrentFrame.SetConfig(FCurrentData.Config);
|
|
CBMaster.Enabled:=FCurrentHandler.AllowMasterDetail;
|
|
M:=FCurrentData.Master;
|
|
if (M<>'') and CBMaster.Enabled then
|
|
begin
|
|
CBMaster.ItemIndex:=CBMaster.Items.IndexOf(M);
|
|
end
|
|
else
|
|
CBMaster.ItemIndex:=0;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
|
|
Var
|
|
I : Integer;
|
|
OK : Boolean;
|
|
S : String;
|
|
|
|
begin
|
|
OK:=ModalResult<>mrOK;
|
|
if Not OK then
|
|
begin
|
|
OK:=SaveCurrentItem;
|
|
I:=0;
|
|
if OK then
|
|
begin
|
|
While OK and (I<Data.Count) do
|
|
begin
|
|
S:=Data[i].Check;
|
|
OK:=(S='');
|
|
if OK then
|
|
Inc(I);
|
|
end;
|
|
if not OK then
|
|
begin
|
|
LBReportData.ItemIndex:=I;
|
|
MessageDlg(SDataNotOK,S,mtError,[mbOK],0);
|
|
end;
|
|
end;
|
|
end;
|
|
CanClose:=OK;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.AAddDataExecute(Sender: TObject);
|
|
|
|
begin
|
|
SaveCurrentItem;
|
|
NewItem(Nil);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.NewItem(CloneFrom : TFPReportDataDefinitionItem);
|
|
|
|
Var
|
|
DOK,VOK : Boolean;
|
|
N : String;
|
|
D : TFPReportDataDefinitionItem;
|
|
I : Integer;
|
|
|
|
begin
|
|
I:=Data.Count;
|
|
Repeat
|
|
Inc(I);
|
|
N:='Data'+IntToStr(I);
|
|
until (Data.FindDataByName(N)=Nil);
|
|
VOK:=False;
|
|
Repeat
|
|
DOK:=InputQuery(SErrNewData,SNameNewData+sLineBreak+SAllowedChars1+sLineBreak+SAllowedChars2,N);
|
|
if not DOK then
|
|
VOK:=False
|
|
else
|
|
begin
|
|
VOK:=IsValidIdent(N);
|
|
if not VOK then
|
|
ShowMessage(Format(SErrIllegalDataName,[N]))
|
|
else
|
|
begin
|
|
VOK:=(Data.IndexOfName(N)=-1);
|
|
if not VOK then
|
|
ShowMessage(Format(SWarnDuplicateDataName,[N]));
|
|
end;
|
|
end;
|
|
Until VOK or not DOK;
|
|
if (VOK and DOK) then
|
|
begin
|
|
if CloneFrom<>Nil then
|
|
D:=CloneFrom.Clone(N)
|
|
else
|
|
begin
|
|
D:=Data.AddData(N);
|
|
D.DataType:='';
|
|
end;
|
|
I:=LBReportData.Items.AddObject(N,D);
|
|
LBReportData.ItemIndex:=I;
|
|
if (FCurrentData<>D) then
|
|
begin
|
|
FCurrentData:=D;
|
|
ShowSelectedItem;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ADeleteDataExecute(Sender: TObject);
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
if FCurrentData=Nil then exit;
|
|
I:=LBReportData.Items.IndexOfObject(FCurrentData);
|
|
FreeAndNil(FCurrentData);
|
|
if I<>-1 then
|
|
begin
|
|
LBReportData.Items.Delete(I);
|
|
if (I>=LBReportData.Items.Count) then
|
|
I:=LBReportData.Items.Count-1;
|
|
end;
|
|
// Will trigger OnSelectionChange
|
|
LBReportData.ItemIndex:=I;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ADeleteDataUpdate(Sender: TObject);
|
|
begin
|
|
(Sender as TAction).Enabled:=(FCurrentData<>Nil);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ADuplicateExecute(Sender: TObject);
|
|
begin
|
|
SaveCurrentItem;
|
|
NewItem(FCurrentData);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ADuplicateUpdate(Sender: TObject);
|
|
begin
|
|
(Sender as TAction).Enabled:=(FCurrentData<>Nil);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.APreviewExecute(Sender: TObject);
|
|
|
|
Var
|
|
C : TJSONObject;
|
|
S : String;
|
|
F : TBaseReportDataPreviewForm;
|
|
|
|
begin
|
|
S:=FCurrentFrame.SaveNotOKMessage;
|
|
if (S<>'') then
|
|
begin
|
|
MessageDlg(SDataNotOK,S,mtError,[mbOK],0);
|
|
exit;
|
|
end;
|
|
C:=TJSONObject.Create;
|
|
try
|
|
FCurrentFrame.GetConfig(C);
|
|
S:=FCurrentHandler.CheckConfig(C);
|
|
if (S<>'') then
|
|
begin
|
|
MessageDlg(SDataNotOK,S,mtError,[mbOK],0);
|
|
exit;
|
|
end;
|
|
F:=ReportDataPreviewClass.Create(Self);
|
|
F.PreviewDataset:=FCurrentHandler.CreateDataset(F,C);
|
|
F.Show;
|
|
finally
|
|
C.Free;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.APreviewUpdate(Sender: TObject);
|
|
begin
|
|
(Sender as TAction).Enabled:=Assigned(ReportDataPreviewClass) and (FCurrentData<>Nil) and (FCurrentFrame<>Nil) and (FCurrentHandler<>Nil);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.CBMasterChange(Sender: TObject);
|
|
|
|
Var
|
|
D : String;
|
|
|
|
begin
|
|
if CBMaster.ItemIndex<0 then
|
|
exit;
|
|
D:=CBMaster.Text;
|
|
if (D<>'') and (D<>SNone) then
|
|
Data.CheckCircularReference(D,FCurrentData);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.FormDestroy(Sender: TObject);
|
|
begin
|
|
FreeAndNil(FCurrentHandler);
|
|
FreeAndNil(FCurrentFrame);
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.LBReportDataSelectionChange(Sender: TObject; User: boolean);
|
|
|
|
Var
|
|
D : TFPReportDataDefinitionItem;
|
|
|
|
begin
|
|
SaveCurrentItem;
|
|
if LBReportData.ItemIndex=-1 then
|
|
D:=Nil
|
|
else
|
|
D:=(LBReportData.Items.Objects[LBReportData.ItemIndex] as TFPReportDataDefinitionItem);
|
|
if D<>FCurrentData then
|
|
begin
|
|
FCurrentData:=D;
|
|
ShowSelectedItem;
|
|
end;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.SetData(AValue: TFPReportDataDefinitions);
|
|
begin
|
|
if Data=AValue then Exit;
|
|
Inherited;
|
|
ShowData;
|
|
end;
|
|
|
|
Function TReportDataConfigForm.SaveCurrentItem : Boolean;
|
|
|
|
Var
|
|
S : String;
|
|
|
|
begin
|
|
Result:=True;
|
|
If Not Assigned(FCurrentData) then
|
|
exit;
|
|
If Not Assigned(FCurrentFrame) then
|
|
exit;
|
|
S:=FCurrentFrame.SaveNotOKMessage;
|
|
Result:=(S='');
|
|
if not Result then
|
|
begin
|
|
ShowMessage(S);
|
|
Exit;
|
|
end;
|
|
// This can raise an exception. Catch it, and restore old name
|
|
|
|
try
|
|
FCurrentData.Name:=EName.Text;
|
|
except
|
|
On E : Exception do
|
|
begin
|
|
Application.ShowException(E);
|
|
EName.Text:=FCurrentData.Name;
|
|
end;
|
|
end;
|
|
FCurrentData.DataType:=CBType.text;
|
|
if (FCurrentData.DataType<>'') then
|
|
begin
|
|
if not Assigned(FCurrentFrame) then
|
|
Raise Exception.Create('Internal error : No config frame');
|
|
FCurrentData.Config.Clear;
|
|
FCurrentFrame.GetConfig(FCurrentData.Config);
|
|
end;
|
|
S:='';
|
|
if CBMaster.Enabled then
|
|
S:=CBMaster.Text;
|
|
if (S='') or (S=SNone) then
|
|
FCurrentData.Master:=''
|
|
else
|
|
FCurrentData.Master:=S;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ShowSelectedItem;
|
|
|
|
Var
|
|
haveItem : Boolean;
|
|
|
|
begin
|
|
HaveItem:=Assigned(FCurrentData);
|
|
EName.Enabled:=HaveItem;
|
|
CBType.Enabled:=HaveItem;
|
|
if Not HaveItem then
|
|
begin
|
|
EName.Text:='';
|
|
CBType.ItemIndex:=-1;
|
|
end
|
|
else
|
|
begin
|
|
EName.Text:=FCurrentData.Name;
|
|
// Will trigger change
|
|
CBType.ItemIndex:=CBType.Items.IndexOf(FCurrentData.DataType);
|
|
end;
|
|
ShowDataFrame;
|
|
end;
|
|
|
|
procedure TReportDataConfigForm.ShowData;
|
|
|
|
Var
|
|
I : Integer;
|
|
S : TFPReportDataDefinitionItem;
|
|
|
|
begin
|
|
LBReportData.Items.Clear;
|
|
CBMaster.Items.Clear;
|
|
CBMaster.Items.AddObject(SNone,nil);
|
|
if Not Assigned(Data) then
|
|
exit;
|
|
For I:=0 to Data.Count-1 do
|
|
begin
|
|
S:=Data[i];
|
|
LBReportData.Items.AddObject(S.Name,S);
|
|
CBMaster.Items.AddObject(S.Name,S);
|
|
end;
|
|
if Data.Count>0 then
|
|
LBReportData.ItemIndex:=0
|
|
else
|
|
LBReportData.ItemIndex:=-1;
|
|
end;
|
|
|
|
initialization
|
|
ReportDataFormClass:=TReportDataConfigForm;
|
|
end.
|
|
|