{ ------------------------------------------------------------- }
{ Purpose : Next DBGrid 6                                       }
{ By      : Bojan Nikolic                                       }
{ For     : BergSoft                                            }
{ ------------------------------------------------------------- }
{ Copyright (C) BergSoft.net 2016. All Rights Reserved.         }
{ ------------------------------------------------------------- }
unit NxDBGridReg6;

interface

uses
  { Standard }
  Classes, Types, SysUtils, Controls,
  { Standard.Design }
  DesignIntf, DesignEditors, VCLEditors,
  { DB }
  DB,
  { Next Standard 6 }
  NxIntf6, NxConsts6, NxTypes6,
  { Next Standard 6 (Design) }
  NxStandardReg6, NxDesignWindow6, NxColumnsEditor6,
  { NextGrid 6 }
  NxColumns6,
  { NextGrid 6 (Design ) }
  NxGridReg6,
  { NextDBGrid 6 }
  NxDBGrid6, NxDBColumns6;

type
  { TNxDBColumnsProperty6 }

  TNxDBColumnsProperty6 = class(TNxColumnsProperty6)
  protected
    function GetEditorClass: TNxEditorClass; override;
  end;

  { TNxDBColumnsProperty6 }

  TNxFieldNameProperty6 = class(TPropertyEditor)
  public
    function GetAttributes: TPropertyAttributes; override;
		function GetValue: string; override;
    procedure GetValues(Proc: TGetStrProc); override;
    procedure SetValue(const Value: string); override;
  end;

  { TNxDBGridComponentEditor6 }

  TNxDBGridComponentEditor6 = class(TNxGridComponentEditor6,
    INxDBDesignNotificationRecipient)
  private
    function CanAddFields: Boolean;
    function GetDataSet: TDataSet;
    function GetDataGrid: TNextDBGrid6;
  protected
    procedure DataLinkActiveChanged(Active: Boolean);
    procedure DoBeforeAddField(Sender: TObject; FieldName: string; var Checked: Boolean);
    procedure ShowFieldsDialog;
  public
    constructor Create(AComponent: TComponent; ADesigner: IDesigner); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
    function CreateColumn(ColumnClass: TNxColumnClass): TNxColumn6;
    procedure ExecuteVerb (Index: Integer); override;
    { Properties }
    property DataGrid: TNextDBGrid6 read GetDataGrid;
    property DataSet: TDataSet read GetDataSet;
  end;

procedure Register;

implementation

uses
  Dialogs,
  NxDBColumnsEditor6, NxDBFieldsEditor6;

procedure Register;
begin
  { NextDBGrid 6 }
  RegisterComponents('Next Suite 6', [TNextDBGrid6]);

  { Component Editors }
  RegisterComponentEditor(TNextDBGrid6, TNxDBGridComponentEditor6);

  RegisterPropertyEditor(TypeInfo(TNxColumns6), TNextDBGrid6, 'Columns', TNxDBColumnsProperty6);

  RegisterPropertyEditor(TypeInfo(String), TNxDataBinding, 'FieldName', TNxFieldNameProperty6);

  { Required }
  RegisterClasses([
    TNxDBButtonColumn6,
    TNxDBCheckBoxColumn6,
    TNxDBCheckComboBoxColumn6,
    TNxDBColorColumn6,
    TNxDBComboBoxColumn6,
    TNxDBDateColumn6,
    TNxDBTimeColumn6,
    TNxDBGraphicColumn6,
    TNxDBHTMLColumn6,
    TNxDBIconColumn6,
    TNxDBIncrementColumn6,
    TNxDBListColumn6,
    TNxDBLookupColumn6,
    TNxDBMemoColumn6,
    TNxDBNumberColumn6,
    TNxDBProgressColumn6,
    TNxDBTextColumn6,
    TNxDBToolbarColumn6,
    TNxDBTrackBarColumn6,
    TNxDBRateColumn6
  ]);

  RegisterNoIcon([
    TNxDBButtonColumn6,
    TNxDBCheckBoxColumn6,
    TNxDBCheckComboBoxColumn6,
    TNxDBColorColumn6,
    TNxDBComboBoxColumn6,
    TNxDBDateColumn6,
    TNxDBTimeColumn6,
    TNxDBGraphicColumn6,
    TNxDBHTMLColumn6,
    TNxDBIconColumn6,
    TNxDBIncrementColumn6,
    TNxDBListColumn6,
    TNxDBLookupColumn6,
    TNxDBMemoColumn6,
    TNxDBNumberColumn6,
    TNxDBProgressColumn6,
    TNxDBTextColumn6,
    TNxDBToolbarColumn6,
    TNxDBTrackBarColumn6,
    TNxDBRateColumn6
  ]);

end;

{ TNxDBColumnsProperty6 }

function TNxDBColumnsProperty6.GetEditorClass: TNxEditorClass;
begin
  Result := TNxDBColumnsEditor6;
end;

{ TNxFieldNameProperty6 }

function TNxFieldNameProperty6.GetAttributes: TPropertyAttributes;
begin
	Result := [paValueList];
end;

function TNxFieldNameProperty6.GetValue: string;
begin
  Result := (GetComponent(0) as TNxDataBinding).FieldName;
