mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-01 21:24:24 +02:00
529 lines
16 KiB
ObjectPascal
529 lines
16 KiB
ObjectPascal
unit DBGridColumnsPropEditForm;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, ComCtrls, StdCtrls, ActnList, LCLType, typinfo, DBGrids;
|
|
|
|
type
|
|
{ TDBGridColumnsPropertyEditorForm }
|
|
|
|
TDBGridColumnsPropertyEditorForm = class(TForm)
|
|
actAdd: TAction;
|
|
actDel: TAction;
|
|
actAddFields: TAction;
|
|
actDeleteAll: TAction;
|
|
actFetchLabels: TAction;
|
|
actMoveUp: TAction;
|
|
actMoveDown: TAction;
|
|
ActionList1: TActionList;
|
|
CollectionListBox: TListBox;
|
|
DividerToolButton1: TToolButton;
|
|
DividerToolButton2: TToolButton;
|
|
DividerToolButton3: TToolButton;
|
|
ToolBar1: TToolBar;
|
|
AddButton: TToolButton;
|
|
DeleteButton: TToolButton;
|
|
DividerToolButton: TToolButton;
|
|
MoveUpButton: TToolButton;
|
|
MoveDownButton: TToolButton;
|
|
btAddFlds: TToolButton;
|
|
ToolButton1: TToolButton;
|
|
ToolButton2: TToolButton;
|
|
procedure actAddExecute(Sender: TObject);
|
|
procedure actAddFieldsExecute(Sender: TObject);
|
|
procedure actDeleteAllExecute(Sender: TObject);
|
|
procedure actDelExecute(Sender: TObject);
|
|
procedure actFetchLabelsExecute(Sender: TObject);
|
|
procedure actMoveDownExecute(Sender: TObject);
|
|
procedure actMoveUpExecute(Sender: TObject);
|
|
procedure CollectionListBoxClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
private
|
|
FCollection: TCollection;
|
|
FOwnerComponent: TPersistent;
|
|
FOwnerPersistent: TPersistent;
|
|
FPropertyName: String;
|
|
protected
|
|
procedure UpdateCaption;
|
|
procedure UpdateButtons;
|
|
procedure PersistentAdded({%H-}APersistent: TPersistent; {%H-}Select: boolean);
|
|
procedure ComponentRenamed(AComponent: TComponent);
|
|
procedure PersistentDeleting(APersistent: TPersistent);
|
|
procedure RefreshPropertyValues;
|
|
public
|
|
procedure FillCollectionListBox;
|
|
procedure SelectInObjectInspector(ForceUpdate, UnselectAll: Boolean);
|
|
procedure SetCollection(NewCollection: TCollection;
|
|
NewOwnerPersistent: TPersistent; const NewPropName: String);
|
|
procedure Modified;
|
|
public
|
|
property Collection: TCollection read FCollection;
|
|
property OwnerComponent: TPersistent read FOwnerComponent;
|
|
property OwnerPersistent: TPersistent read FOwnerPersistent;
|
|
property PropertyName: String read FPropertyName;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
Controls, Dialogs, LCLProc, IDEImagesIntf, ObjInspStrConsts, PropEdits,
|
|
PropEditUtils;
|
|
|
|
type
|
|
TPersistentAccess = class(TPersistent)
|
|
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.FormCreate(Sender: TObject);
|
|
begin
|
|
ToolBar1.Images := IDEImages.Images_16;
|
|
actAdd.Caption := oiColEditAdd;
|
|
actAddFields.Caption := dceAddFields;
|
|
actAddFields.ImageIndex := IDEImages.LoadImage(16, 'laz_add');
|
|
actFetchLabels.Caption := dceFetchLabels;
|
|
actFetchLabels.ImageIndex := IDEImages.LoadImage(16, 'laz_add');
|
|
actDel.Caption := oiColEditDelete;
|
|
actMoveUp.Caption := oiColEditUp;
|
|
actMoveDown.Caption := oiColEditDown;
|
|
actAdd.ImageIndex := IDEImages.LoadImage(16, 'laz_add');
|
|
actDel.ImageIndex := IDEImages.LoadImage(16, 'laz_delete');
|
|
actDeleteAll.Caption := dceDeleteAll;
|
|
actDeleteAll.ImageIndex := IDEImages.LoadImage(16, 'laz_delete');
|
|
actMoveUp.ImageIndex := IDEImages.LoadImage(16, 'arrow_up');
|
|
actMoveDown.ImageIndex := IDEImages.LoadImage(16, 'arrow_down');
|
|
actMoveUp.ShortCut := scCtrl or VK_UP;
|
|
actMoveDown.ShortCut := scCtrl or VK_DOWN;
|
|
|
|
actAdd.Hint := oiColEditAdd;
|
|
actDel.Hint := oiColEditDelete;
|
|
actMoveUp.Hint := oiColEditUp;
|
|
actMoveDown.Hint := oiColEditDown;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.FormDestroy(Sender: TObject);
|
|
begin
|
|
if GlobalDesignHook <> nil then
|
|
GlobalDesignHook.RemoveAllHandlersForObject(Self);
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.CollectionListBoxClick(Sender: TObject);
|
|
begin
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
SelectInObjectInspector(False, False);
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actAddExecute(Sender: TObject);
|
|
begin
|
|
if Collection = nil then Exit;
|
|
Collection.Add;
|
|
|
|
FillCollectionListBox;
|
|
if CollectionListBox.Items.Count > 0 then
|
|
CollectionListBox.ItemIndex := CollectionListBox.Items.Count - 1;
|
|
SelectInObjectInspector(True, False);
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
Modified;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actAddFieldsExecute(Sender: TObject);
|
|
var It : TCollectionItem;
|
|
flChanged : Boolean;
|
|
flEmpty : Boolean;
|
|
i : Integer;
|
|
begin
|
|
//
|
|
if Collection = nil then Exit;
|
|
if not ( Collection is TDBGridColumns ) then Exit;
|
|
|
|
flChanged := False;
|
|
flEmpty := False;
|
|
//Collection.Add;
|
|
//
|
|
//FillCollectionListBox;
|
|
//if CollectionListBox.Items.Count > 0 then
|
|
// CollectionListBox.ItemIndex := CollectionListBox.Items.Count - 1;
|
|
//SelectInObjectInspector(True, False);
|
|
//UpdateButtons;
|
|
//UpdateCaption;
|
|
//Modified;
|
|
if Collection.Count > 0 then
|
|
It := Collection.Items[ 0 ]
|
|
else begin
|
|
It := Collection.Add;
|
|
flEmpty:=True;
|
|
end;
|
|
|
|
if flEmpty or ( MessageDlg( dceColumnEditor, dceOkToDelete,
|
|
mtConfirmation, [mbYes, mbNo], 0) = mrYes ) then begin
|
|
|
|
try
|
|
if (It is TColumn) and ( Assigned( TDBGrid( TColumn( It ).Grid).DataSource ) ) and
|
|
Assigned ( TDBGrid( TColumn( It ).Grid).DataSource.DataSet ) then begin
|
|
flChanged:=True;
|
|
BeginFormUpdate;
|
|
Collection.Clear;
|
|
It := Collection.Add;
|
|
// TDBGrid( TColumn( It ).Grid).DataSource.DataSet.Open;
|
|
if TDBGrid( TColumn( It ).Grid).DataSource.DataSet.Fields.Count > 0 then begin
|
|
for i := 0 to TDBGrid( TColumn( It ).Grid).DataSource.DataSet.Fields.Count - 1 do begin
|
|
if i > 0 then begin
|
|
It := Collection.Add;
|
|
end;
|
|
TColumn( It ).Field:=TDBGrid( TColumn( It ).Grid).DataSource.DataSet.Fields[ i ];
|
|
TColumn( It ).Title.Caption:=TDBGrid( TColumn( It ).Grid).DataSource.DataSet.Fields[ i ].DisplayLabel;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
finally
|
|
if flChanged then begin
|
|
RefreshPropertyValues;
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
Modified;
|
|
EndFormUpdate;
|
|
end
|
|
else
|
|
if flEmpty then begin
|
|
Collection.Clear;
|
|
RefreshPropertyValues;
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
Modified;
|
|
EndFormUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actDeleteAllExecute(Sender: TObject);
|
|
begin
|
|
//
|
|
if Collection = nil then Exit;
|
|
if ( MessageDlg( dceColumnEditor, dceOkToDelete,
|
|
mtConfirmation, [mbYes, mbNo], 0) = mrYes ) then begin
|
|
try
|
|
BeginFormUpdate;
|
|
Collection.Clear;
|
|
finally
|
|
RefreshPropertyValues;
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
Modified;
|
|
EndFormUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actDelExecute(Sender: TObject);
|
|
var
|
|
I : Integer;
|
|
NewItemIndex: Integer;
|
|
begin
|
|
if Collection = nil then Exit;
|
|
|
|
I := CollectionListBox.ItemIndex;
|
|
if (I >= 0) and (I < Collection.Count) then
|
|
begin
|
|
if MessageDlg(oisConfirmDelete,
|
|
Format(oisDeleteItem, [Collection.Items[I].DisplayName]),
|
|
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
|
|
begin
|
|
// select other item, or unselect
|
|
NewItemIndex := I + 1;
|
|
while (NewItemIndex < CollectionListBox.Items.Count)
|
|
and (CollectionListBox.Selected[NewItemIndex]) do Inc(NewItemIndex);
|
|
|
|
if NewItemIndex = CollectionListBox.Items.Count then
|
|
begin
|
|
NewItemIndex := 0;
|
|
while (NewItemIndex < Pred(I))
|
|
and not (CollectionListBox.Selected[NewItemIndex]) do Inc(NewItemIndex);
|
|
|
|
if NewItemIndex = I then NewItemIndex := -1;
|
|
end;
|
|
|
|
CollectionListBox.ItemIndex := -1;
|
|
|
|
if NewItemIndex > I then Dec(NewItemIndex);
|
|
//debugln('TDBGridColumnsPropertyEditorForm.DeleteClick A NewItemIndex=',dbgs(NewItemIndex),' ItemIndex=',dbgs(CollectionListBox.ItemIndex),' CollectionListBox.Items.Count=',dbgs(CollectionListBox.Items.Count),' Collection.Count=',dbgs(Collection.Count));
|
|
// unselect all items in OI (collections can act strange on delete)
|
|
SelectInObjectInspector(True, True);
|
|
// now delete
|
|
Collection.Items[I].Free;
|
|
// update listbox after whatever happened
|
|
FillCollectionListBox;
|
|
// set NewItemIndex
|
|
if NewItemIndex < CollectionListBox.Items.Count then
|
|
begin
|
|
CollectionListBox.ItemIndex := NewItemIndex;
|
|
SelectInObjectInspector(False, False);
|
|
end;
|
|
//debugln('TDBGridColumnsPropertyEditorForm.DeleteClick B');
|
|
Modified;
|
|
end;
|
|
end;
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actFetchLabelsExecute(Sender: TObject
|
|
);
|
|
var It : TColumn;
|
|
i : Integer;
|
|
begin
|
|
//
|
|
if (Collection.Count > 0) and ( MessageDlg( dceColumnEditor, dceWillReplaceContinue,
|
|
mtConfirmation, [mbYes, mbNo], 0) = mrYes ) then begin
|
|
|
|
It := TColumn (Collection.Items[ 0 ]);
|
|
if Assigned ( It.Grid ) and Assigned (TDBGrid(It.Grid).DataSource) and Assigned (TDBGrid(It.Grid).DataSource.DataSet) then begin
|
|
for i := 0 to Collection.Count - 1 do
|
|
TColumn(Collection.Items[ i ]).Title.Caption:=TDBGrid(TColumn(Collection.Items[I]).Grid).DataSource.DataSet.FieldByName( TColumn(Collection.Items[I]).FieldName ).DisplayLabel;
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actMoveDownExecute(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Collection = nil then Exit;
|
|
|
|
I := CollectionListBox.ItemIndex;
|
|
if I >= Collection.Count - 1 then Exit;
|
|
|
|
Collection.Items[I].Index := I + 1;
|
|
CollectionListBox.ItemIndex := I + 1;
|
|
|
|
FillCollectionListBox;
|
|
SelectInObjectInspector(True, False);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.actMoveUpExecute(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Collection = nil then Exit;
|
|
|
|
I := CollectionListBox.ItemIndex;
|
|
if I < 0 then Exit;
|
|
|
|
Collection.Items[I].Index := I - 1;
|
|
CollectionListBox.ItemIndex := I - 1;
|
|
|
|
FillCollectionListBox;
|
|
SelectInObjectInspector(True, False);
|
|
Modified;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.UpdateCaption;
|
|
var
|
|
NewCaption: String;
|
|
begin
|
|
//I think to match Delphi this should be formatted like
|
|
//"Editing ComponentName.PropertyName[Index]"
|
|
if OwnerPersistent is TComponent then
|
|
NewCaption := TComponent(OwnerPersistent).Name
|
|
else
|
|
if OwnerPersistent <> nil then
|
|
NewCaption := OwnerPersistent.GetNamePath
|
|
else
|
|
NewCaption := '';
|
|
|
|
if NewCaption <> '' then NewCaption := NewCaption + '.';
|
|
NewCaption := oiColEditEditing + ' ' + NewCaption + PropertyName;
|
|
|
|
if CollectionListBox.ItemIndex > -1 then
|
|
NewCaption := NewCaption + '[' + IntToStr(CollectionListBox.ItemIndex) + ']';
|
|
Caption := NewCaption;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.UpdateButtons;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := CollectionListBox.ItemIndex;
|
|
actAdd.Enabled := Collection <> nil;
|
|
actFetchLabels.Enabled:=actAdd.Enabled and (CollectionListBox.Items.Count > 0);
|
|
actDel.Enabled := I > -1;
|
|
actMoveUp.Enabled := I > 0;
|
|
actMoveDown.Enabled := (I >= 0) and (I < CollectionListBox.Items.Count - 1);
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.PersistentAdded(APersistent: TPersistent; Select: boolean);
|
|
begin
|
|
//DebugLn('*** TDBGridColumnsPropertyEditorForm.PersistentAdded called ***');
|
|
FillCollectionListBox;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.ComponentRenamed(AComponent: TComponent);
|
|
begin
|
|
//DebugLn('*** TDBGridColumnsPropertyEditorForm.ComponentRenamed called ***');
|
|
if AComponent = OwnerPersistent then
|
|
UpdateCaption;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.PersistentDeleting(APersistent: TPersistent);
|
|
var
|
|
AIndex, I: Integer;
|
|
begin
|
|
if (APersistent = OwnerPersistent) or (APersistent = OwnerComponent) then
|
|
begin
|
|
SetCollection(nil, nil, '');
|
|
Hide;
|
|
end
|
|
else
|
|
if Assigned(Collection) and (APersistent is TCollectionItem) and
|
|
(TCollectionItem(APersistent).Collection = Collection) then
|
|
begin
|
|
// persistent is still alive
|
|
AIndex := CollectionListBox.ItemIndex;
|
|
CollectionListBox.Items.BeginUpdate;
|
|
CollectionListBox.Items.Delete(TCollectionItem(APersistent).Index);
|
|
for I := TCollectionItem(APersistent).Index to CollectionListBox.Items.Count - 1 do
|
|
CollectionListBox.Items[I] := IntToStr(I) + ' - ' + Collection.Items[I + 1].DisplayName;
|
|
CollectionListBox.Items.EndUpdate;
|
|
if AIndex < CollectionListBox.Items.Count then
|
|
CollectionListBox.ItemIndex := AIndex
|
|
else
|
|
CollectionListBox.ItemIndex := CollectionListBox.Items.Count - 1;
|
|
end;
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
//DebugLn('*** TDBGridColumnsPropertyEditorForm.PersistentDeleting called ***');
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.RefreshPropertyValues;
|
|
begin
|
|
FillCollectionListBox;
|
|
//DebugLn('*** TDBGridColumnsPropertyEditorForm.RefreshPropertyValues called ***');
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.FillCollectionListBox;
|
|
var
|
|
I: Integer;
|
|
CurItem: String;
|
|
Cnt: Integer;
|
|
begin
|
|
CollectionListBox.Items.BeginUpdate;
|
|
try
|
|
if Collection <> nil then Cnt := Collection.Count
|
|
else Cnt := 0;
|
|
|
|
// add or replace list items
|
|
for I := 0 to Cnt - 1 do
|
|
begin
|
|
CurItem := IntToStr(I) + ' - ' + Collection.Items[I].DisplayName;// +' '+ TDBGrid(TColumn(Collection.Items[I]).Grid).DataSource.DataSet.FieldByName( TColumn(Collection.Items[I]).FieldName ).DisplayLabel ;// + ' - '+Collection.Items[I].ClassName +' - ' + Collection.ClassName;
|
|
|
|
DividerToolButton1.Visible := (Collection is TDBGridColumns);
|
|
btAddFlds.Visible := DividerToolButton1.Visible;
|
|
actAddFields.Enabled := DividerToolButton1.Visible;
|
|
if I >= CollectionListBox.Items.Count then
|
|
CollectionListBox.Items.Add(CurItem)
|
|
else
|
|
CollectionListBox.Items[I] := CurItem;
|
|
end;
|
|
|
|
// delete unneeded list items
|
|
if Cnt > 0 then
|
|
begin
|
|
while CollectionListBox.Items.Count > Cnt do
|
|
begin
|
|
CollectionListBox.Items.Delete(CollectionListBox.Items.Count - 1);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
CollectionListBox.Items.Clear;
|
|
end;
|
|
finally
|
|
CollectionListBox.Items.EndUpdate;
|
|
UpdateButtons;
|
|
UpdateCaption;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.SelectInObjectInspector(ForceUpdate, UnselectAll: Boolean);
|
|
var
|
|
I: Integer;
|
|
NewSelection: TPersistentSelectionList;
|
|
begin
|
|
if Collection = nil then Exit;
|
|
// select in OI
|
|
NewSelection := TPersistentSelectionList.Create;
|
|
NewSelection.ForceUpdate := ForceUpdate;
|
|
try
|
|
if not UnselectAll then
|
|
begin
|
|
for I := 0 to CollectionListBox.Items.Count - 1 do
|
|
if CollectionListBox.Selected[I] then
|
|
NewSelection.Add(Collection.Items[I]);
|
|
end;
|
|
if GlobalDesignHook <> nil then
|
|
begin
|
|
GlobalDesignHook.SetSelection(NewSelection);
|
|
GlobalDesignHook.LookupRoot := GetLookupRootForComponent(OwnerPersistent);
|
|
end;
|
|
finally
|
|
NewSelection.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.SetCollection(NewCollection: TCollection;
|
|
NewOwnerPersistent: TPersistent; const NewPropName: String);
|
|
begin
|
|
if (FCollection = NewCollection) and (FOwnerPersistent = NewOwnerPersistent)
|
|
and (FPropertyName = NewPropName) then Exit;
|
|
|
|
FCollection := NewCollection;
|
|
FOwnerPersistent := NewOwnerPersistent;
|
|
FPropertyName := NewPropName;
|
|
//find the component that owns the collection
|
|
FOwnerComponent := NewOwnerPersistent;
|
|
while FOwnerComponent <> nil do
|
|
begin
|
|
if FOwnerComponent is TComponent then
|
|
break;
|
|
FOwnerComponent := TPersistentAccess(FOwnerComponent).GetOwner;
|
|
end;
|
|
//debugln('TDBGridColumnsPropertyEditorForm.SetCollection A Collection=',dbgsName(FCollection),' OwnerPersistent=',dbgsName(OwnerPersistent),' PropName=',PropertyName);
|
|
if GlobalDesignHook <> nil then
|
|
begin
|
|
GlobalDesignHook.RemoveAllHandlersForObject(Self);
|
|
if FOwnerPersistent <> nil then
|
|
begin
|
|
GlobalDesignHook.AddHandlerPersistentAdded(@PersistentAdded);
|
|
GlobalDesignHook.AddHandlerComponentRenamed(@ComponentRenamed);
|
|
GlobalDesignHook.AddHandlerPersistentDeleting(@PersistentDeleting);
|
|
GlobalDesignHook.AddHandlerRefreshPropertyValues(@RefreshPropertyValues);
|
|
end;
|
|
end;
|
|
|
|
FillCollectionListBox;
|
|
UpdateCaption;
|
|
end;
|
|
|
|
procedure TDBGridColumnsPropertyEditorForm.Modified;
|
|
begin
|
|
if GlobalDesignHook <> nil then
|
|
GlobalDesignHook.Modified(Self);
|
|
end;
|
|
|
|
end.
|
|
|