{*******************************************************}
{                                                       }
{       Administración de puntos de venta               }
{                                                       }
{       Copyright (C) 2006 Rodax Software S.L.          }
{                                                       }
{*******************************************************}

unit uViewGridBase;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uViewBase, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData,
  cxDataStorage, cxEdit, DB, cxDBData, uDADataTable, cxGridLevel,
  cxClasses, cxControls, cxGridCustomView, cxGridCustomTableView,
  cxGridTableView, cxGridDBTableView, cxGrid, Menus, ActnList, Grids,
  DBGrids, JvComponent, JvFormAutoSize, uGridStatusUtils, uViewFiltroBase,
  uDAInterfaces, cxGridExportLink;

type
  IViewGridBase = interface(IViewBase)
  ['{D5B9B017-2A2E-44AC-8223-E54664C6BC66}']
    procedure ExpandirTodo;
    procedure ContraerTodo;
    procedure AjustarAncho;

    procedure Preview;
    procedure Print;
    procedure PrintSetup;

    function IsEmpty : Boolean;

    procedure SaveGridStatus;
    procedure RestoreGridStatus;

    procedure GotoFirst;
    procedure GotoLast;

    procedure ExportToExcel(const AFileName: string); overload;
    procedure ExportToExcel; overload;

    function GetFocusedView : TcxGridDBTableView;
    property _FocusedView : TcxGridDBTableView read GetFocusedView;

    function GetGrid : TcxGrid;
    property _Grid : TcxGrid read GetGrid;

    procedure RestoreFromIniFile;
    procedure StoreToIniFile;

    procedure StoreToRegistry (const Path : String);
    procedure RestoreFromRegistry (const Path : String);

    procedure SetDblClick(const Value: TNotifyEvent);
    function GetDblClick: TNotifyEvent;
    property OnDblClick: TNotifyEvent read GetDblClick write SetDblClick;

    procedure SetPopupMenu(const Value: TPopupMenu);
    function GetPopupMenu: TPopupMenu;
    property PopupMenu: TPopupMenu read GetPopupMenu write SetPopupMenu;

    function GetMultiSelect: Boolean;
    procedure SetMultiSelect(const Value: Boolean);
    property MultiSelect : Boolean read GetMultiSelect write SetMultiSelect;

    procedure SetFilter(const Value: string);
    function GetFilter: string;
    property Filter: string read GetFilter write SetFilter;

    function GetFiltered: Boolean;
    property Filtered : Boolean read GetFiltered;

    function GetViewFiltros: IViewFiltroBase;
    procedure SetViewFiltros(const Value: IViewFiltroBase);
    property ViewFiltros: IViewFiltroBase read GetViewFiltros write SetViewFiltros;

    function esSeleccionCeldaDatos: Boolean;

    function getNumSeleccionados: Integer;
    property NumSeleccionados: Integer read getNumSeleccionados;

    function Locate(const AItemIndex: Integer; const AValue: String;
      const APartialCompare: Boolean = False) : Boolean;

    function GetAgrupacionesVisibles: Boolean;
    property AgrupacionesVisibles : Boolean read GetAgrupacionesVisibles;
 end;


  TfrViewGridBase = class(TfrViewBase, IViewGridBase)
    dsDataSource: TDADataSource;
  private
    FViewFiltros: IViewFiltroBase;
    FFilter: string;
    FOnFilterChanged : TNotifyEvent;
    FGridStatus : TcxGridStatus;
