unit uViewDetallesGenerico;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uViewBase, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData,
  cxDataStorage, cxEdit, DB, cxDBData, cxTextEdit, ActnList, ImgList,
  PngImageList, uDADataTable, ComCtrls, ToolWin, cxGridLevel,
  cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxClasses,
  cxControls, cxGridCustomView, cxGrid, uDAInterfaces;

type
  IViewDetallesGenerico = interface(IViewBase)
    ['{A2D2B5CF-6E47-4635-8B80-C761BFCD7FB2}']
  end;

  TfrViewDetallesGenerico = class(TfrViewBase, IViewDetallesGenerico)
    cxGrid: TcxGrid;
    cxGridView: TcxGridDBTableView;
    cxGridViewID: TcxGridDBColumn;
    cxGridLevel: TcxGridLevel;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    dsDetalles: TDADataSource;
    ContenidoImageList: TPngImageList;
    ActionListContenido: TActionList;
    actAnadir: TAction;
    actEliminar: TAction;
    ToolButton4: TToolButton;
    actModificar: TAction;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    actAnchoAutomatico: TAction;
    ToolButton7: TToolButton;
    procedure cxGridViewEditKeyDown(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; AEdit: TcxCustomEdit; var Key: Word;
      Shift: TShiftState);
    procedure actAnadirExecute(Sender: TObject);
    procedure actEliminarExecute(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actAnadirUpdate(Sender: TObject);
    procedure actAnchoAutomaticoExecute(Sender: TObject);
    procedure actModificarUpdate(Sender: TObject);
    procedure actModificarExecute(Sender: TObject);
  protected
    function HayDatos : Boolean;
    procedure AnadirInterno; virtual;
    procedure ModificarInterno; virtual;
    procedure EliminarInterno; virtual;

    function GetModified: Boolean; override;
  end;

implementation

{$R *.dfm}

uses
  uDataTableUtils;

procedure TfrViewDetallesGenerico.actAnadirExecute(Sender: TObject);
var
  bEsMultiSelect : Boolean;
begin
  // Debo quitar el multiselect porque provoca que se quede seleccionado
  // el registro actual y no el nuevo registro que voy a añadir
  bEsMultiSelect := cxGridView.OptionsSelection.MultiSelect;
  if bEsMultiSelect then
    cxGridView.OptionsSelection.MultiSelect := False;

  cxGridView.BeginUpdate;
  try
    if cxGridView.Controller.EditingController.IsEditing then
       cxGridView.Controller.EditingController.Edit.PostEditValue;

    AnadirInterno;
  finally
    cxGridView.EndUpdate;

    // Dejo la propiedad MultiSelect como estaba
    if bEsMultiSelect then
       cxGridView.OptionsSelection.MultiSelect := bEsMultiSelect;
  end;
end;

procedure TfrViewDetallesGenerico.actAnadirUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := Assigned(dsDetalles.DataTable);
end;

procedure TfrViewDetallesGenerico.actAnchoAutomaticoExecute(Sender: TObject);
begin
  inherited;
  cxGridView.ApplyBestFit(nil, True, False);
end;

procedure TfrViewDetallesGenerico.actEliminarExecute(Sender: TObject);
var
  AuxTop, AuxRow:Integer;
begin
  cxGridView.BeginUpdate;
  AuxTop := cxGridView.Controller.TopRowIndex;
  AuxRow := cxGridView.DataController.FocusedRowIndex;
  try
    EliminarInterno;

    //Selecciona en el grid el registro siguiente
    if (AuxRow < cxGridView.DataController.RowCount-1) then
      Inc(AuxRow)
    else
      Dec(AuxRow);

    if dsDetalles.DataTable.RecordCount > 0 then
    begin
      cxGridView.DataController.SelectRows(AuxRow,AuxRow);
      cxGridView.Controller.TopRowIndex := AuxTop;
    end;
  finally
    cxGridView.EndUpdate;
  end;
end;

procedure TfrViewDetallesGenerico.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos;
end;

procedure TfrViewDetallesGenerico.actModificarExecute(Sender: TObject);
begin
  inherited;
  ModificarInterno;
end;

procedure TfrViewDetallesGenerico.actModificarUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos and
    (cxGridView.DataController.FocusedRowIndex >= 0)
end;

procedure TfrViewDetallesGenerico.AnadirInterno;
begin
  dsDetalles.DataTable.Insert;
end;

procedure TfrViewDetallesGenerico.cxGridViewEditKeyDown(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem;
  AEdit: TcxCustomEdit; var Key: Word; Shift: TShiftState);
begin
  inherited;
  cxGridView.BeginUpdate;
  try
    Case Key of
    VK_DOWN  : begin
                  //En el caso de ser la última fila hacemos un append nosotros no el grid
                  //ya que se saltaria la lógica del controllerDetallesBase
                  if cxGridView.Controller.IsFinish then
                  begin
                    Key := 0;
                    if Sender.Controller.EditingController.IsEditing then
                       Sender.Controller.EditingController.Edit.PostEditValue;
                    actAnadir.Execute;
                  end;
               end;

    VK_RETURN, VK_RIGHT
             : begin
                  //En el caso de ser la última fila hacemos un append nosotros no el grid
                  //ya que se saltaria la lógica del controllerDetallesBase
                  if cxGridView.Controller.IsFinish
                  and AItem.IsLast then
                  begin
                    Key := 0;
                    if Sender.Controller.EditingController.IsEditing then
                       Sender.Controller.EditingController.Edit.PostEditValue;
                    actAnadir.Execute;
                  end;
              end;
    end;
  finally
    cxGridView.EndUpdate;
  end;
end;

procedure TfrViewDetallesGenerico.EliminarInterno;
begin
  dsDetalles.DataTable.Delete;
end;

function TfrViewDetallesGenerico.GetModified: Boolean;
begin
  Result := DataTableModified(dsDetalles.DataTable) or inherited GetModified;
end;

function TfrViewDetallesGenerico.HayDatos: Boolean;
begin
  Result := Assigned(dsDetalles.DataTable) and
    (cxGridView.ViewInfo.VisibleRecordCount > 0)
end;

procedure TfrViewDetallesGenerico.ModificarInterno;
begin
  //
end;

end.
