Componentes.Terceros.RemObj.../internal/5.0.24.615/1/Data Abstract for Delphi/Source/uDAReconcileDialog.pas

320 lines
10 KiB
ObjectPascal

unit uDAReconcileDialog;
{----------------------------------------------------------------------------}
{ Data Abstract Library - Core Library }
{ }
{ compiler: Delphi 6 and up, Kylix 3 and up }
{ platform: Win32, Linux }
{ }
{ (c)opyright RemObjects Software. all rights reserved. }
{ }
{ Using this code requires a valid license of the Data Abstract }
{ which can be obtained at http://www.remobjects.com. }
{----------------------------------------------------------------------------}
{$I DataAbstract.inc}
interface
uses
Windows, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, uDADelta, uDADatatable, ComCtrls,
{$IFDEF FPC} buttons,LResources,{$ENDIF}
uDARemoteDataAdapter, ImgList;
type
TReconcileDialogForm = class(TForm)
SkipButton: TButton;
CancelButton: TButton;
SkipAllButton: TButton;
CancelAllButton: TButton;
ShowDetailButton: TButton;
lMessageError: TLabel;
TreeView: TTreeView;
ImageList: TImageList;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
btn_Cancel: TButton;
procedure SkipButtonClick(Sender: TObject);
procedure CancelButtonClick(Sender: TObject);
procedure SkipAllButtonClick(Sender: TObject);
procedure CancelAllButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ShowDetailButtonClick(Sender: TObject);
procedure ListBoxClick(Sender: TObject);
private
{ Private declarations }
ChangeList: TList;
TableList: TList;
RDA: TDARemoteDataAdapter;
procedure CancelChange(aNode: TTreeNode);
procedure SkipChange(aNode: TTreeNode);
procedure SkipAllChanges;
procedure CancelAllChanges;
procedure Setup;
function FindDatatable(ADelta: IDADelta): TDADatatable;
procedure DeleteNodeFromTreeView(aNode: TTreeNode);
end;
var
ReconcileDialogForm: TReconcileDialogForm;
procedure ReconcileDialog(RemoteDataAdapter: TDARemoteDataAdapter; var AFailedDeltaList: TList; aTableList: TList);
implementation
uses
uDAReconcileDialogDetails, uDAInterfaces;
{$IFNDEF FPC}
{$R *.dfm}
{$ENDIF}
procedure ReconcileDialog(RemoteDataAdapter: TDARemoteDataAdapter; var AFailedDeltaList: TList; aTableList: TList);
begin
with TReconcileDialogForm.Create(Application) do try
RDA:=RemoteDataAdapter;
ChangeList.Assign(AFailedDeltaList);
TableList.Assign(aTableList);
Setup;
ShowModal;
AFailedDeltaList.Assign(ChangeList);
finally
Release;
end;
end;
procedure TReconcileDialogForm.SkipButtonClick(Sender: TObject);
begin
SkipChange(TreeView.Selected);
end;
procedure TReconcileDialogForm.CancelButtonClick(Sender: TObject);
begin
CancelChange(TreeView.Selected);
end;
procedure TReconcileDialogForm.SkipAllButtonClick(Sender: TObject);
begin
SkipAllChanges;
end;
procedure TReconcileDialogForm.CancelAllButtonClick(Sender: TObject);
begin
CancelAllChanges;
end;
procedure TReconcileDialogForm.CancelAllChanges;
begin
if Application.MessageBox('Do you want cancel all changes?', 'Cancel All', MB_YESNO) = IDYES then begin
while TreeView.Items.Count > 0 do
CancelChange(TreeView.Items[0]);
ModalResult := mrOk;
end;
end;
procedure TReconcileDialogForm.SkipAllChanges;
begin
if Application.MessageBox('Do you want skip all changes?', 'Skip All', MB_YESNO) = IDYES then
ModalResult := mrOk;
end;
procedure TReconcileDialogForm.FormCreate(Sender: TObject);
begin
inherited;
ChangeList := TList.Create;
TableList := TList.Create;
end;
procedure TReconcileDialogForm.FormDestroy(Sender: TObject);
begin
ChangeList.Free;
TableList.Free;
inherited;
end;
procedure TReconcileDialogForm.ShowDetailButtonClick(Sender: TObject);
var
lChange: TDADeltaChange;
lHandled: Boolean;
lAction: TDAReconcileDialogAction;
begin
lChange := TDADeltaChange(Treeview.Selected.Data);
Hide;
try
lAction:= rdlgNone;
lHandled:=False;
if Assigned(rda) and Assigned(rda.OnShowReconcileRecordInAppUI) then
rda.OnShowReconcileRecordInAppUI(RDA, lChange, FindDatatable(lChange.Delta),lHandled,lAction);
if not lHandled then
ReconcileDialogShowDetails(lChange, FindDatatable(lChange.Delta), Treeview.Selected.Text, lAction);
finally
Show;
end;
if lAction = rdlgSkip then SkipButton.Click
else if lAction = rdlgCancel then CancelButton.Click;
end;
procedure TReconcileDialogForm.Setup;
var
i, j: integer;
change: TDADeltaChange;
anode: TTreeNode;
s: string;
begin
TreeView.Items.Clear;
for i := 0 to ChangeList.Count - 1 do begin
change := TDADeltaChange(ChangeList[i]);
s := change.Delta.LogicalName + ':';
for j := 0 to change.Delta.KeyFieldCount - 1 do begin
if j > 0 then s := s + ';';
if change.ChangeType = ctDelete then
s := s + VarToStr(change.OldValueByName[change.Delta.KeyFieldNames[j]])
else
s := s + VarToStr(change.NewValueByName[change.Delta.KeyFieldNames[j]]);
end;
anode := TreeView.Items.AddChildObject(nil, s, Change);
case Change.ChangeType of
ctInsert: aNode.StateIndex := 2;
ctUpdate: aNode.StateIndex := 3;
ctDelete: aNode.StateIndex := 4;
end;
end;
if TreeView.Items.Count > 0 then begin
TreeView.Items[0].Selected := True;
ListBoxClick(TreeView);
end;
end;
procedure TReconcileDialogForm.CancelChange(aNode: TTreeNode);
procedure DeleteChangeFromTreeView(aChange: TDADeltaChange);
var
i: integer;
begin
for i := TreeView.Items.Count - 1 downto 0 do
if TreeView.Items[i].Data = aChange then begin
TreeView.Items[i].Delete;
Break;
end;
end;
var
lTable: TDADatatable;
details: TList;
detailChange: TDADeltaChange;
i, j, k: integer;
ChangePKValueArray: array of Variant;
lNeedDeleteChange: boolean;
keyvalue: variant;
aChange: TDADeltaChange;
begin
aChange := TDADeltaChange(ANode.Data);
if aChange <> nil then begin
ChangeList.Remove(aChange);
lTable := FindDatatable(aChange.Delta);
if lTable <> nil then begin
// remove changes for detail tables
details := lTable.GetDetailTablesforApplyUpdate;
try
if Details.Count > 0 then begin
SetLength(ChangePKValueArray, aChange.Delta.KeyFieldCount);
for i := 1 to aChange.Delta.KeyFieldCount do begin
if aChange.ChangeType = ctInsert then
keyvalue := aChange.NewValueByName[aChange.Delta.KeyFieldNames[i - 1]]
else
keyvalue := aChange.OldValueByName[aChange.Delta.KeyFieldNames[i - 1]];
ChangePKValueArray[0] := keyvalue;
end;
for i := 0 to details.Count - 1 do begin
for j := 0 to TDADataTable(details[i]).Delta.Count - 1 do begin
detailChange := TDADataTable(details[i]).Delta.Changes[j];
if detailChange.Status <> csResolved then begin
lNeedDeleteChange := True;
for k := 0 to aChange.Delta.KeyFieldCount - 1 do begin
if detailChange.ChangeType = ctInsert then
keyvalue := detailChange.NewValueByName[aChange.Delta.KeyFieldNames[k]]
else
keyvalue := detailChange.oldValueByName[aChange.Delta.KeyFieldNames[k]];
if not VarSameValue(keyValue, ChangePKValueArray[k]) then begin
lNeedDeleteChange := False;
Break;
end;
end;
if lNeedDeleteChange then DeleteChangeFromTreeView(detailChange);
end;
end;
end;
end;
finally
details.Free;
end;
DeleteNodeFromTreeView(aNode);
lTable.CancelUpdateChange(aChange);
end;
end;
if Treeview.Items.Count = 0 then ModalResult := MrOk;
end;
procedure TReconcileDialogForm.SkipChange(aNode: TTreeNode);
begin
DeleteNodeFromTreeView(ANode);
if Treeview.Items.Count = 0 then ModalResult := MrOk;
end;
procedure TReconcileDialogForm.ListBoxClick(Sender: TObject);
var
s: string;
change: TDADeltaChange;
i: integer;
begin
if Treeview.Selected <> nil then begin
change := TDADeltaChange(Treeview.Selected.Data);
s := 'A problem occured while ';
case change.ChangeType of
ctInsert: s := s + 'inserting';
ctUpdate: s := s + 'updating';
ctDelete: s := s + 'deleting';
end;
s := s + ' a record in table "' + change.Delta.LogicalName + '", record "';
for i := 1 to Change.Delta.KeyFieldCount do begin
if i <> 1 then s := s + ';';
if Change.ChangeType = ctInsert then
s := s + VarToStr(Change.NewValueByName[Change.Delta.KeyFieldNames[i - 1]])
else
s := s + VarToStr(Change.OldValueByName[Change.Delta.KeyFieldNames[i - 1]]);
end;
s := s + '"'+ sLineBreak + sLineBreak + change.Message;
if Assigned(RDA) and Assigned(RDA.OnGenerateRecordMessage) then RDA.OnGenerateRecordMessage(RDA, change,FindDatatable(change.Delta),s);
lMessageError.Caption:=s;
end;
end;
function TReconcileDialogForm.FindDatatable(ADelta: IDADelta): TDADatatable;
var
i: integer;
begin
Result := nil;
for i := 0 to TableList.Count - 1 do
if AnsiSameText(ADelta.LogicalName, TDADatatable(TableList[i]).LogicalName) then begin
Result := TDADatatable(TableList[i]);
Break;
end;
end;
procedure TReconcileDialogForm.DeleteNodeFromTreeView(aNode: TTreeNode);
begin
aNode.Delete;
ListBoxClick(TreeView);
end;
{$IFDEF FPC}
initialization
{$I uDAReconcileDialog.lrs}
{$ENDIF}
end.