//		procedure BestFitAllColumns;    
  protected
    FOnDblClick: TNotifyEvent;
    FPopupMenu: TPopupMenu;
    function GetMultiSelect: Boolean; virtual;
    procedure SetMultiSelect(const Value: Boolean); virtual;
    procedure SetPopupMenu(const Value: TPopupMenu); virtual;
    function GetPopupMenu: TPopupMenu; virtual;
    procedure SetDblClick(const Value: TNotifyEvent); virtual;
    function GetDblClick: TNotifyEvent; virtual;
    function GetGrid : TcxGrid; virtual; abstract;
    function GetFocusedView : TcxGridDBTableView; virtual; abstract;
    function EsSeleccionCeldaDatos: Boolean; virtual; abstract;
    function getNumSeleccionados: Integer;

    procedure SetFilter(const Value: string); virtual;
    procedure RefrescarFiltro;
    function GetFilter: string; virtual;
    function GetFiltered: Boolean; virtual;
    procedure FiltrarGrid(TextoFiltro : String); virtual;
    function GetViewFiltros: IViewFiltroBase;
    procedure SetViewFiltros(const Value: IViewFiltroBase); virtual;
    procedure FilterChanged(Sender : TObject); virtual;

    procedure cxGridViewInitStoredObject(Sender: TcxCustomGridView;  AObject: TObject);
    procedure cxGridViewGetStoredProperties(Sender: TcxCustomGridView;
      AProperties: TStrings);
    procedure cxGridViewGetStoredPropertyValue(Sender: TcxCustomGridView;
      const AName: string; var AValue: Variant);
    procedure cxGridViewSetStoredPropertyValue(Sender: TcxCustomGridView;
      const AName: string; const AValue: Variant);

    procedure cxGridViewColumnGetStoredProperties(
      Sender: TcxCustomGridTableItem; AProperties: TStrings);
    procedure cxGridViewColumnGetStoredPropertyValue(
      Sender: TcxCustomGridTableItem; const AName: string; var AValue: Variant);
    procedure cxGridViewColumnSetStoredPropertyValue(
      Sender: TcxCustomGridTableItem; const AName: string;
      const AValue: Variant);
    function GetAgrupacionesVisibles: Boolean; virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure ShowEmbedded(const AParent : TWinControl); override;

    procedure ExpandirTodo; virtual;
    procedure ContraerTodo; virtual;
    procedure AjustarAncho; virtual;

    procedure Preview; virtual;
    procedure Print; virtual;
    procedure PrintSetup; virtual;

    function IsEmpty : Boolean; virtual;

    procedure SaveGridStatus;
    procedure RestoreGridStatus;

    procedure RestoreFromIniFile;
    procedure StoreToIniFile;

    procedure GotoFirst;
    procedure GotoLast;

    procedure ExportToExcel(const AFileName: string); overload;
    procedure ExportToExcel; overload;

    procedure StoreToRegistry (const Path : String); virtual;
    procedure RestoreFromRegistry (const Path : String); virtual;

    function Locate(const AItemIndex: Integer; const AValue: String;
      const APartialCompare: Boolean = False) : Boolean;

    property Filter: string read GetFilter write SetFilter;
    property Filtered : Boolean read GetFiltered;

    procedure AnadirOtrosFiltros; virtual;
    property ViewFiltros: IViewFiltroBase read GetViewFiltros write SetViewFiltros;

    property _FocusedView : TcxGridDBTableView read GetFocusedView;
    property _Grid : TcxGrid read GetGrid;
    property OnDblClick: TNotifyEvent read GetDblClick write SetDblClick;
    property PopupMenu: TPopupMenu read GetPopupMenu write SetPopupMenu;
    property MultiSelect : Boolean read GetMultiSelect write SetMultiSelect;
    property NumSeleccionados: Integer read getNumSeleccionados;
    property AgrupacionesVisibles : Boolean read GetAgrupacionesVisibles;
  end;

procedure Register;

implementation

uses
  uDMBase, cxGridBandedTableView, uDBSelectionListUtils,
  uSistemaFunc, SHFolder, uAppInfoUtils;

{$R *.dfm}

procedure Register;
begin
  //RegisterCustomContainer(TfrViewGridBase);
end;

{ TfrViewGrid }

{procedure TfrViewGridBase.BestFitAllColumns;
var
  i : Integer ;

begin
  ShowHourglassCursor;
  _FocusedView.BeginUpdate;

  try
    for i := 0 to _FocusedView.VisibleColumnCount-1 do
    begin
      _FocusedView.VisibleColumns[i].ApplyBestFit;
      if (_FocusedView.VisibleColumns[i].BestFitMaxWidth > 0) and
         (_FocusedView.VisibleColumns[i].Width > _FocusedView.VisibleColumns[i].BestFitMaxWidth) then
          _FocusedView.VisibleColumns[i].Width := _FocusedView.VisibleColumns[i].BestFitMaxWidth;
    end;
  finally
    _FocusedView.EndUpdate;
    HideHourglassCursor;
  end;
end;}

