git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@26 05c56307-c608-d34a-929d-697000501d7a
866 lines
27 KiB
ObjectPascal
866 lines
27 KiB
ObjectPascal
|
|
{********************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressEditors }
|
|
{ }
|
|
{ Copyright (c) 1998-2008 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSEDITORS AND ALL }
|
|
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{********************************************************************}
|
|
|
|
unit cxDBLookupEdit;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
Variants,
|
|
{$ENDIF}
|
|
Messages, Controls,
|
|
SysUtils, Classes, DB,
|
|
cxClasses, cxContainer, cxEdit, cxDBEdit, cxEditConsts,
|
|
cxDB, cxDataUtils, cxDataStorage, cxCustomData, cxDBData, cxDropDownEdit, cxLookupEdit;
|
|
|
|
type
|
|
TcxCustomDBLookupEditProperties = class;
|
|
|
|
{ TcxCustomDBLookupEditLookupData }
|
|
|
|
TcxCustomDBLookupEditLookupData = class(TcxCustomLookupEditLookupData)
|
|
private
|
|
function GetDataController: TcxDBDataController;
|
|
function GetProperties: TcxCustomDBLookupEditProperties;
|
|
protected
|
|
procedure DoSetCurrentKey(ARecordIndex: Integer); override;
|
|
procedure DoSyncGrid; override;
|
|
property DataController: TcxDBDataController read GetDataController;
|
|
property Properties: TcxCustomDBLookupEditProperties read GetProperties;
|
|
end;
|
|
|
|
{ TcxCustomDBLookupEditProperties }
|
|
|
|
TcxCustomDBLookupEditProperties = class(TcxCustomLookupEditProperties)
|
|
private
|
|
FCaseSensitiveSearch: Boolean;
|
|
FLockGridModeCount: Integer;
|
|
FLookupField: TField;
|
|
FLookupList: TcxLookupList;
|
|
FLookupSource: TDataSource;
|
|
FLookupSourceFreeNotificator: TcxFreeNotificator;
|
|
FSyncLookup: Boolean;
|
|
function GetIsUseLookupList: Boolean;
|
|
function GetKeyFieldNames: string;
|
|
function GetListField: TField;
|
|
function GetListFieldIndex: Integer;
|
|
function GetListFieldNames: string;
|
|
procedure SetIsUseLookupList(Value: Boolean);
|
|
procedure SetKeyFieldNames(const Value: string);
|
|
procedure SetListFieldIndex(Value: Integer);
|
|
procedure SetListFieldNames(const Value: string);
|
|
protected
|
|
// DBLookupGrid methods
|
|
procedure DBLookupGridBeginUpdate; virtual;
|
|
procedure DBLookupGridCheckColumnByFieldName(const AFieldName: string); virtual; // if a column does not exist, then create it with zero index
|
|
procedure DBLookupGridCreateColumnsByFieldNames(const AFieldNames: string); virtual;
|
|
procedure DBLookupGridEndUpdate; virtual;
|
|
function GetDBLookupGridColumnField(AIndex: Integer): TField; virtual;
|
|
function GetDBLookupGridColumnFieldName(AIndex: Integer): string; virtual;
|
|
function GetDBLookupGridColumnIndexByFieldName(const AFieldName: string): Integer; virtual;
|
|
function GetDBLookupGridDataController: TcxDBDataController; virtual;
|
|
|
|
function CanDisplayArbitraryEditValue: Boolean;
|
|
procedure CheckLookup; virtual;
|
|
procedure CheckLookupColumn; virtual;
|
|
procedure CheckLookupList;
|
|
procedure DefaultValuesProviderDestroyed; override;
|
|
procedure DefineByLookupError;
|
|
function FindByText(AItemIndex: Integer; const AText: string; APartialCompare: Boolean): Integer; override;
|
|
function GetDisplayColumnIndex: Integer; override;
|
|
function GetDisplayLookupText(const AKey: TcxEditValue): string; override;
|
|
function GetDefaultHorzAlignment: TAlignment; override;
|
|
function GetDefaultMaxLength: Integer; override;
|
|
function GetIncrementalFiltering: Boolean; override;
|
|
function GetKeyByRecordIndex(ARecordIndex: Integer): Variant;
|
|
class function GetLookupDataClass: TcxInterfacedPersistentClass; override;
|
|
function GetLookupResultFieldName: string;
|
|
function GetNullKey: Variant; override;
|
|
function GetRecordIndexByKey(const AKey: Variant): Integer;
|
|
function IsPickMode: Boolean; override;
|
|
procedure LockDataChanged; override;
|
|
procedure LookupSourceFreeNotification(Sender: TComponent); virtual;
|
|
procedure SetDisplayColumnIndex(Value: Integer); override;
|
|
procedure SetLookupField(ALookupField: TField);
|
|
procedure UnlockDataChanged; override;
|
|
property InSyncLookup: Boolean read FSyncLookup;
|
|
property IsUseLookupList: Boolean read GetIsUseLookupList write SetIsUseLookupList;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure Changed; override;
|
|
class function GetContainerClass: TcxContainerClass; override;
|
|
function GetDataField: TField;
|
|
function GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource; override;
|
|
function GetLookupField: TField;
|
|
function IsLookupField: Boolean; override;
|
|
procedure PrepareDisplayValue(const AEditValue: TcxEditValue;
|
|
var DisplayValue: TcxEditValue; AEditFocused: Boolean); override;
|
|
property CaseSensitiveSearch: Boolean read FCaseSensitiveSearch
|
|
write FCaseSensitiveSearch default False;
|
|
property DataController: TcxDBDataController read GetDBLookupGridDataController;
|
|
property KeyFieldNames: string read GetKeyFieldNames write SetKeyFieldNames;
|
|
property ListField: TField read GetListField;
|
|
property ListFieldNames: string read GetListFieldNames write SetListFieldNames stored False;
|
|
property ListFieldIndex: Integer read GetListFieldIndex write SetListFieldIndex default 0;
|
|
end;
|
|
|
|
{ TcxCustomDBLookupEdit }
|
|
|
|
TcxCustomDBLookupEdit = class(TcxCustomLookupEdit)
|
|
private
|
|
function GetProperties: TcxCustomDBLookupEditProperties;
|
|
function GetActiveProperties: TcxCustomDBLookupEditProperties;
|
|
procedure SetProperties(Value: TcxCustomDBLookupEditProperties);
|
|
protected
|
|
function GetClearValue: TcxEditValue; override;
|
|
function IsValidChar(AChar: Char): Boolean; override;
|
|
function ItemIndexToLookupKey(AItemIndex: Integer): TcxEditValue; override;
|
|
function LookupKeyToEditValue(const AKey: TcxEditValue): TcxEditValue; override;
|
|
function LookupKeyToItemIndex(const AKey: TcxEditValue): Integer; override;
|
|
procedure PopupWindowClosed(Sender: TObject); override;
|
|
procedure PrepareDisplayValue(const AEditValue: TcxEditValue;
|
|
var DisplayValue: TcxEditValue; AEditFocused: Boolean); override;
|
|
public
|
|
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
|
|
property ActiveProperties: TcxCustomDBLookupEditProperties
|
|
read GetActiveProperties;
|
|
property Properties: TcxCustomDBLookupEditProperties read GetProperties
|
|
write SetProperties;
|
|
end;
|
|
|
|
{ TcxDBLookupEditDataBinding }
|
|
|
|
TcxDBLookupEditDataBinding = class(TcxDBTextEditDataBinding)
|
|
protected
|
|
function IsLookupControl: Boolean; override;
|
|
end;
|
|
|
|
function IsLinkedToDataSet(ADataSource: TDataSource{list}; ADataSet: TDataSet{data binding}): Boolean;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
VDBConsts,
|
|
{$ENDIF}
|
|
Contnrs, DBConsts;
|
|
|
|
function IsLinkedToDataSet(ADataSource: TDataSource{list}; ADataSet: TDataSet{data binding}): Boolean;
|
|
var
|
|
AListDataSet: TDataSet;
|
|
begin
|
|
AListDataSet := ADataSource.DataSet;
|
|
Result := True;
|
|
while ADataSet <> nil do
|
|
begin
|
|
if ADataSet = AListDataSet then Exit;
|
|
if (ADataSet.DataSetField <> nil) and
|
|
(ADataSet.DataSetField.DataSet = AListDataSet) then Exit;
|
|
if ADataSet.DataSource = nil then
|
|
Break
|
|
else
|
|
ADataSet := ADataSet.DataSource.DataSet;
|
|
end;
|
|
Result := False;
|
|
end;
|
|
|
|
{ TcxCustomDBLookupEditLookupData }
|
|
|
|
procedure TcxCustomDBLookupEditLookupData.DoSetCurrentKey(ARecordIndex: Integer);
|
|
begin
|
|
FCurrentKey := Properties.GetKeyByRecordIndex(ARecordIndex);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditLookupData.DoSyncGrid;
|
|
begin
|
|
if DataController <> nil then
|
|
try
|
|
Properties.LockDataChanged;
|
|
try
|
|
DataController.LocateByKey(GetCurrentKey);
|
|
finally
|
|
Properties.UnlockDataChanged;
|
|
end;
|
|
except
|
|
on EVariantError do;
|
|
on EDatabaseError do;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditLookupData.GetDataController: TcxDBDataController;
|
|
begin
|
|
Result := Properties.DataController;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditLookupData.GetProperties: TcxCustomDBLookupEditProperties;
|
|
begin
|
|
Result := TcxCustomDBLookupEditProperties(inherited Properties);
|
|
end;
|
|
|
|
{ TcxCustomDBLookupEditProperties }
|
|
|
|
destructor TcxCustomDBLookupEditProperties.Destroy;
|
|
begin
|
|
SetLookupField(nil);
|
|
FreeAndNil(FLookupSourceFreeNotificator);
|
|
FLookupList.Free;
|
|
FLookupList := nil;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxCustomDBLookupEditProperties then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
inherited Assign(Source);
|
|
CaseSensitiveSearch := TcxCustomDBLookupEditProperties(Source).CaseSensitiveSearch;
|
|
if not IsDefinedByLookup then
|
|
KeyFieldNames := TcxCustomDBLookupEditProperties(Source).KeyFieldNames;
|
|
finally
|
|
EndUpdate;
|
|
end
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.Changed;
|
|
begin
|
|
CheckLookupList;
|
|
CheckLookup;
|
|
CheckLookupColumn;
|
|
inherited Changed;
|
|
end;
|
|
|
|
class function TcxCustomDBLookupEditProperties.GetContainerClass: TcxContainerClass;
|
|
begin
|
|
Result := TcxCustomDBLookupEdit;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDataField: TField;
|
|
var
|
|
ADefaultValuesProvider: TcxCustomEditDefaultValuesProvider;
|
|
begin
|
|
Result := nil;
|
|
if IDefaultValuesProvider <> nil then
|
|
begin
|
|
ADefaultValuesProvider := TcxCustomEditDefaultValuesProvider(IDefaultValuesProvider.GetInstance);
|
|
if ADefaultValuesProvider is TcxCustomDBEditDefaultValuesProvider then
|
|
Result := TcxCustomDBEditDefaultValuesProvider(ADefaultValuesProvider).Field;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource;
|
|
begin
|
|
if GetLookupField <> nil then
|
|
begin
|
|
if AEditFocused then
|
|
Result := evsKey
|
|
else
|
|
Result := evsText;
|
|
end
|
|
else
|
|
Result := inherited GetEditValueSource(AEditFocused);
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetLookupField: TField;
|
|
begin
|
|
Result := GetDataField;
|
|
if (Result <> nil) and (not Result.Lookup or (csDestroying in Result.ComponentState)) then
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.IsLookupField: Boolean;
|
|
begin
|
|
Result := GetLookupField <> nil;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.PrepareDisplayValue(
|
|
const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue;
|
|
AEditFocused: Boolean);
|
|
begin
|
|
if CanDisplayArbitraryEditValue and (DropDownListStyle <> lsEditList) and
|
|
not AEditFocused then
|
|
DisplayValue := VarToStr(AEditValue)
|
|
else
|
|
inherited PrepareDisplayValue(AEditValue, DisplayValue, AEditFocused);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.DBLookupGridBeginUpdate;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.DBLookupGridCheckColumnByFieldName(const AFieldName: string);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.DBLookupGridCreateColumnsByFieldNames(const AFieldNames: string);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.DBLookupGridEndUpdate;
|
|
begin
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDBLookupGridColumnField(AIndex: Integer): TField;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDBLookupGridColumnFieldName(AIndex: Integer): string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDBLookupGridColumnIndexByFieldName(const AFieldName: string): Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDBLookupGridDataController: TcxDBDataController;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.CanDisplayArbitraryEditValue: Boolean;
|
|
var
|
|
AKeyField: TField;
|
|
begin
|
|
Result := False; // TODO: method in DataController?
|
|
if (KeyFieldNames <> '') and not IsMultipleFieldNames(KeyFieldNames) and
|
|
(DataController <> nil) and (DataController.DataSet <> nil) then
|
|
begin
|
|
AKeyField := DataController.DataSet.FindField(KeyFieldNames);
|
|
if AKeyField <> nil then
|
|
Result := (AKeyField = GetListField) and
|
|
((DropDownListStyle = lsEditList) or (AKeyField is TStringField));
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.CheckLookup;
|
|
|
|
procedure CheckListSource;
|
|
var
|
|
AField: TField;
|
|
begin
|
|
AField := GetDataField;
|
|
if Assigned(AField) and Assigned(DataController) and Assigned(DataController.DataSource) and
|
|
// AField.DataSet.IsLinkedTo(DataController.DataSource) then
|
|
IsLinkedToDataSet(DataController.DataSource, AField.DataSet) then
|
|
DatabaseError(SCircularDataLink);
|
|
end;
|
|
|
|
begin
|
|
SetLookupField(GetLookupField);
|
|
CheckListSource;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.CheckLookupColumn;
|
|
var
|
|
AFieldName: string;
|
|
begin
|
|
AFieldName := GetLookupResultFieldName;
|
|
if AFieldName <> '' then
|
|
DBLookupGridCheckColumnByFieldName(AFieldName);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.CheckLookupList;
|
|
begin
|
|
if FLookupList <> nil then
|
|
FLookupList.Clear;
|
|
if (DataController <> nil) then
|
|
DataController.DataModeController.GridMode := IsUseLookupList;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.DefaultValuesProviderDestroyed;
|
|
begin
|
|
inherited DefaultValuesProviderDestroyed;
|
|
BeginUpdate;
|
|
try
|
|
Changed;
|
|
finally
|
|
EndUpdate(False);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.DefineByLookupError;
|
|
begin
|
|
DatabaseError(SPropDefByLookup);
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.IsPickMode: Boolean;
|
|
begin
|
|
Result := (DropDownListStyle = lsEditList) and CanDisplayArbitraryEditValue;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.LockDataChanged;
|
|
begin
|
|
inherited LockDataChanged;
|
|
// TODO: if GridMode
|
|
if (DataController <> nil) and DataController.IsGridMode then
|
|
Inc(FLockGridModeCount);
|
|
if FLockGridModeCount <> 0 then
|
|
DataController.LockGridModeNotify;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.LookupSourceFreeNotification(Sender: TComponent);
|
|
begin
|
|
CheckLookup;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.SetDisplayColumnIndex(Value: Integer);
|
|
begin
|
|
if IsDefinedByLookup and not FSyncLookup then
|
|
DefineByLookupError;
|
|
inherited SetDisplayColumnIndex(Value);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.SetLookupField(ALookupField: TField);
|
|
begin
|
|
if FLookupField <> ALookupField then
|
|
begin
|
|
FLookupField := ALookupField;
|
|
if FLookupField <> nil then
|
|
begin
|
|
// Lookup Source
|
|
if FLookupSource = nil then
|
|
FLookupSource := TDataSource.Create(nil);
|
|
|
|
FreeAndNil(FLookupSourceFreeNotificator);
|
|
FLookupSourceFreeNotificator := TcxFreeNotificator.Create(nil);
|
|
FLookupSourceFreeNotificator.OnFreeNotification := LookupSourceFreeNotification;
|
|
FLookupSourceFreeNotificator.AddSender(FLookupField);
|
|
|
|
FLookupSource.DataSet := FLookupField.LookupDataSet;
|
|
// Sync Lookup Data
|
|
if DataController <> nil then
|
|
begin
|
|
FSyncLookup := True;
|
|
try
|
|
// if DataController.DataSet <> FLookupSource.DataSet then // SC DB11573
|
|
DataController.DataSource := FLookupSource;
|
|
if GetDBLookupGridColumnIndexByFieldName(FLookupField.LookupResultField) = -1 then
|
|
ListFieldNames := FLookupField.LookupResultField;
|
|
KeyFieldNames := FLookupField.LookupKeyFields;
|
|
ListFieldIndex := 0;
|
|
finally
|
|
FSyncLookup := False;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
FreeAndNil(FLookupSourceFreeNotificator);
|
|
FreeAndNil(FLookupSource);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.UnlockDataChanged;
|
|
begin
|
|
if FLockGridModeCount <> 0 then
|
|
begin
|
|
if DataController <> nil then
|
|
DataController.UnlockGridModeNotify;
|
|
Dec(FLockGridModeCount);
|
|
end;
|
|
inherited UnlockDataChanged;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.FindByText(AItemIndex: Integer;
|
|
const AText: string; APartialCompare: Boolean): Integer;
|
|
|
|
function GetLocateOptions: TLocateOptions;
|
|
begin
|
|
Result := [];
|
|
if not CaseSensitiveSearch then
|
|
Include(Result, loCaseInsensitive);
|
|
if APartialCompare then
|
|
Result := Result + [loPartialKey];
|
|
end;
|
|
|
|
function GetLocateValue: Variant;
|
|
begin
|
|
Result := AText;
|
|
// TDataSet.Locate does not work with empty strings passed as key values for numeric fields
|
|
if (AText = '') and not (DataController.GetItemField(AItemIndex) is TStringField) then
|
|
Result := Null;
|
|
end;
|
|
|
|
var
|
|
ADataSet: TDataSet;
|
|
AListFieldName: string;
|
|
begin
|
|
if not IsUseLookupList then
|
|
begin
|
|
Result := inherited FindByText(AItemIndex, AText, APartialCompare);
|
|
Exit;
|
|
end;
|
|
|
|
Result := -1;
|
|
LockDataChanged;
|
|
try
|
|
ADataSet := DataController.DataSet;
|
|
AListFieldName := DataController.GetItemFieldName(AItemIndex);
|
|
try
|
|
if (ADataSet <> nil) and ADataSet.Active and (AItemIndex <> -1) and
|
|
ADataSet.Locate(AListFieldName, GetLocateValue, GetLocateOptions) then
|
|
Result := DataController.GetFocusedRecordIndex;
|
|
except
|
|
on EDatabaseError do;
|
|
on EVariantError do;
|
|
end;
|
|
finally
|
|
UnlockDataChanged;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDisplayColumnIndex: Integer;
|
|
var
|
|
AFieldName: string;
|
|
begin
|
|
AFieldName := GetLookupResultFieldName;
|
|
if AFieldName <> '' then
|
|
Result := GetDBLookupGridColumnIndexByFieldName(AFieldName)
|
|
else
|
|
Result := inherited GetDisplayColumnIndex;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDisplayLookupText(const AKey: TcxEditValue): string;
|
|
var
|
|
ARecordIndex: Integer;
|
|
AItemIndex: Integer;
|
|
ADataSet: TDataSet;
|
|
begin
|
|
Result := '';
|
|
AItemIndex := GetListIndex;
|
|
if (AItemIndex <> -1) and (DataController <> nil) then
|
|
begin
|
|
if IsUseLookupList then
|
|
begin
|
|
|
|
// TODO: proc?
|
|
if FLookupList.Find(AKey, ARecordIndex) then
|
|
Result := FLookupList[ARecordIndex]^.DisplayText
|
|
else
|
|
begin
|
|
ADataSet := DataController.DataSet;
|
|
LockDataChanged;
|
|
try
|
|
if (ADataSet <> nil) and ADataSet.Active and (ListField <> nil) and
|
|
CanCallDataSetLocate(DataController.DataSet, KeyFieldNames, AKey) and
|
|
ADataSet.Locate(KeyFieldNames, AKey, []) then
|
|
Result := ListField.AsString {ListField.DisplayText}
|
|
else
|
|
Result := '';
|
|
finally
|
|
UnlockDataChanged;
|
|
end;
|
|
FLookupList.Insert(ARecordIndex, AKey, Result);
|
|
end;
|
|
|
|
end
|
|
else
|
|
begin
|
|
ARecordIndex := GetRecordIndexByKey(AKey);
|
|
if ARecordIndex <> -1 then
|
|
Result := DataController.DisplayTexts[ARecordIndex, AItemIndex];
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDefaultHorzAlignment: TAlignment;
|
|
begin
|
|
if ListField <> nil then
|
|
Result := ListField.Alignment
|
|
else
|
|
Result := inherited GetDefaultHorzAlignment;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetDefaultMaxLength: Integer;
|
|
begin
|
|
if ListField <> nil then
|
|
Result := ListField.Size
|
|
else
|
|
Result := inherited GetDefaultMaxLength;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetIncrementalFiltering: Boolean;
|
|
begin
|
|
if IsUseLookupList then
|
|
Result := False
|
|
else
|
|
Result := inherited GetIncrementalFiltering;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetKeyByRecordIndex(ARecordIndex: Integer): Variant;
|
|
begin
|
|
if (ARecordIndex <> -1) and (DataController <> nil) then
|
|
Result := DataController.GetRecordId(ARecordIndex)
|
|
else
|
|
Result := Null;
|
|
end;
|
|
|
|
class function TcxCustomDBLookupEditProperties.GetLookupDataClass: TcxInterfacedPersistentClass;
|
|
begin
|
|
Result := TcxCustomDBLookupEditLookupData;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetLookupResultFieldName: string;
|
|
begin
|
|
if GetLookupField <> nil then
|
|
Result := GetLookupField.LookupResultField
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetNullKey: Variant;
|
|
var
|
|
I, C: Integer;
|
|
begin
|
|
if IsMultipleFieldNames(KeyFieldNames) then
|
|
begin
|
|
C := GetFieldNamesCount(KeyFieldNames);
|
|
Result := VarArrayCreate([0, C - 1], varVariant);
|
|
for I := 0 to C - 1 do
|
|
Result[I] := Null;
|
|
end
|
|
else
|
|
Result := Null;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetRecordIndexByKey(const AKey: Variant): Integer;
|
|
begin
|
|
try
|
|
Result := DataController.FindRecordIndexByKey(AKey);
|
|
except
|
|
on EVariantError do
|
|
Result := -1;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetIsUseLookupList: Boolean;
|
|
begin
|
|
Result := FLookupList <> nil;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetKeyFieldNames: string;
|
|
begin
|
|
if DataController <> nil then
|
|
Result := DataController.KeyFieldNames
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetListField: TField;
|
|
var
|
|
AListIndex: Integer;
|
|
begin
|
|
AListIndex := GetListIndex;
|
|
if AListIndex <> -1 then
|
|
Result := GetDBLookupGridColumnField(AListIndex)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetListFieldIndex: Integer;
|
|
begin
|
|
Result := inherited DisplayColumnIndex;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEditProperties.GetListFieldNames: string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
if GetLookupGridColumnCount > 0 then
|
|
begin
|
|
Result := GetDBLookupGridColumnFieldName(0);
|
|
for I := 1 to GetLookupGridColumnCount - 1 do
|
|
Result := Result + ';' + GetDBLookupGridColumnFieldName(I);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.SetIsUseLookupList(Value: Boolean);
|
|
begin
|
|
if (FLookupList <> nil) <> Value then
|
|
begin
|
|
if Value then
|
|
begin
|
|
FLookupList := TcxLookupList.Create;
|
|
end
|
|
else
|
|
begin
|
|
FLookupList.Free;
|
|
FLookupList := nil;
|
|
end;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.SetKeyFieldNames(const Value: string);
|
|
begin
|
|
if IsDefinedByLookup and not FSyncLookup then
|
|
DefineByLookupError;
|
|
if DataController <> nil then
|
|
DataController.KeyFieldNames := Value;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.SetListFieldIndex(Value: Integer);
|
|
begin
|
|
inherited DisplayColumnIndex := Value;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEditProperties.SetListFieldNames(const Value: string);
|
|
var
|
|
AChanged: Boolean;
|
|
begin
|
|
AChanged := ListFieldNames <> Value;
|
|
DBLookupGridBeginUpdate;
|
|
try
|
|
DBLookupGridCreateColumnsByFieldNames(Value);
|
|
CheckLookupColumn;
|
|
CheckDisplayColumnIndex;
|
|
finally
|
|
DBLookupGridEndUpdate;
|
|
end;
|
|
if AChanged then
|
|
Changed;
|
|
end;
|
|
|
|
{ TcxCustomDBLookupEdit }
|
|
|
|
class function TcxCustomDBLookupEdit.GetPropertiesClass: TcxCustomEditPropertiesClass;
|
|
begin
|
|
Result := TcxCustomDBLookupEditProperties;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.GetClearValue: TcxEditValue;
|
|
|
|
function GetNullArray: Variant;
|
|
var
|
|
AFieldList: TObjectList;
|
|
I: Integer;
|
|
begin
|
|
AFieldList := TObjectList.Create(False);
|
|
try
|
|
ActiveProperties.FLookupSource.DataSet.GetFieldList(AFieldList, ActiveProperties.KeyFieldNames);
|
|
Result := VarArrayCreate([0, AFieldList.Count - 1], varVariant);
|
|
for I := 0 to AFieldList.Count - 1 do
|
|
Result[I] := Null;
|
|
finally
|
|
AFieldList.Free;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if (ActiveProperties.GetEditValueSource(InternalFocused) = evsKey) and
|
|
(Pos(';', ActiveProperties.KeyFieldNames) <> 0) then
|
|
Result := GetNullArray
|
|
else
|
|
Result := inherited GetClearValue;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.IsValidChar(AChar: Char): Boolean;
|
|
begin
|
|
if ActiveProperties.ListField <> nil then
|
|
Result := ActiveProperties.ListField.IsValidChar(AChar)
|
|
else
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.ItemIndexToLookupKey(AItemIndex: Integer): TcxEditValue;
|
|
begin
|
|
Result := ActiveProperties.GetKeyByRecordIndex(AItemIndex);
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.LookupKeyToEditValue(const AKey: TcxEditValue): TcxEditValue;
|
|
begin
|
|
Result := AKey;
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.LookupKeyToItemIndex(const AKey: TcxEditValue): Integer;
|
|
begin
|
|
Result := ActiveProperties.GetRecordIndexByKey(AKey);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEdit.PopupWindowClosed(Sender: TObject);
|
|
begin
|
|
inherited PopupWindowClosed(Sender);
|
|
if ActiveProperties.DataController.DataModeController.SyncMode then
|
|
ILookupData.CurrentKey := EditValue;
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEdit.PrepareDisplayValue(
|
|
const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue;
|
|
AEditFocused: Boolean);
|
|
begin
|
|
if (ActiveProperties.DropDownListStyle <> lsEditList) and not Focused and
|
|
ActiveProperties.CanDisplayArbitraryEditValue then
|
|
DisplayValue := VarToStr(AEditValue)
|
|
else
|
|
ActiveProperties.PrepareDisplayValue(AEditValue, DisplayValue, AEditFocused);
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.GetProperties: TcxCustomDBLookupEditProperties;
|
|
begin
|
|
Result := TcxCustomDBLookupEditProperties(FProperties);
|
|
end;
|
|
|
|
function TcxCustomDBLookupEdit.GetActiveProperties: TcxCustomDBLookupEditProperties;
|
|
begin
|
|
Result := TcxCustomDBLookupEditProperties(InternalGetActiveProperties);
|
|
end;
|
|
|
|
procedure TcxCustomDBLookupEdit.SetProperties(Value: TcxCustomDBLookupEditProperties);
|
|
begin
|
|
FProperties.Assign(Value);
|
|
end;
|
|
|
|
{ TcxDBLookupEditDataBinding }
|
|
|
|
function TcxDBLookupEditDataBinding.IsLookupControl: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
end.
|