end;

procedure TNxFieldNameProperty6.GetValues(Proc: TGetStrProc);
var
  i: Integer;
  DataBinding: TNxDataBinding;
begin
  DataBinding := GetComponent(0) as TNxDataBinding;
  with DataBinding do
  begin
    if Assigned(DataBinding.DataSet) then
    begin
      { Stored Fields }
      for i := 0 to Pred(DataSet.FieldCount) do
        Proc(DataSet.Fields[i].FieldName);

      { Aggregate Fields }
      for i := 0 to Pred(DataSet.AggFields.Count) do
        Proc(DataSet.AggFields[i].FieldName);
    end;
  end;
end;

procedure TNxFieldNameProperty6.SetValue(const Value: string);
begin
  inherited;
	(GetComponent(0) as TNxDataBinding).FieldName := Value;
  Designer.Modified;
end;

{ TNxDBGridComponentEditor6 }

function TNxDBGridComponentEditor6.CanAddFields: Boolean;
begin
  with GetComponent as TNextDBGrid6 do
  begin
    Result := Assigned(DataSource) and Assigned(DataSource.DataSet)
      and (DataSource.DataSet.FieldDefs.Count > 0);
  end;
end;

constructor TNxDBGridComponentEditor6.Create(AComponent: TComponent; ADesigner: IDesigner);
var
  Control: INxDesignControl;
begin
  inherited;
  if Supports(GetComponent, INxDesignControl, Control) then
  begin
    Control.DesignerDelegate := Self as INxDBDesignNotificationRecipient;
  end;
end;

function TNxDBGridComponentEditor6.CreateColumn(
  ColumnClass: TNxColumnClass): TNxColumn6;
var
  Ref: IInterfaceComponentReference;
  NewName: TComponentName;
begin
  Result := ColumnClass.Create(DataGrid.Owner);

  if Supports(Result, IInterfaceComponentReference, Ref) then
  begin
    try
      { Set Unique Name to View }
      NewName := Designer.UniqueName(Ref.GetComponent.ClassName);

      Ref.GetComponent.Name := NewName;

      { Add Object into List }
      DataGrid.Columns.Add(Result);
    except

      Exit; { Excape }
    end;
  end;
end;

procedure TNxDBGridComponentEditor6.DataLinkActiveChanged(Active: Boolean);
begin
  if Active then ShowFieldsDialog;
end;

procedure TNxDBGridComponentEditor6.DoBeforeAddField(Sender: TObject; FieldName: string; var Checked: Boolean);
var
  i: Integer;
begin
  for i := 0 to Pred(DataGrid.ColCount) do
  begin
    if DataGrid.DataBinding[i].FieldName = FieldName then
    begin
      Checked := False;
      Exit;
    end;
  end;
end;

procedure TNxDBGridComponentEditor6.ExecuteVerb(Index: Integer);
begin
  inherited;
  if CanAddFields then
  begin
    if Index = GetVerbCount - 4 then ShowFieldsDialog;
  end;
end;

function TNxDBGridComponentEditor6.GetDataGrid: TNextDBGrid6;
begin
  Result := TNextDBGrid6(GetComponent);
end;

function TNxDBGridComponentEditor6.GetDataSet: TDataSet;
begin
  with GetComponent as TNextDBGrid6 do
  begin
    if Assigned(DataSource) then Result := DataSource.DataSet
      else Result := nil;
  end;
end;

function TNxDBGridComponentEditor6.GetVerb(Index: Integer): string;
begin
  Result := inherited GetVerb(Index);
  if CanAddFields then
  begin
    if Index = GetVerbCount - 5 then Result := '-';
    if Index = GetVerbCount - 4 then Result := 'Add Fields...';
  end;
end;

function TNxDBGridComponentEditor6.GetVerbCount: Integer;
begin
  Result := inherited GetVerbCount;
  if CanAddFields then Inc(Result, 2);
end;

procedure TNxDBGridComponentEditor6.ShowFieldsDialog;
var
  i: Integer;
  Column: TNxColumn6;
  ColumnClass: TNxColumnClass;
  DataBinding: INxDataBinding;
  FieldName: string;
begin
  try
    FieldsDialog := TFieldsDialog.Create(nil);
    FieldsDialog.DataSet := DataSet;
    FieldsDialog.OnBeforeAddField := DoBeforeAddField;

    if FieldsDialog.ShowModal = mrOk then
    begin
      for i := 0 to Pred(FieldsDialog.FieldsGrid.RowCount) do
      begin
        if FieldsDialog.FieldsGrid.Cell[0, i].AsBoolean then
        begin
          ColumnClass := FieldsDialog.ClassAt[i];

          if ColumnClass <> nil then
          begin
            FieldName := FieldsDialog.FieldsGrid.Cell[1, i].AsString;

            Column := CreateColumn(ColumnClass);
            Column.Header.Caption := FieldName;

            if Supports(Column, INxDataBinding, DataBinding) then
            begin
              DataBinding.DataBinding.Options := [dboUseFieldProperties];
              DataBinding.DataBinding.FieldName := FieldName;
            end;
          end;


        end;
      end;
    end;
  finally
    FieldsDialog.Free;
  end;
end;

end.