procedure TfrViewGridBase.AjustarAncho;
begin
  if Assigned(_FocusedView) then
  begin
    //BestFitAllColumns;
    _FocusedView.ApplyBestFit(nil, True, False);
  end;
end;

procedure TfrViewGridBase.AnadirOtrosFiltros;
begin
//
end;

procedure TfrViewGridBase.ContraerTodo;
begin
  if Assigned(_FocusedView) then
    _FocusedView.ViewData.Collapse(True);
end;

constructor TfrViewGridBase.Create(AOwner: TComponent);
var
  I: Integer;
begin
  inherited;
  FFilter := '';
  FOnFilterChanged := FilterChanged;
  FPopupMenu := nil;
  FOnDblClick := nil;
  FGridStatus := NIL;

  if Assigned(_FocusedView) then
  begin
    _FocusedView.OnInitStoredObject := cxGridViewInitStoredObject;
    _FocusedView.OnGetStoredProperties := cxGridViewGetStoredProperties;
    _FocusedView.OnGetStoredPropertyValue := cxGridViewGetStoredPropertyValue;
    _FocusedView.OnSetStoredPropertyValue := cxGridViewSetStoredPropertyValue;
    for I := 0 to _FocusedView.ColumnCount - 1 do
    begin
      _FocusedView.Columns[i].OnGetStoredProperties := cxGridViewColumnGetStoredProperties;
      _FocusedView.Columns[i].OnGetStoredPropertyValue := cxGridViewColumnGetStoredPropertyValue;
      _FocusedView.Columns[i].OnSetStoredPropertyValue := cxGridViewColumnSetStoredPropertyValue;
    end;
  end;
end;

procedure TfrViewGridBase.cxGridViewColumnGetStoredProperties(
  Sender: TcxCustomGridTableItem; AProperties: TStrings);
begin
end;

procedure TfrViewGridBase.cxGridViewColumnGetStoredPropertyValue(
  Sender: TcxCustomGridTableItem; const AName: string; var AValue: Variant);
begin
end;

procedure TfrViewGridBase.cxGridViewColumnSetStoredPropertyValue(
  Sender: TcxCustomGridTableItem; const AName: string; const AValue: Variant);
begin
end;

procedure TfrViewGridBase.cxGridViewGetStoredProperties(
  Sender: TcxCustomGridView; AProperties: TStrings);
begin
  AProperties.Delete(AProperties.IndexOf('Footer'));
  AProperties.Delete(AProperties.IndexOf('GroupByBox'));
  AProperties.Delete(AProperties.IndexOf('GroupFooters'));
  AProperties.Delete(AProperties.IndexOf('NewItemRow'));    
end;

procedure TfrViewGridBase.cxGridViewGetStoredPropertyValue(
  Sender: TcxCustomGridView; const AName: string; var AValue: Variant);
begin
end;

procedure TfrViewGridBase.cxGridViewSetStoredPropertyValue(
  Sender: TcxCustomGridView; const AName: string; const AValue: Variant);
begin
end;

procedure TfrViewGridBase.ExpandirTodo;
begin
  if Assigned(_FocusedView) then
    _FocusedView.ViewData.Expand(True);
end;

procedure TfrViewGridBase.ExportToExcel(const AFileName: string);
begin
  if Assigned(_Grid) then
    ExportGridToExcel(AFileName, _Grid);
end;

procedure TfrViewGridBase.ExportToExcel;
var
  AFileName : String;
begin
  if PreguntarFicheroExcelExportar(AFileName) then
    ExportToExcel(AFileName);
end;

function TfrViewGridBase.GetAgrupacionesVisibles: Boolean;
begin
  Result := False;
end;

