unit uEditorDBBase;

interface

uses
  Windows, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  uEditorItem, ImgList, PngImageList, StdActns, ActnList, TBX,
  TB2Item, TB2Dock, TB2Toolbar, ComCtrls, JvExControls, JvComponent,
  JvNavigationPane, DB, uDADataTable, uEditorBase, JvFormAutoSize,
  uDAScriptingProvider, uDACDSDataTable, AppEvnts, uCustomView, uViewBase,
  JvAppStorage, JvAppRegistryStorage, JvFormPlacement,
  pngimage, ExtCtrls, dxLayoutLookAndFeels, JvComponentBase, TBXStatusBars,
  JvExComCtrls, JvStatusBar, uDAInterfaces;

type
  IEditorDBBase = interface(IEditorBase)
  ['{1F5B318F-F700-4C78-ABCE-E2329AD876B8}']
  end;

  TfEditorDBBase = class(TfEditorBase, IEditorDBBase)
    dsDataTable: TDADataSource;
    procedure actAnteriorExecute(Sender: TObject);
    procedure actSiguienteExecute(Sender: TObject);
    procedure actAnteriorUpdate(Sender: TObject);
    procedure actSiguienteUpdate(Sender: TObject);
    procedure actRefrescarUpdate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); virtual;
    procedure actEliminarUpdate(Sender: TObject);
    procedure actModificarUpdate(Sender: TObject);
    procedure actPrevisualizarUpdate(Sender: TObject);
    procedure actImprimirUpdate(Sender: TObject);
    procedure actGuardarUpdate(Sender: TObject);
    procedure actGuardarCerrarUpdate(Sender: TObject);
    procedure dsDataTableDataChange(Sender: TObject; Field: TField);
  protected
    function HayDatos: Boolean;
    function GetModified: Boolean; override;
    procedure RefrescarInterno; override;
    procedure CancelarCambiosInterno; override;
  end;

implementation

uses
  uDataTableUtils, cxControls, uCustomEditor;

{$R *.dfm}

procedure TfEditorDBBase.actAnteriorExecute(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
  begin
    if (not ModifiedQuery) then
      Exit;

    dsDataTable.DataTable.Prior;
  end;
end;

procedure TfEditorDBBase.actSiguienteExecute(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
  begin
    if (not ModifiedQuery) then
      Exit;

    dsDataTable.DataTable.Next;
  end;
end;

procedure TfEditorDBBase.actAnteriorUpdate(Sender: TObject);
begin
  inherited;
  if HayDatos then
    (Sender as TAction).Enabled := not dsDataTable.DataTable.BOF
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorDBBase.actSiguienteUpdate(Sender: TObject);
begin
  inherited;
  if HayDatos then
    (Sender as TAction).Enabled := not dsDataTable.DataTable.EOF
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorDBBase.CancelarCambiosInterno;
var
  dtDetails : TList;
  i : integer;
  ABookmark : TBookmark;
begin
  inherited;

  if Assigned(dsDataTable.DataTable) then
  begin
    ABookmark := dsDataTable.DataTable.GetBookMark;
    dsDataTable.DataTable.DisableControls;
//    dsDataTable.DataTable.DisableEventHandlers;  <- No descomentar

    ShowHourglassCursor;
    { No lo pongo en try..finally para ver posibles errores }
    //try
      dsDataTable.DataTable.Cancel;

      dtDetails := dsDataTable.DataTable.GetDetailDataTables;
      for i := 0 to dtDetails.Count - 1 do
      begin
        (TDADataTable(dtDetails.Items[i])).Cancel;
      end;

      dsDataTable.DataTable.CancelUpdates;

      //No funciona bien al CancelUpdates para las tablas detalle de esta forma le obligamos
      dtDetails := dsDataTable.DataTable.GetDetailDataTables;
      for i := 0 to dtDetails.Count - 1 do
      begin
        (TDADataTable(dtDetails.Items[i])).CancelUpdates;
      end;

      { Comprobar si el bookmark no es válido cuando estamos cancelando la
        inserción de una fila nueva.
        CUIDADO!! Si no es válido salta una excepción. NO devuelve false!!!}
      try
        if (Assigned(ABookmark)) and
           (dsDataTable.DataTable.Dataset.BookmarkValid(ABookmark)) then
            dsDataTable.DataTable.GotoBookmark(ABookmark);
      except
      end;

    //finally
      dsDataTable.DataTable.EnableControls;
      dsDataTable.DataTable.FreeBookmark(ABookmark);
//      dsDataTable.DataTable.EnableEventHandlers; <- No descomentar
      HideHourglassCursor
    //end;
  end;
end;

procedure TfEditorDBBase.dsDataTableDataChange(Sender: TObject; Field: TField);
begin
  inherited;
  if not (Sender as TDADataSource).Opening then
	ActualizarEstadoEditor;
end;

procedure TfEditorDBBase.actRefrescarUpdate(Sender: TObject);
begin
  inherited;
  if HayDatos then
    (Sender as TAction).Enabled := (not dsDataTable.DataTable.Fetching) and
      (not dsDataTable.DataTable.Opening) and
      (not dsDataTable.DataTable.Closing) and
      (dsDataTable.DataTable.State <> dsInsert)
  else
    (Sender as TAction).Enabled := False;

  //MODO CONSULTAR ITEM
  if (Sender as TAction).Enabled
  and Assigned(dsDataTable.DataTable) then
     (Sender as TAction).Enabled := not dsDataTable.DataTable.ReadOnly;
end;

function TfEditorDBBase.GetModified: Boolean;
begin
  if ReadOnly then
     Result := False
  else
     Result := DataTableModified(dsDataTable.DataTable) or inherited GetModified;
end;

function TfEditorDBBase.HayDatos: Boolean;
begin
  Result := Assigned(dsDataTable.DataTable) and (dsDataTable.DataTable.State <> dsInactive)
    and (not dsDataTable.DataTable.IsEmpty);
end;

procedure TfEditorDBBase.RefrescarInterno;
var
  AID: Integer;
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
  begin
    if (dsDataTable.DataTable.IsEmpty) or (not ModifiedQuery) then
      Exit; // No continuar con el refresco

	with dsDataTable.DataTable do 
    begin 
      AID := RecIDValue; 
      DisableControls;  //<- No descomentar 
 
      ShowHourglassCursor; 
      try 
        Refresh; 
        Locate(RecIDField.FieldName, AID, []); 
      finally 
        EnableControls;   //<- No descomentar 
        HideHourglassCursor; 
      end; 
	end;
  end;
end;

procedure TfEditorDBBase.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  { Para resetear el estado de la tabla en el caso de hacer un insert
    sin meter ningún dato. }
  if Assigned(dsDataTable.DataTable) and (not Modified) then
    dsDataTable.DataTable.Cancel;
  inherited;
end;

procedure TfEditorDBBase.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := HayDatos and (dsDataTable.DataTable.State <> dsInsert)
end;

procedure TfEditorDBBase.actGuardarCerrarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := HayDatos;
end;

procedure TfEditorDBBase.actGuardarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := HayDatos;
end;

procedure TfEditorDBBase.actModificarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := HayDatos;
end;

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

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

initialization
  RegisterClass(TfEditorDBBase);

finalization
  UnRegisterClass(TfEditorDBBase);

end.
