git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.SDAC@3 6f543ec7-021b-7e4c-98c9-62eafc7fb9a8
544 lines
14 KiB
ObjectPascal
544 lines
14 KiB
ObjectPascal
|
|
//////////////////////////////////////////////////
|
|
// DB Access Components
|
|
// Copyright @ 1998-2007 Core Lab. All right reserved.
|
|
// CRFldLinks
|
|
//////////////////////////////////////////////////
|
|
|
|
{$I Dac.inc}
|
|
|
|
unit CRFldLinks;
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF LINUX}
|
|
QStdCtrls, QControls, QExtCtrls, QForms,
|
|
{$ELSE}
|
|
StdCtrls, Controls, ExtCtrls, Forms,
|
|
{$ENDIF}
|
|
{$IFDEF VER6P}DesignIntf, DesignEditors,{$ELSE}DsgnIntf,{$ENDIF}
|
|
SysUtils, Classes, DB, Buttons, Windows;
|
|
|
|
type
|
|
|
|
{ TCRFieldLinkProperty }
|
|
|
|
TCRFieldLinkProperty = class(TStringProperty)
|
|
private
|
|
FChanged: Boolean;
|
|
FDataSet: TDataSet;
|
|
protected
|
|
function GetDataSet: TDataSet;
|
|
procedure GetFieldNamesForIndex(List: TStrings); virtual;
|
|
function GetIndexBased: Boolean; virtual;
|
|
function GetIndexDefs: TIndexDefs; virtual;
|
|
function GetIndexFieldNames: string; virtual;
|
|
function GetIndexName: string; virtual;
|
|
function GetMasterFields: string; virtual; abstract;
|
|
procedure SetIndexFieldNames(const Value: string); virtual;
|
|
procedure SetIndexName(const Value: string); virtual;
|
|
procedure SetMasterFields(const Value: string); virtual; abstract;
|
|
public
|
|
constructor CreateWith(ADataSet: TDataSet); virtual;
|
|
procedure GetIndexNames(List: TStrings);
|
|
property IndexBased: Boolean read GetIndexBased;
|
|
property IndexDefs: TIndexDefs read GetIndexDefs;
|
|
property IndexFieldNames: string read GetIndexFieldNames write SetIndexFieldNames;
|
|
property IndexName: string read GetIndexName write SetIndexName;
|
|
property MasterFields: string read GetMasterFields write SetMasterFields;
|
|
property Changed: Boolean read FChanged;
|
|
procedure Edit; override;
|
|
function GetAttributes: TPropertyAttributes; override;
|
|
property DataSet: TDataSet read GetDataSet;
|
|
end;
|
|
|
|
{ TCRLinkFields }
|
|
|
|
TCRLinkFields = class(TForm)
|
|
DetailList: TListBox;
|
|
MasterList: TListBox;
|
|
BindList: TListBox;
|
|
Label30: TLabel;
|
|
Label31: TLabel;
|
|
IndexList: TComboBox;
|
|
IndexLabel: TLabel;
|
|
Label2: TLabel;
|
|
Bevel1: TBevel;
|
|
Bevel2: TBevel;
|
|
AddButton: TButton;
|
|
DeleteButton: TButton;
|
|
ClearButton: TButton;
|
|
Button1: TButton;
|
|
Button2: TButton;
|
|
Help: TButton;
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure BindingListClick(Sender: TObject);
|
|
procedure AddButtonClick(Sender: TObject);
|
|
procedure DeleteButtonClick(Sender: TObject);
|
|
procedure BindListClick(Sender: TObject);
|
|
procedure ClearButtonClick(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure BitBtn1Click(Sender: TObject);
|
|
procedure HelpClick(Sender: TObject);
|
|
procedure IndexListChange(Sender: TObject);
|
|
private
|
|
FDataSet: TDataSet;
|
|
FMasterDataSet: TDataSet;
|
|
FDataSetProxy: TCRFieldLinkProperty;
|
|
FFullIndexName: string;
|
|
MasterFieldList: string;
|
|
IndexFieldList: string;
|
|
OrderedDetailList: TStringList;
|
|
OrderedMasterList: TStringList;
|
|
procedure OrderFieldList(OrderedList, List: TStrings);
|
|
procedure AddToBindList(const Str1, Str2: string);
|
|
procedure Initialize;
|
|
property FullIndexName: string read FFullIndexName;
|
|
procedure SetDataSet(Value: TDataSet);
|
|
public
|
|
property DataSet: TDataSet read FDataSet write SetDataSet;
|
|
property DataSetProxy: TCRFieldLinkProperty read FDataSetProxy write FDataSetProxy;
|
|
function Edit: Boolean;
|
|
end;
|
|
|
|
function EditMasterFields(ADataSet: TDataSet; ADataSetProxy: TCRFieldLinkProperty): Boolean;
|
|
|
|
implementation
|
|
|
|
{$IFDEF IDE}
|
|
{$R *.dfm}
|
|
{$ENDIF}
|
|
{$IFDEF MSWINDOWS}
|
|
{$R CRFldLinks.dfm}
|
|
{$ENDIF}
|
|
{$IFDEF LINUX}
|
|
{$R *.xfm}
|
|
{$ENDIF}
|
|
|
|
uses
|
|
{$IFDEF LINUX}
|
|
QDialogs,
|
|
{$ELSE}
|
|
Dialogs,
|
|
{$IFDEF VER6P}
|
|
DsnDBCst,
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
DBConsts, LibHelp, TypInfo;
|
|
|
|
{ Utility Functions }
|
|
|
|
function StripFieldName(const Fields: string; var Pos: Integer): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := Pos;
|
|
while (I <= Length(Fields)) and (Fields[I] <> ';') do Inc(I);
|
|
Result := Copy(Fields, Pos, I - Pos);
|
|
if (I <= Length(Fields)) and (Fields[I] = ';') then Inc(I);
|
|
Pos := I;
|
|
end;
|
|
|
|
function StripDetail(const Value: string): string;
|
|
var
|
|
S: string;
|
|
I: Integer;
|
|
begin
|
|
S := Value;
|
|
I := 0;
|
|
while Pos('->', S) > 0 do
|
|
begin
|
|
I := Pos('->', S);
|
|
S[I] := ' ';
|
|
end;
|
|
Result := Copy(Value, 0, I - 2);
|
|
end;
|
|
|
|
function StripMaster(const Value: string): string;
|
|
var
|
|
S: string;
|
|
I: Integer;
|
|
begin
|
|
S := Value;
|
|
I := 0;
|
|
while Pos('->', S) > 0 do
|
|
begin
|
|
I := Pos('->', S);
|
|
S[I] := ' ';
|
|
end;
|
|
Result := Copy(Value, I + 3, Length(Value));
|
|
end;
|
|
|
|
function EditMasterFields(ADataSet: TDataSet; ADataSetProxy: TCRFieldLinkProperty): Boolean;
|
|
begin
|
|
with TCRLinkFields.Create(nil) do
|
|
try
|
|
DataSetProxy := ADataSetProxy;
|
|
DataSet := ADataSet;
|
|
Result := Edit;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
{ TCRFieldLinkProperty }
|
|
|
|
function TCRFieldLinkProperty.GetIndexBased: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TCRFieldLinkProperty.GetIndexDefs: TIndexDefs;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TCRFieldLinkProperty.GetIndexFieldNames: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TCRFieldLinkProperty.GetIndexName: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TCRFieldLinkProperty.GetIndexNames(List: TStrings);
|
|
begin
|
|
end;
|
|
|
|
procedure TCRFieldLinkProperty.GetFieldNamesForIndex(List: TStrings);
|
|
begin
|
|
end;
|
|
|
|
procedure TCRFieldLinkProperty.SetIndexFieldNames(const Value: string);
|
|
begin
|
|
end;
|
|
|
|
procedure TCRFieldLinkProperty.SetIndexName(const Value: string);
|
|
begin
|
|
end;
|
|
|
|
function TCRFieldLinkProperty.GetAttributes: TPropertyAttributes;
|
|
begin
|
|
Result := [paDialog];
|
|
{$IFDEF LINUX}
|
|
Result := Result + [paVCL]
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TCRFieldLinkProperty.Edit;
|
|
begin
|
|
FChanged := EditMasterFields(DataSet, Self);
|
|
if FChanged then Modified;
|
|
end;
|
|
|
|
constructor TCRFieldLinkProperty.CreateWith(ADataSet: TDataSet);
|
|
begin
|
|
FDataSet := ADataSet;
|
|
end;
|
|
|
|
function TCRFieldLinkProperty.GetDataSet: TDataSet;
|
|
begin
|
|
if FDataSet = nil then
|
|
FDataSet := TDataSet(GetComponent(0));
|
|
Result := FDataSet;
|
|
end;
|
|
|
|
{ TCRLinkFields }
|
|
|
|
procedure TCRLinkFields.FormCreate(Sender: TObject);
|
|
begin
|
|
OrderedDetailList := TStringList.Create;
|
|
OrderedMasterList := TStringList.Create;
|
|
{$IFDEF LINUX}
|
|
Help.Visible := False;
|
|
{$ELSE}
|
|
{$IFDEF VER6P}
|
|
HelpContext := hcDFieldLinksDesign;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TCRLinkFields.FormDestroy(Sender: TObject);
|
|
begin
|
|
OrderedDetailList.Free;
|
|
OrderedMasterList.Free;
|
|
end;
|
|
|
|
function TCRLinkFields.Edit;
|
|
begin
|
|
Initialize;
|
|
if ShowModal = mrOK then
|
|
begin
|
|
if FullIndexName <> '' then
|
|
DataSetProxy.IndexName := FullIndexName else
|
|
DataSetProxy.IndexFieldNames := IndexFieldList;
|
|
DataSetProxy.MasterFields := MasterFieldList;
|
|
Result := True;
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TCRLinkFields.SetDataSet(Value: TDataSet);
|
|
{$IFDEF LINUX}
|
|
const
|
|
SMissingDataSource = 'Missing MasterSource or DataSource';
|
|
{$ENDIF}
|
|
{$IFNDEF VER6P}
|
|
const
|
|
SMissingDataSource = 'Missing MasterSource or DataSource';
|
|
{$ENDIF}
|
|
var
|
|
IndexDefs: TIndexDefs;
|
|
begin
|
|
Value.FieldDefs.Update;
|
|
IndexDefs := DataSetProxy.IndexDefs;
|
|
if Assigned(IndexDefs) then IndexDefs.Update;
|
|
if not Assigned(Value.DataSource) or not Assigned(Value.DataSource.DataSet) then
|
|
DatabaseError(SMissingDataSource, Value);
|
|
Value.DataSource.DataSet.FieldDefs.Update;
|
|
FDataSet := Value;
|
|
FMasterDataSet := Value.DataSource.DataSet;
|
|
end;
|
|
|
|
procedure TCRLinkFields.Initialize;
|
|
var
|
|
SIndexName: string;
|
|
|
|
procedure SetUpLists(const MasterFieldList, DetailFieldList: string);
|
|
var
|
|
I, J: Integer;
|
|
MasterFieldName, DetailFieldName: string;
|
|
begin
|
|
I := 1;
|
|
J := 1;
|
|
while (I <= Length(MasterFieldList)) and (J <= Length(DetailFieldList)) do
|
|
begin
|
|
MasterFieldName := StripFieldName(MasterFieldList, I);
|
|
DetailFieldName := StripFieldName(DetailFieldList, J);
|
|
if (MasterList.Items.IndexOf(MasterFieldName) <> -1) and
|
|
(OrderedDetailList.IndexOf(DetailFieldName) <> -1) then
|
|
begin
|
|
with OrderedDetailList do
|
|
Objects[IndexOf(DetailFieldName)] := TObject(True);
|
|
with DetailList.Items do Delete(IndexOf(DetailFieldName));
|
|
with MasterList.Items do Delete(IndexOf(MasterFieldName));
|
|
BindList.Items.Add(Format('%s -> %s',
|
|
[DetailFieldName, MasterFieldName]));
|
|
ClearButton.Enabled := True;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if not DataSetProxy.IndexBased then
|
|
begin
|
|
IndexLabel.Visible := False;
|
|
IndexList.Visible := False;
|
|
end
|
|
else with DataSetProxy do
|
|
begin
|
|
GetIndexNames(IndexList.Items);
|
|
if IndexFieldNames <> '' then
|
|
SIndexName := IndexDefs.FindIndexForFields(IndexFieldNames).Name
|
|
else SIndexName := IndexName;
|
|
if (SIndexName <> '') and (IndexList.Items.IndexOf(SIndexName) >= 0) then
|
|
IndexList.ItemIndex := IndexList.Items.IndexOf(SIndexName) else
|
|
IndexList.ItemIndex := 0;
|
|
end;
|
|
with DataSetProxy do
|
|
begin
|
|
MasterFieldList := MasterFields;
|
|
if (IndexFieldNames = '') and (IndexName <> '') and
|
|
(IndexDefs.IndexOf(IndexName) >=0) then
|
|
IndexFieldList := IndexDefs[IndexDefs.IndexOf(IndexName)].Fields else
|
|
IndexFieldList := IndexFieldNames;
|
|
end;
|
|
IndexListChange(nil);
|
|
FMasterDataSet.GetFieldNames(MasterList.Items);
|
|
OrderedMasterList.Assign(MasterList.Items);
|
|
SetUpLists(MasterFieldList, IndexFieldList);
|
|
end;
|
|
|
|
procedure TCRLinkFields.IndexListChange(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
IndexExp: string;
|
|
begin
|
|
DetailList.Items.Clear;
|
|
if DataSetProxy.IndexBased then
|
|
begin
|
|
DataSetProxy.IndexName := IndexList.Text;
|
|
I := DataSetProxy.IndexDefs.IndexOf(DataSetProxy.IndexName);
|
|
if (I <> -1) then IndexExp := DataSetProxy.IndexDefs.Items[I].Expression;
|
|
if IndexExp <> '' then
|
|
DetailList.Items.Add(IndexExp) else
|
|
DataSetProxy.GetFieldNamesForIndex(DetailList.Items);
|
|
end else
|
|
DataSet.GetFieldNames(DetailList.Items);
|
|
MasterList.Items.Assign(OrderedMasterList);
|
|
OrderedDetailList.Assign(DetailList.Items);
|
|
for I := 0 to OrderedDetailList.Count - 1 do
|
|
OrderedDetailList.Objects[I] := TObject(False);
|
|
BindList.Clear;
|
|
AddButton.Enabled := False;
|
|
ClearButton.Enabled := False;
|
|
DeleteButton.Enabled := False;
|
|
MasterList.ItemIndex := -1;
|
|
end;
|
|
|
|
procedure TCRLinkFields.OrderFieldList(OrderedList, List: TStrings);
|
|
var
|
|
I, J: Integer;
|
|
MinIndex, Index, FieldIndex: Integer;
|
|
begin
|
|
for J := 0 to List.Count - 1 do
|
|
begin
|
|
MinIndex := $7FFF;
|
|
FieldIndex := -1;
|
|
for I := J to List.Count - 1 do
|
|
begin
|
|
Index := OrderedList.IndexOf(List[I]);
|
|
if Index < MinIndex then
|
|
begin
|
|
MinIndex := Index;
|
|
FieldIndex := I;
|
|
end;
|
|
end;
|
|
List.Move(FieldIndex, J);
|
|
end;
|
|
end;
|
|
|
|
procedure TCRLinkFields.AddToBindList(const Str1, Str2: string);
|
|
var
|
|
I: Integer;
|
|
NewField: string;
|
|
NewIndex: Integer;
|
|
begin
|
|
NewIndex := OrderedDetailList.IndexOf(Str1);
|
|
NewField := Format('%s -> %s', [Str1, Str2]);
|
|
with BindList.Items do
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
if OrderedDetailList.IndexOf(StripDetail(Strings[I])) > NewIndex then
|
|
begin
|
|
Insert(I, NewField);
|
|
Exit;
|
|
end;
|
|
end;
|
|
Add(NewField);
|
|
end;
|
|
end;
|
|
|
|
procedure TCRLinkFields.BindingListClick(Sender: TObject);
|
|
begin
|
|
AddButton.Enabled := (DetailList.ItemIndex <> LB_ERR) and
|
|
(MasterList.ItemIndex <> LB_ERR);
|
|
end;
|
|
|
|
procedure TCRLinkFields.AddButtonClick(Sender: TObject);
|
|
var
|
|
DetailIndex: Integer;
|
|
MasterIndex: Integer;
|
|
begin
|
|
DetailIndex := DetailList.ItemIndex;
|
|
MasterIndex := MasterList.ItemIndex;
|
|
AddToBindList(DetailList.Items[DetailIndex],
|
|
MasterList.Items[MasterIndex]);
|
|
with OrderedDetailList do
|
|
Objects[IndexOf(DetailList.Items[DetailIndex])] := TObject(True);
|
|
DetailList.Items.Delete(DetailIndex);
|
|
MasterList.Items.Delete(MasterIndex);
|
|
ClearButton.Enabled := True;
|
|
AddButton.Enabled := False;
|
|
end;
|
|
|
|
procedure TCRLinkFields.ClearButtonClick(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
BindValue: string;
|
|
begin
|
|
for I := 0 to BindList.Items.Count - 1 do
|
|
begin
|
|
BindValue := BindList.Items[I];
|
|
DetailList.Items.Add(StripDetail(BindValue));
|
|
MasterList.Items.Add(StripMaster(BindValue));
|
|
end;
|
|
BindList.Clear;
|
|
ClearButton.Enabled := False;
|
|
DeleteButton.Enabled := False;
|
|
OrderFieldList(OrderedDetailList, DetailList.Items);
|
|
DetailList.ItemIndex := -1;
|
|
MasterList.Items.Assign(OrderedMasterList);
|
|
for I := 0 to OrderedDetailList.Count - 1 do
|
|
OrderedDetailList.Objects[I] := TObject(False);
|
|
AddButton.Enabled := False;
|
|
end;
|
|
|
|
procedure TCRLinkFields.DeleteButtonClick(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with BindList do
|
|
begin
|
|
for I := Items.Count - 1 downto 0 do
|
|
begin
|
|
if Selected[I] then
|
|
begin
|
|
DetailList.Items.Add(StripDetail(Items[I]));
|
|
MasterList.Items.Add(StripMaster(Items[I]));
|
|
with OrderedDetailList do
|
|
Objects[IndexOf(StripDetail(Items[I]))] := TObject(False);
|
|
Items.Delete(I);
|
|
end;
|
|
end;
|
|
if Items.Count > 0 then Selected[0] := True;
|
|
DeleteButton.Enabled := Items.Count > 0;
|
|
ClearButton.Enabled := Items.Count > 0;
|
|
OrderFieldList(OrderedDetailList, DetailList.Items);
|
|
DetailList.ItemIndex := -1;
|
|
OrderFieldList(OrderedMasterList, MasterList.Items);
|
|
MasterList.ItemIndex := -1;
|
|
AddButton.Enabled := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TCRLinkFields.BindListClick(Sender: TObject);
|
|
begin
|
|
DeleteButton.Enabled := BindList.ItemIndex <> LB_ERR;
|
|
end;
|
|
|
|
procedure TCRLinkFields.BitBtn1Click(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
MasterFieldList := '';
|
|
IndexFieldList := '';
|
|
FFullIndexName := '';
|
|
with BindList do
|
|
begin
|
|
for I := 0 to Items.Count - 1 do
|
|
begin
|
|
MasterFieldList := Format('%s%s;', [MasterFieldList, StripMaster(Items[I])]);
|
|
IndexFieldList := Format('%s%s;', [IndexFieldList, StripDetail(Items[I])]);
|
|
end;
|
|
if MasterFieldList <> '' then
|
|
SetLength(MasterFieldList, Length(MasterFieldList) - 1);
|
|
if IndexFieldList <> '' then
|
|
SetLength(IndexFieldList, Length(IndexFieldList) - 1);
|
|
end;
|
|
end;
|
|
|
|
procedure TCRLinkFields.HelpClick(Sender: TObject);
|
|
begin
|
|
{$IFNDEF LINUX}
|
|
Application.HelpContext(HelpContext);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
end.
|