function TfrViewGridBase.GetDblClick: TNotifyEvent;
begin
  Result := FOnDblClick;
end;

function TfrViewGridBase.GetFilter: string;
begin
  Result := FFilter;
end;

function TfrViewGridBase.GetFiltered: Boolean;
begin
//Los niveles de los grid no se consideran filtros
 if (_Grid.Levels.Count > 1) then
    Result := (_FocusedView.DataController.Filter.Root.Count > 1)
  else
    Result := (_FocusedView.DataController.Filter.Root.Count > 0);
end;

function TfrViewGridBase.GetMultiSelect: Boolean;
begin
  Result := _FocusedView.OptionsSelection.MultiSelect;
end;

function TfrViewGridBase.getNumSeleccionados: Integer;
begin
  Result := _FocusedView.DataController.GetSelectedCount;
end;

function TfrViewGridBase.GetPopupMenu: TPopupMenu;
begin
  Result := FPopupMenu;
end;

function TfrViewGridBase.GetViewFiltros: IViewFiltroBase;
begin
  Result := FViewFiltros;
end;

procedure TfrViewGridBase.GotoFirst;
begin
  if Assigned(_FocusedView) then
    _FocusedView.DataController.GotoFirst;
end;

procedure TfrViewGridBase.GotoLast;
begin
  if Assigned(_FocusedView) then
    _FocusedView.DataController.GotoLast;
end;

procedure TfrViewGridBase.cxGridViewInitStoredObject(Sender: TcxCustomGridView;
  AObject: TObject);
begin
  if AObject is TcxGridDBColumn then
    with TcxGridDBColumn(AObject) do
    begin
      OnGetStoredProperties := cxGridViewColumnGetStoredProperties;
      OnGetStoredPropertyValue := cxGridViewColumnGetStoredPropertyValue;
      OnSetStoredPropertyValue := cxGridViewColumnSetStoredPropertyValue;
    end;
end;

function TfrViewGridBase.IsEmpty: Boolean;
begin
  Result := (_FocusedView.ViewData.RowCount < 1);
end;

function TfrViewGridBase.Locate(const AItemIndex: Integer; const AValue: String;
  const APartialCompare: Boolean): Boolean;
begin
  if Assigned(_FocusedView) then
    Result := (_FocusedView.DataController.FindRecordIndexByText(0, AItemIndex, AValue, APartialCompare, True, True) <> -1)
  else
    Result := False;
end;

procedure TfrViewGridBase.Preview;
begin
//
end;

procedure TfrViewGridBase.Print;
begin
//
end;

procedure TfrViewGridBase.PrintSetup;
begin
//
end;

procedure TfrViewGridBase.RefrescarFiltro;
begin
  //De esta forma obligaremos a que se creen nuevamente todos los filtros, cuando llamemos a este metodo
  if Assigned(ViewFiltros) then
     Filter := ViewFiltros.Texto;
end;

procedure TfrViewGridBase.RestoreFromIniFile;
var
  AIniFile : String;
begin
  if Assigned(_FocusedView) then
  begin

    AIniFile := GetSpecialFolderPath(CSIDL_APPDATA); //[Current Users]\Application Data
    AIniFile := AIniFile + PathDelim + 'Rodax Software' + PathDelim + GetAppName + PathDelim;

    if not DirectoryExists(AIniFile) then
      ForceDirectories(AIniFile);

    _FocusedView.RestoreFromIniFile(AIniFile + 'grid.xml', True, False, []);
  end;
end;

procedure TfrViewGridBase.RestoreFromRegistry(const Path : String);
begin
  if Assigned(_FocusedView) then
    _FocusedView.RestoreFromRegistry(Path + '\\GridSettings\\' + Self.Name, False, False, []);
end;

procedure TfrViewGridBase.StoreToIniFile;
var
  AIniFile : String;
begin
  if Assigned(_FocusedView) then
  begin

    AIniFile := GetSpecialFolderPath(CSIDL_APPDATA); //[Current Users]\Application Data
    AIniFile := AIniFile + PathDelim + 'Rodax Software' + PathDelim + GetAppName + PathDelim;

    if not DirectoryExists(AIniFile) then
      ForceDirectories(AIniFile);

    _FocusedView.StoreToIniFile(AIniFile + 'grid.xml', False, []);
  end;
