unit uViewSumarios;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uViewBase, dxLayoutControl, cxControls, cxContainer, cxListBox,
  TBXDkPanels, ActnList, cxCustomData,  cxGridDBTableView, cxGridTableView,
  cxGraphics, cxStyles, cxTL, cxTextEdit, cxDropDownEdit, ImgList,
  PngImageList, ComCtrls, JvExComCtrls, JvComCtrls, cxInplaceContainer,
  ExtCtrls, cxEdit, cxVGrid, TBXToolPals, uViewControlGrid,
  uViewParametrosControlGrid;

type
  IViewSumarios = interface(IViewParametrosControlGrid)
  ['{4AEE3447-C6A4-491F-87E7-02CD255A7695}']
  end;

  TfrViewSumarios = class(TfrViewParametrosControlGrid, IViewSumarios)
    PngImageList1: TPngImageList;
    vgSumarios: TcxVerticalGrid;
    TBXLabel1: TTBXLabel;
    cxStyleRepository1: TcxStyleRepository;
    cxStyleNombreColumna: TcxStyle;
    cxStyleCategoria: TcxStyle;
    cxStyleNombreColumnaInactivo: TcxStyle;
    cxStyleCategoriaInactivo: TcxStyle;
    cxStyleContentInactivo: TcxStyle;
    procedure vgSumariosEditorRowInitPopup(Sender: TObject);
    procedure vgSumariosEditorRowEditValueChanged(
      Sender: TObject);
  protected
    procedure RellenarArbolTotales;

    function AnadirSumario(const ACaption : String;
      const AKind : TcxSummaryKind) : TcxEditorRow;

    procedure RellenarTotalesPie;
    procedure RellenarTotalesGrupo(const AGroupName : String);
    procedure RellenarCategorias;
    procedure RellenarCategoria(const APosition : TcxSummaryPosition;
      const AGroupName : String = '');

    procedure AplicarSumarioVista(const APosition : TcxSummaryPosition;
      const AColumnCaption : String; const AKind : TcxSummaryKind);
    procedure SetModificable(const Value: Boolean); override;
  public
    procedure Execute; override;
    procedure Refresh; override;
  end;

implementation

{$R *.dfm}

uses
  DB, cxGridPopupMenuConsts;

var
  SumaryKindStrArray : array[skNone..skAverage] of String
    = ('', 'Sumar', 'Mínimo', 'Máximo', 'Contar', 'Promedio');

procedure TfrViewSumarios.Refresh;
begin
  RellenarCategorias;
end;

procedure TfrViewSumarios.RellenarArbolTotales;
var
  i : Integer;
begin
  // Recuperar las agrupaciones del grid
  for i := 0 to ViewControlGrid.GroupedColumnCount - 1 do
  begin
    if i = 3 then
      Break;  // Sólo meter las 3 primera agrupaciones
    RellenarCategoria(spGroup, ViewControlGrid.GroupedColumns[i].Caption);
  end;
end;

function TfrViewSumarios.AnadirSumario(const ACaption : String;
  const AKind : TcxSummaryKind) : TcxEditorRow;
begin
  Result := vgSumarios.Add(TcxEditorRow) as TcxEditorRow;
  with Result do
  begin
    Properties.Caption := ACaption;
    Properties.Value := SumaryKindStrArray[AKind];
    Properties.ImageIndex := 2;
    Properties.EditPropertiesClass := TcxComboBoxProperties;
    with TcxComboBoxProperties(Properties.EditProperties) do
    begin
      ImmediateDropDown := True;
      DropDownListStyle := lsFixedList;
      ImmediatePost := True;
      ImmediateUpdateText := True;
      PostPopupValueOnTab := True;
      OnInitPopup := vgSumariosEditorRowInitPopup;
      OnEditValueChanged := vgSumariosEditorRowEditValueChanged;
    end;
  end;
end;

procedure TfrViewSumarios.AplicarSumarioVista (
  const APosition: TcxSummaryPosition; const AColumnCaption: String;
  const AKind: TcxSummaryKind);
const
  MASK_MONEDA = ',0.## €;-,0.## €';
  MASK_NUMERO = '#,##0';
var
  AColumn : TcxGridDBColumn;
begin
  AColumn := ViewControlGrid.GetColumnByCaption(AColumnCaption);
  if APosition = spFooter then
  begin
    AColumn.Summary.FooterKind := AKind;
    if (AKind in [skSum, skAverage]) and (AColumn.PropertiesClassName = 'TcxCurrencyEditProperties') then
      AColumn.Summary.FooterFormat := MASK_MONEDA
    else
      AColumn.Summary.FooterFormat := MASK_NUMERO;
  end
  else begin
    AColumn.Summary.GroupFooterKind := AKind;
    if (AKind in [skSum, skAverage]) and (AColumn.PropertiesClassName = 'TcxCurrencyEditProperties') then
      AColumn.Summary.GroupFooterFormat := MASK_MONEDA
    else
      AColumn.Summary.GroupFooterFormat := MASK_NUMERO;
  end;
end;

procedure TfrViewSumarios.RellenarTotalesPie;
var
  i, j: Integer;
  ASummary: TcxDataFooterSummaryItems;
  AClase : TcxSummaryKind;
  ACaption : String;
  ACategory : TcxCategoryRow;
  ARow : TcxEditorRow;
