unit uViewGrid; 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, dxPSGlbl, dxPSUtl, dxPSEngn, dxPrnPg, dxBkgnd, dxWrap, dxPrnDev, dxPSCompsProvider, dxPSFillPatterns, dxPSEdgePatterns, dxPSCore, dxPScxCommon, dxPScxGridLnk, dxPrnDlg, cxIntlPrintSys3, dxPSPrvwAdv, uViewFiltroBase, TB2Item, TBX, TB2Toolbar, TBXDkPanels, TB2Dock; type IViewGrid = interface(IViewBase) ['{07468FAD-4891-42E6-B646-51F17F0033F5}'] function GetDblClick: TNotifyEvent; function GetFilter: string; function GetPopupMenu: TPopupMenu; function GetGrid : TcxGrid; procedure Preview; procedure Print; procedure PrintSetup; procedure GotoFirst; procedure GotoLast; procedure SetDblClick(const Value: TNotifyEvent); procedure SetFilter(const Value: string); procedure SetPopupMenu(const Value: TPopupMenu); procedure RefreshGrid; function GetMultiSelection: Boolean; procedure SetMultiSelection(const Value: Boolean); property Filter: string read GetFilter write SetFilter; property OnDblClick: TNotifyEvent read GetDblClick write SetDblClick; property PopupMenu: TPopupMenu read GetPopupMenu write SetPopupMenu; property MultiSelection : Boolean read GetMultiSelection write SetMultiSelection; property Grid : TcxGrid read GetGrid; procedure SyncFocusedRecordsFromGrid; procedure SyncFocusedRecordsFromDataSet; procedure StoreToRegistry; procedure RestoreFromRegistry; procedure AjustarAncho; procedure ActivarDesactivarFiltros; function EstanFiltrosVisible: Boolean; end; TfrViewGrid = class(TfrViewBase, IViewGrid) ActionList1: TActionList; cxGrid: TcxGrid; cxGridLevel: TcxGridLevel; cxGridView: TcxGridDBTableView; DADataSource: TDADataSource; dxComponentPrinter: TdxComponentPrinter; dxComponentPrinterLink: TdxGridReportLink; dxPSEngineController1: TdxPSEngineController; cxStyleRepository1: TcxStyleRepository; cxStyleEven: TcxStyle; cxStyleOdd: TcxStyle; cxStyleSelection: TcxStyle; frViewFiltroBase1: TfrViewFiltroBase; pnlAgrupaciones: TTBXDockablePanel; TBXAlignmentPanel1: TTBXAlignmentPanel; TBXToolbar1: TTBXToolbar; TBXItem1: TTBXItem; ActionList2: TActionList; actQuitarAgrupaciones: TAction; procedure cxGridViewDblClick(Sender: TObject); procedure cxGridViewDataControllerSortingChanged(Sender: TObject); procedure SelectionChanged(Sender: TcxCustomGridTableView); virtual; abstract; private FViewFiltros: IViewFiltroBase; FFilter: string; // FOnFilterChanged : TNotifyEvent; FOnDblClick: TNotifyEvent; FPopupMenu: TPopupMenu; procedure FiltrarGrid(TextoFiltro : String); function GetViewFiltros: IViewFiltroBase; procedure SetViewFiltros(const Value: IViewFiltroBase); procedure OnChangeFiltros(Sender: TObject); protected function GetGrid : TcxGrid; function GetDblClick: TNotifyEvent; virtual; function GetFilter: string; virtual; function GetPopupMenu: TPopupMenu; virtual; function GetMultiSelection: Boolean; virtual; procedure SetDblClick(const Value: TNotifyEvent); virtual; procedure SetPopupMenu(const Value: TPopupMenu); virtual; procedure SetMultiSelection(const Value: Boolean); virtual; procedure SetFilter(const Value: string); virtual; procedure RefrescarFiltro; procedure AnadirOtrosFiltros; virtual; function AddFilterGrid(const Operator: tcxFilterBoolOperatorKind): TcxFilterCriteriaItemList; public procedure ShowEmbedded(const AParent : TWinControl); override; constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Preview; procedure Print; procedure PrintSetup; procedure GotoFirst; procedure GotoLast; procedure StoreToRegistry; virtual; procedure RestoreFromRegistry; virtual; property OnDblClick: TNotifyEvent read GetDblClick write SetDblClick; property PopupMenu: TPopupMenu read GetPopupMenu write SetPopupMenu; property Grid : TcxGrid read GetGrid; procedure SyncFocusedRecordsFromGrid; procedure SyncFocusedRecordsFromDataSet; property MultiSelection : Boolean read GetMultiSelection write SetMultiSelection; property ViewFiltros: IViewFiltroBase read GetViewFiltros write SetViewFiltros; property Filter: string read GetFilter write SetFilter; procedure ActivarDesactivarFiltros; function EstanFiltrosVisible: Boolean; procedure RefreshGrid; procedure AjustarAncho; end; procedure Register; var frViewGrid: TfrViewGrid; implementation uses CCReg, uDataModuleBase, uDBSelectionList; {$R *.dfm} { TfrViewGrid } procedure Register; begin RegisterCustomContainer(TfrViewGrid); end; { ********************************* TfrViewGrid ********************************** } constructor TfrViewGrid.Create(AOwner: TComponent); begin inherited; ViewFiltros := frViewFiltroBase1; FFilter := ''; // FOnFilterChanged := FilterChanged; GotoFirst; end; procedure TfrViewGrid.cxGridViewDblClick(Sender: TObject); begin if Assigned(FOnDblClick) then FOnDblClick(Sender); end; procedure TfrViewGrid.FiltrarGrid(TextoFiltro : String); var Columna: TcxGridDBColumn; i: Integer; AItemList: TcxFilterCriteriaItemList; AItemList2: TcxFilterCriteriaItemList; EsPrimera: Boolean; begin with cxGridView.DataController.Filter do begin BeginUpdate; try Options := [fcoCaseInsensitive, fcoSoftCompare]; Root.Clear; if Length(TextoFiltro) > 0 then begin EsPrimera := True; for i:=0 to (cxGridView as TcxGridDBTableView).ColumnCount - 1 do begin Columna := (cxGridView as TcxGridDBTableView).Columns[i]; if Columna.Visible then begin if EsPrimera then begin AItemList := Root; AItemList.BoolOperatorKind := fboAnd; AItemList2 := AItemList.AddItemList(fboAnd); AItemList := AItemList2; AItemList2 := AItemList.AddItemList(fboOr); AItemList := AItemList2; AItemList.AddItem(Columna, foLike, '%'+TextoFiltro+'%', IntToStr(i)); EsPrimera := False; end else begin AItemList2 := AItemList.AddItemList(fboOr); AItemList2.AddItem(Columna, foLike, '%'+TextoFiltro+'%', IntToStr(i)); AItemList := AItemList2; end; end; end; Active := True; end else Active := False; finally EndUpdate; end; end; end; function TfrViewGrid.GetDblClick: TNotifyEvent; begin Result := FOnDblClick; end; function TfrViewGrid.GetFilter: string; begin Result := FFilter; end; function TfrViewGrid.GetPopupMenu: TPopupMenu; begin Result := FPopupMenu; end; procedure TfrViewGrid.GotoFirst; begin cxGridView.DataController.GotoFirst; end; procedure TfrViewGrid.GotoLast; begin cxGridView.DataController.GotoLast; end; procedure TfrViewGrid.SetDblClick(const Value: TNotifyEvent); begin FOnDblClick := Value; end; procedure TfrViewGrid.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; end; procedure TfrViewGrid.SetPopupMenu(const Value: TPopupMenu); begin FPopupMenu := Value; cxGridView.PopupMenu := FPopupMenu; end; procedure TfrViewGrid.cxGridViewDataControllerSortingChanged( Sender: TObject); var i: Integer; AFields: array of String; ADirections: array of TDASortDirection; ABookmark : Pointer; begin inherited; with cxGridView do begin for i := 0 to SortedItemCount - 1 do begin SetLength(AFields, i+1); AFields[i] := (SortedItems[i] as TcxGridDBColumn).DataBinding.FieldName; SetLength(ADirections, i+1); case (SortedItems[i] as TcxGridDBColumn).SortOrder of soAscending : ADirections[i] := sdAscending; soDescending : ADirections[i] := sdDescending; end; end; end; if Assigned(DADataSource.DataTable) then with DADataSource.DataTable do begin DisableControls; ABookmark := GetBookMark; try Sort(AFields, ADirections); GotoBookmark(ABookmark); finally FreeBookmark(ABookmark); EnableControls; end; end; end; function TfrViewGrid.GetGrid: TcxGrid; begin Result := cxGrid; end; procedure TfrViewGrid.ShowEmbedded(const AParent : TWinControl); begin inherited; if not DADataSource.DataTable.Active then DADataSource.DataTable.Active := True; with Grid do begin ActiveView.DataController.GotoFirst; ActiveView.Focused := True; if (ActiveView.ViewData as TcxCustomGridTableViewData).RecordCount > 0 then begin (ActiveView.ViewData as TcxCustomGridTableViewData).Records[0].Selected := True; (ActiveView.ViewData as TcxCustomGridTableViewData).Records[0].Focused := True; end; { if (ActiveView is TcxCustomGridTableView) then (ActiveView as TcxCustomGridTableView).ApplyBestFit;} end; end; procedure TfrViewGrid.Preview; begin dxComponentPrinter.Preview; end; procedure TfrViewGrid.Print; begin dxComponentPrinter.Print(True, nil, nil); end; procedure TfrViewGrid.PrintSetup; begin dxComponentPrinter.PageSetup(nil); end; procedure TfrViewGrid.RefreshGrid; var FocusedRow, TopRow : Integer; begin { Refrescar las filas del grid a partir del dataset y colocar la fila seleccionada donde estaba } if DADataSource.DataTable.State = dsBrowse then begin TopRow := cxGridView.Controller.TopRowIndex; FocusedRow := cxGridView.DataController.FocusedRowIndex; cxGridView.DataController.UpdateItems(False); // <- Refresco cxGridView.DataController.FocusedRowIndex := FocusedRow; cxGridView.Controller.TopRowIndex := TopRow; end; end; procedure TfrViewGrid.SyncFocusedRecordsFromDataSet; var AIndex : Integer; begin { for AIndex := 0 to cxGridView.DataController.RecordCount - 1 do begin if (MessageBox(0, PChar(cxGridView.DataController.GetDisplayText(AIndex, 1)), '', MB_ICONQUESTION or MB_YESNO or MB_DEFBUTTON1) = idYes) then begin cxGridView.DataController.SelectAll; cxGridView.DataController.SelectRows(AIndex, AIndex); cxGridView.DataController.FocusSelectedRow(0); Break; end; end;} end; procedure TfrViewGrid.SyncFocusedRecordsFromGrid; var AValue : Variant; i: Integer; aObj : ISelectedRowList; Clave : String; begin if not Supports(DADataSource.DataTable, ISelectedRowList, aObj) then raise Exception.Create('La tabla no soporta el interfaz ISelectedRowList (SyncFocusedRecords)'); Clave := cxGridView.DataController.KeyFieldNames; if Length(Clave) = 0 then raise Exception.Create('Falta indicar los campos clave de la tabla en la vista del grid (SyncFocusedRecords)'); DADataSource.DataTable.DisableControls; // DADataSource.DataTable.DisableEventHandlers; <- No descomentar try for i := 0 to cxGridView.Controller.SelectedRecordCount - 1 do begin AValue := cxGridView.Controller.SelectedRows[i].Values[cxGridView.GetColumnByFieldName(Clave).Index]; DADataSource.DataTable.First; if DADataSource.DataTable.Locate(Clave, AValue, []) then aObj.SelectedRows.CurrentRowSelected := True; end; finally // DADataSource.DataTable.EnableEventHandlers; <- No descomentar DADataSource.DataTable.EnableControls; end; end; function TfrViewGrid.GetMultiSelection: Boolean; begin Result := (cxGrid.ActiveView as TcxGridDBTableView).OptionsSelection.MultiSelect; end; procedure TfrViewGrid.SetMultiSelection(const Value: Boolean); begin (cxGrid.ActiveView as TcxGridDBTableView).OptionsSelection.MultiSelect := True; (cxGrid.ActiveView as TcxGridDBTableView).OnSelectionChanged := SelectionChanged; end; procedure TfrViewGrid.RestoreFromRegistry; begin cxGridView.RestoreFromRegistry('Software\\FactuGES\\GridSettings\\' + Self.Name, False, False, []); end; procedure TfrViewGrid.StoreToRegistry; begin cxGridView.StoreToRegistry('Software\\FactuGES\\GridSettings\\' + Self.Name, True, []); end; { procedure TfrViewGrid.FilterChanged(Sender: TObject); begin // end; } destructor TfrViewGrid.Destroy; begin // FOnFilterChanged := Nil; ViewFiltros := NIL; inherited; end; procedure TfrViewGrid.AjustarAncho; begin cxGridView.ApplyBestFit; end; function TfrViewGrid.AddFilterGrid(const Operator: tcxFilterBoolOperatorKind): TcxFilterCriteriaItemList; var AItemList: TcxFilterCriteriaItemList; begin AItemList := cxGridView.DataController.Filter.Root; Result := AItemList.AddItemList(Operator); end; procedure TfrViewGrid.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; function TfrViewGrid.GetViewFiltros: IViewFiltroBase; begin Result := FViewFiltros; end; procedure TfrViewGrid.SetViewFiltros(const Value: IViewFiltroBase); begin if Assigned(Value) then begin FViewFiltros := Value; FViewFiltros.OnFiltrosChange := OnChangeFiltros; end else begin FViewFiltros.OnFiltrosChange := Nil; FViewFiltros := Value; end; end; procedure TfrViewGrid.OnChangeFiltros(Sender: TObject); begin cxGridView.DataController.Filter.BeginUpdate; RefrescarFiltro; cxGridView.DataController.Filter.EndUpdate; end; procedure TfrViewGrid.ActivarDesactivarFiltros; begin if Assigned(ViewFiltros) then ViewFiltros.VerFiltros := not ViewFiltros.VerFiltros; end; function TfrViewGrid.EstanFiltrosVisible: Boolean; begin Result := ViewFiltros.VerFiltros; end; procedure TfrViewGrid.AnadirOtrosFiltros; begin // end; end.