end;

procedure TfrViewGridBase.StoreToRegistry(const Path : String);
begin
  if Assigned(_FocusedView) then
    _FocusedView.StoreToRegistry(Path + '\\GridSettings\\' + Self.Name, True, []);
end;

procedure TfrViewGridBase.RestoreGridStatus;
begin
  if Assigned(FGridStatus) and (not IsEmpty) then
    FGridStatus.Restore(_FocusedView);
end;

procedure TfrViewGridBase.SaveGridStatus;
begin
  FreeAndNil(FGridStatus);
  if not IsEmpty then
    FGridStatus := TcxGridStatus.Create(_FocusedView);
end;

procedure TfrViewGridBase.SetDblClick(const Value: TNotifyEvent);
begin
  FOnDblClick := Value;
end;

procedure TfrViewGridBase.SetFilter(const Value: string);
begin
  FFilter := Value;

  //Así tendremos el mismo valor en el filtro simple que en el filtro en detalle
  if Assigned(ViewFiltros) then
     ViewFiltros.Texto := FFilter;

  FiltrarGrid(FFilter);

  //Obliga a generar todos los filtros de las vista hija
  AnadirOtrosFiltros;

  if Assigned(FOnFilterChanged) then
    FOnFilterChanged(Self);
end;

procedure TfrViewGridBase.SetMultiSelect(const Value: Boolean);
begin
  _FocusedView.OptionsSelection.MultiSelect := Value;
//  _FocusedView..OnSelectionChanged := SelectionChanged;
end;

procedure TfrViewGridBase.SetPopupMenu(const Value: TPopupMenu);
begin
  FPopupMenu := Value;
end;

procedure TfrViewGridBase.SetViewFiltros(const Value: IViewFiltroBase);
begin
  if Assigned(FViewFiltros) then
     ViewFiltros.OnFiltrosChange := Nil;

  FViewFiltros := Value;
end;

procedure TfrViewGridBase.ShowEmbedded(const AParent: TWinControl);
begin
  inherited;

  // No activar la tabla ya por si acaso tuviera parámetros
{  if not DADataSource.DataTable.Active then
    DADataSource.DataTable.Active := True;}

  GotoFirst;
  _FocusedView.Focused := True;
  if _FocusedView.ViewData.RecordCount > 0 then
  begin
    _FocusedView.ViewData.Records[0].Selected := True;
    _FocusedView.ViewData.Records[0].Focused := True;
  end;
end;


procedure TfrViewGridBase.FiltrarGrid(TextoFiltro : String);
var
  Columna: TcxGridDBColumn;
  i: Integer;
  AItemList: TcxFilterCriteriaItemList;
begin
  with _FocusedView.DataController.Filter do
  begin
    BeginUpdate;
    try
      Options := [fcoCaseInsensitive, fcoSoftCompare];
      Root.Clear;
      if Length(TextoFiltro) > 0 then
      begin
        AItemList := Root.AddItemList(fboAnd);
        AItemList.BoolOperatorKind := fboOr;
        for i:=0 to (_FocusedView as TcxGridDBTableView).ColumnCount - 1 do
        begin
          Columna := (_FocusedView as TcxGridDBTableView).Columns[i];
          if (Length(Columna.Caption) > 0) and (Columna.Caption <> 'RecID') then
             AItemList.AddItem(Columna, foLike, '%'+TextoFiltro+'%', IntToStr(i));
        end;
        Active := True;
      end
      else
        Active := False;
    finally
      EndUpdate;
    end;
  end;
end;


procedure TfrViewGridBase.FilterChanged(Sender: TObject);
begin
//
end;

destructor TfrViewGridBase.Destroy;
begin
  FOnFilterChanged := Nil;
  if Assigned(FGridStatus) then
    FreeAndNil(FGridStatus);  
  inherited;
end;

end.