begin
  vgSumarios.BeginUpdate;
  try
    ACategory := (vgSumarios.AddChild(nil, TcxCategoryRow) as TcxCategoryRow);
    with ACategory.Properties do
    begin
      ASummary := ViewControlGrid.FocusedView.DataController.Summary.FooterSummaryItems;
      ImageIndex := 0;
      Caption := 'Resúmenes totales'
    end;

    for i := 0 to ViewControlGrid.FocusedView.VisibleColumnCount - 1 do
    begin
      ACaption := ViewControlGrid.FocusedView.VisibleColumns[i].Caption;
      AClase := ViewControlGrid.FocusedView.VisibleColumns[i].Summary.FooterKind;
      ARow := AnadirSumario(ACaption, AClase);
      ARow.Parent := ACategory;
    end;
  finally
    vgSumarios.EndUpdate;
  end;
end;


procedure TfrViewSumarios.RellenarCategoria(
  const APosition: TcxSummaryPosition; const AGroupName: String);
begin
  if APosition = spFooter then
    RellenarTotalesPie
  else
    RellenarTotalesGrupo(AGroupName);
end;

procedure TfrViewSumarios.RellenarCategorias;
var
  i : Integer;
begin
  vgSumarios.ClearRows;
  RellenarCategoria(spFooter);

  // Recuperar las agrupaciones del grid
  for i := 0 to ViewControlGrid.GroupedColumnCount - 1 do
  begin
    if i = 3 then
      Break;  // Sólo meter las 3 primera agrupaciones
    RellenarCategoria(spGroup, ViewControlGrid.GroupedColumns[i].Caption);
  end;
end;

procedure TfrViewSumarios.vgSumariosEditorRowInitPopup(Sender: TObject);
var
  AColumn: TcxGridDBColumn;
  ARow : TcxEditorRow;
const
  NumberFieldTypes =
  [ftSmallint, ftInteger, ftWord, ftFloat, ftCurrency, ftBCD, ftDate, ftTime,
      ftDateTime, ftAutoInc];
  TimeFieldTypes = [ftDate, ftTime, ftDateTime];

begin
  inherited;

  ARow := TcxEditorRow(vgSumarios.FocusedRow);
  AColumn := TcxGridDBColumn(ViewControlGrid.FocusedView.VisibleColumns[ARow.Index]);

  if Assigned(AColumn.DataBinding.Field) then
    with TcxComboBoxProperties(TcxPopupEdit(Sender).Properties) do
    begin
      Items.Clear;
      BeginUpdate;
      try
        Items.Add(SumaryKindStrArray[skNone]);
        Items.Add(SumaryKindStrArray[skCount]);

        if AColumn.DataBinding.Field.DataType in NumberFieldTypes then
        begin
          Items.Add(SumaryKindStrArray[skMax]);
          Items.Add(SumaryKindStrArray[skMin]);
          if not (AColumn.DataBinding.Field.DataType in TimeFieldTypes) then
          begin
            Items.Add(SumaryKindStrArray[skSum]);
            Items.Add(SumaryKindStrArray[skAverage]);
          end;
        end;
      finally
        EndUpdate;
      end;
    end;
end;

procedure TfrViewSumarios.vgSumariosEditorRowEditValueChanged(
  Sender: TObject);
var
  AColumn : String;
  ARow : TcxEditorRow;
  AKind : TcxSummaryKind;

  function DarSummaryKind(AKind : String) : TcxSummaryKind;
  var
    i : TcxSummaryKind;
  begin
    if Length(AKind) = 0 then
      Result := skNone
    else
      for i := skSum to skAverage do
        if SumaryKindStrArray[i] = AKind then
        begin
          Result := i;
          Break;
        end;
  end;

begin
  inherited;

  ARow := TcxEditorRow(vgSumarios.FocusedRow);
  AColumn := ARow.Properties.Caption;
  AKind := DarSummaryKind(VarToStr(ARow.Properties.Value));

  if Assigned(ARow.Parent) then
  begin
    if(ARow.Parent.Index = 0) then
      AplicarSumarioVista(spFooter, AColumn, AKind)
    else
      AplicarSumarioVista(spGroup, AColumn, AKind)
  end;
end;

procedure TfrViewSumarios.RellenarTotalesGrupo(const AGroupName: String);
var
  i, j: Integer;
  ASummary: TcxDataSummaryGroup;
  AClase : TcxSummaryKind;
  ACaption : String;
  ACategory : TcxCategoryRow;
  ARow : TcxEditorRow;

begin
  ASummary := ViewControlGrid.FocusedView.DataController.Summary.SummaryGroups.FindByItemLink(ViewControlGrid.GetColumnByCaption(AGroupName));

  vgSumarios.BeginUpdate;
  try
    ACategory := (vgSumarios.AddChild(nil, TcxCategoryRow) as TcxCategoryRow);
    with ACategory.Properties do
    begin
      ImageIndex := 1;
      Caption := 'Totales de ' + AGroupName;
    end;

    for i := 0 to ViewControlGrid.FocusedView.VisibleColumnCount - 1 do
    begin
      ACaption := ViewControlGrid.FocusedView.VisibleColumns[i].Caption;
      AClase := ViewControlGrid.FocusedView.VisibleColumns[i].Summary.GroupFooterKind;
      ARow := AnadirSumario(ACaption, AClase);
      ARow.Parent := ACategory;
    end;
  finally
    vgSumarios.EndUpdate;
  end;
end;

procedure TfrViewSumarios.Execute;
begin
  inherited;
  //
end;

procedure TfrViewSumarios.SetModificable(const Value: Boolean);
begin
  inherited;
  vgSumarios.Enabled := Value;
  if Value then
  begin
    vgSumarios.Styles.Category := cxStyleCategoria;
    vgSumarios.Styles.Header := cxStyleNombreColumna;
    vgSumarios.Styles.Content := nil;    
  end
  else begin
    vgSumarios.Styles.Category := cxStyleCategoriaInactivo;
    vgSumarios.Styles.Header := cxStyleNombreColumnaInactivo;
    vgSumarios.Styles.Content := cxStyleContentInactivo;
  end;
end;

end.


