lazarus/components/ideintf/dbpropedits.pas
2020-03-23 20:33:04 +00:00

222 lines
6.3 KiB
ObjectPascal

{ Copyright (C) 2004-2013
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Author: Lagunov Aleksey
Abstract:
Property Editors for Database components of FCL and LCL.
}
unit DBPropEdits;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, TypInfo, DB,
// LCL
Dialogs, Forms, DbCtrls, DBGrids,
// IdeIntf
PropEdits, PropEditUtils, ComponentEditors, DBGridColumnsPropEditForm,
ObjInspStrConsts;
type
TFieldProperty = class(TStringPropertyEditor)
public
function GetAttributes: TPropertyAttributes; override;
procedure GetValues(Proc: TGetStrProc); override;
procedure FillValues(const Values: TStringList); virtual;
end;
{ TDBGridColumnsPropertyEditor }
TDBGridColumnsPropertyEditor = class (TCollectionPropertyEditor)
public
class function ShowCollectionEditor(ACollection: TCollection;
OwnerPersistent: TPersistent; const PropName: String): TCustomForm; override;
end;
{ TLookupFieldProperty }
TLookupFieldProperty = class(TFieldProperty)
public
procedure FillValues(const Values: TStringList); override;
end;
TDBGridFieldProperty = class(TFieldProperty)
public
procedure FillValues(const Values: TStringList); override;
end;
{ TDBGridComponentEditor }
TDBGridComponentEditor = class(TComponentEditor)
public
function GetVerbCount: Integer; override;
function GetVerb({%H-}Index: Integer): string; override;
procedure ExecuteVerb({%H-}Index: Integer); override;
end;
function GetDefCollectionLookupRoot(APersistent: TPersistent): TPersistent;
procedure ListDataSourceFields(DataSource: TDataSource; List: TStrings);
procedure EditDBGridColumns(AComponent: TComponent; ACollection: TCollection; APropertyName: String);
implementation
procedure ListDataSourceFields(DataSource: TDataSource; List: TStrings);
var
DataSet: TDataSet;
i: Integer;
begin
if Assigned(DataSource) then
begin
DataSet := DataSource.DataSet;
if Assigned(DataSet) then
begin
if DataSet.Fields.Count > 0 then
DataSet.GetFieldNames(List)
else
begin
try
DataSet.FieldDefs.Update;
except
// some FPC versions will fail here, but having persistent fields should
// actually work or else present an empty list of fields... but not crash/freeze
if Dataset.FieldDefs.Count=0 then begin
List.Clear;
ShowMessage(dpeUnableToRetrieveFieldsDefinitions);
exit;
end;
end;
for i := 0 to DataSet.FieldDefs.Count - 1 do
List.Add(DataSet.FieldDefs[i].Name);
end;
end;
end;
end;
function GetDefCollectionLookupRoot(APersistent: TPersistent): TPersistent;
begin
if not (APersistent is TDefCollection) then
exit(nil);
Result:=TDefCollection(APersistent).Owner;
if Result=nil then
Result:=TDefCollection(APersistent).Dataset;
Result:=GetLookupRootForComponent(Result);
end;
procedure EditDBGridColumns(AComponent: TComponent; ACollection: TCollection;
APropertyName: String);
begin
TDBGridColumnsPropertyEditor.ShowCollectionEditor(ACollection, AComponent, APropertyName);
end;
{ TDBGridColumnsPropertyEditor }
const
DBGridColumnsForm: TDBGridColumnsPropertyEditorForm = nil;
class function TDBGridColumnsPropertyEditor.ShowCollectionEditor(
ACollection: TCollection; OwnerPersistent: TPersistent; const PropName: String
): TCustomForm;
begin
if DBGridColumnsForm = nil then
DBGridColumnsForm := TDBGridColumnsPropertyEditorForm.Create(Application);
DBGridColumnsForm.SetCollection(ACollection, OwnerPersistent, PropName);
DBGridColumnsForm.EnsureVisible;
Result:=DBGridColumnsForm;
// Result:=inherited ShowCollectionEditor(ACollection, OwnerPersistent, PropName );
end;
{ TFieldProperty }
function TFieldProperty.GetAttributes: TPropertyAttributes;
begin
Result:= [paValueList, paSortList, paMultiSelect];
end;
procedure TFieldProperty.GetValues(Proc: TGetStrProc);
var
I: Integer;
Values: TStringList;
begin
Values := TStringList.Create;
try
FillValues(Values);
for I := 0 to Values.Count - 1 do Proc(Values[I]);
finally
Values.Free;
end;
end;
procedure TFieldProperty.FillValues(const Values: TStringList);
var
DataSource: TDataSource;
begin
DataSource := GetObjectProp(GetComponent(0), 'DataSource') as TDataSource;
ListDataSourceFields(DataSource, Values);
end;
{ TDBGridFieldProperty }
procedure TDBGridFieldProperty.FillValues(const Values: TStringList);
var
Column: TColumn;
Grid: TdbGrid;
begin
Column:=TColumn(GetComponent(0));
if not (Column is TColumn) then exit;
Grid:=TdbGrid(Column.Grid);
if not (Grid is TdbGrid) then exit;
ListDataSourceFields(Grid.DataSource, Values);
end;
{ TDBGridComponentEditor }
function TDBGridComponentEditor.GetVerbCount: Integer;
begin
Result:= 1;
end;
function TDBGridComponentEditor.GetVerb(Index: Integer): string;
begin
Result:= sccsLvColEdt;
end;
procedure TDBGridComponentEditor.ExecuteVerb(Index: Integer);
var
Hook: TPropertyEditorHook;
DBGrid: TDBGrid;
begin
DBGrid := GetComponent as TDBGrid;
GetHook(Hook);
EditDBGridColumns( DBGrid, DBGrid.Columns, 'Columns' );
if Assigned(Hook) then Hook.Modified(Self);
end;
{ TLookupFieldProperty }
procedure TLookupFieldProperty.FillValues(const Values: TStringList);
var
DataSource: TDataSource;
begin
DataSource := GetObjectProp(GetComponent(0), 'ListSource') as TDataSource;
ListDataSourceFields(DataSource, Values);
end;
initialization
RegisterPropertyEditor(TypeInfo(string), TComponent, 'DataField', TFieldProperty);
RegisterPropertyEditor(TypeInfo(string), TDBLookupListBox, 'KeyField', TLookupFieldProperty);
RegisterPropertyEditor(TypeInfo(string), TDBLookupListBox, 'ListField', TLookupFieldProperty);
RegisterPropertyEditor(TypeInfo(string), TDBLookupComboBox, 'KeyField', TLookupFieldProperty);
RegisterPropertyEditor(TypeInfo(string), TDBLookupComboBox, 'ListField', TLookupFieldProperty);
RegisterPropertyEditor(TypeInfo(string), TColumn, 'FieldName', TDBGridFieldProperty);
RegisterComponentEditor(TDBGrid,TDBGridComponentEditor);
RegisterGetLookupRoot(@GetDefCollectionLookupRoot);
RegisterPropertyEditor(TypeInfo(TDBGridColumns), nil, '', TDBGridColumnsPropertyEditor);
end.