unit uEditorDBBase;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, 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;

type
  IEditorDBBase = interface(IEditorBase)
  ['{497AE4CE-D061-4F75-A29A-320F8565FF54}']
  end;

  TfEditorDBBase = class(TfEditorBase, IEditorDBBase)
    dsDataTable: TDADataSource;
    procedure actRefrescarExecute(Sender: TObject);
    procedure actAnteriorExecute(Sender: TObject);
    procedure actSiguienteExecute(Sender: TObject);
    procedure actAnteriorUpdate(Sender: TObject);
    procedure actSiguienteUpdate(Sender: TObject);
    procedure actRefrescarUpdate(Sender: TObject);
    procedure actCancelarCambiosExecute(Sender: TObject);
    procedure actGuardarExecute(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); virtual;
    procedure actEliminarExecute(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actModificarUpdate(Sender: TObject);
    procedure actPrevisualizarUpdate(Sender: TObject);
    procedure actImprimirUpdate(Sender: TObject);
  private
    { Private declarations }
  protected
    function GetModified: Boolean; override;
  published
  end;

var
  fEditorDBBase: TfEditorDBBase;

implementation

uses uExceptions, uDataTableUtils, uBizInformesBase,
  uDAInterfaces, cxControls;

{$R *.dfm}

procedure TfEditorDBBase.actRefrescarExecute(Sender: TObject);
var
  ABookmark : TBookmark;
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
  begin
    if (dsDataTable.DataTable.IsEmpty) or (not ModifiedQuery) then
      Exit; // No continuar con el refresco

    ABookmark := dsDataTable.DataTable.GetBookMark;
//    dsDataTable.DataTable.DisableControls;  <- No descomentar

    ShowHourglassCursor;
    try
      dsDataTable.DataTable.Refresh;

      if dsDataTable.DataTable.Dataset.BookmarkValid(ABookmark) then
        dsDataTable.DataTable.GotoBookmark(ABookmark);
    finally
      dsDataTable.DataTable.FreeBookmark(ABookmark);
//      dsDataTable.DataTable.EnableControls;   <- No descomentar
      HideHourglassCursor;
    end;
  end;
end;

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 Assigned(dsDataTable.DataTable) then
    (Sender as TAction).Enabled := not dsDataTable.DataTable.BOF
  else
    (Sender as TAction).Enabled := False;
end;

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

procedure TfEditorDBBase.actRefrescarUpdate(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
    (Sender as TAction).Enabled := not dsDataTable.DataTable.Fetching
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorDBBase.actCancelarCambiosExecute(Sender: TObject);
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;

      { 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.actGuardarExecute(Sender: TObject);
var
  dtDetails : TList;
  i : integer;
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
  begin
    if dsDataTable.DataTable.Editing then
      dsDataTable.DataTable.Post;

    dtDetails := dsDataTable.DataTable.GetDetailDataTables;
    for i := 0 to dtDetails.Count - 1 do
      if (TDADataTable(dtDetails.Items[i])).Editing then
        (TDADataTable(dtDetails.Items[i])).Post;

    dsDataTable.DataTable.ApplyUpdates;
    Modified := False;
  end;
end;

function TfEditorDBBase.GetModified: Boolean;
var
  dtDetails : TList;
  i : integer;
  bCambiado : Boolean;
begin
  bCambiado := False;
  if Assigned(dsDataTable.DataTable) then
  begin
    bCambiado := (dsDataTable.DataTable.State = dsEdit) or
                DeltaValuesAreDifferent(dsDataTable.DataTable.Delta);

    if (not bCambiado) then
    begin
      dtDetails := dsDataTable.DataTable.GetDetailDataTables;
      for i := 0 to dtDetails.Count - 1 do
      begin
        bCambiado := bCambiado or
                    ((TDADataTable(dtDetails.Items[i])).State = dsEdit) or
                    DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta);
        if bCambiado then
          Break;
      end;
    end;
  end;

  if (not bCambiado) then
    bCambiado := inherited GetModified;

  Result := bCambiado;
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.actEliminarExecute(Sender: TObject);
var
  aObj : IApplyUpdateFailedException;
begin
  inherited;
  ShowHourglassCursor;
  try
    if dsDataTable.DataTable.State in dsEditModes then
      dsDataTable.DataTable.Cancel;
    dsDataTable.DataTable.Delete;
    try
      dsDataTable.DataTable.ApplyUpdates;
      Modified := False;
    except
      on E: EDAApplyUpdateFailed do
      begin
        dsDataTable.DataTable.CancelUpdates;
        actRefrescar.Execute;        
        if Supports(dsDataTable.DataTable, IApplyUpdateFailedException, aObj) then
          aObj.ShowApplyUpdateFailed(E);
      end
      else
        raise; // Generic exception
    end;
  finally
    HideHourglassCursor;
  end;
end;

procedure TfEditorDBBase.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
    (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty)
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorDBBase.actModificarUpdate(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
    (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty)
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorDBBase.actPrevisualizarUpdate(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
    (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty)
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorDBBase.actImprimirUpdate(Sender: TObject);
begin
  inherited;
  if Assigned(dsDataTable.DataTable) then
    (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty)
  else
    (Sender as TAction).Enabled := False;
end;

end.
