/***************************************************************************
                            FLDataTable.h
                          -------------------
 begin                : Sun Jul 1 2001
 copyright            : (C) 2001-2005 by InfoSiAL S.L.
 email                : mail@infosial.com
***************************************************************************/
/***************************************************************************
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; version 2 of the License.               *
 ***************************************************************************/
/***************************************************************************
   Este  programa es software libre. Puede redistribuirlo y/o modificarlo
   bajo  los  términos  de  la  Licencia  Pública General de GNU   en  su
   versión 2, publicada  por  la  Free  Software Foundation.
 ***************************************************************************/

#ifndef FLDATATABLE_H
#define FLDATATABLE_H

#include <qdatatable.h>
#include <qpainter.h>
#include <qpixmapcache.h>
#include <qdatetime.h>
#include <qcolor.h>
#include <qcheckbox.h>

class FLSqlCursor;

/**
Clase que es una redefinicion de la clase QDataTable,
especifica para las necesidades de AbanQ.

@author InfoSiAL S.L.
*/
class FL_EXPORT FLDataTable: public QDataTable {

  Q_OBJECT

public:

  /**
  constructor
  */
  FLDataTable( QWidget * parent = 0, const char *name = 0, bool popup = false );

  /**
  desctructor
  */
  ~FLDataTable();

  /**
  Establece el cursor
  */
  void setFLSqlCursor( FLSqlCursor * c );

  /**
  Establece un filtro persistente que siempre se aplica al cursor antes
  de hacer un refresh
  */
  void setPersistentFilter( const QString & pFilter );

  /**
  Devuelve el cursor
  */
  FLSqlCursor *cursor() const {
    return cursor_;
  }

  /**
  Establece la tabla a sólo lectura o no
  */
  void setFLReadOnly( const bool mode );

  /**
  Establece la tabla a sólo edición o no
  */
  void setEditOnly( const bool mode );

  /**
  Establece la tabla a sólo insercion o no
  */
  void setInsertOnly( const bool mode );

  /**
  Obtiene la lista con las claves primarias de los registros seleccionados por chequeo
  */
  const QValueList<QVariant> primarysKeysChecked() const;

  /**
  Limpia la lista con las claves primarias de los registros seleccionados por chequeo
  */
  void clearChecked();

  /**
  Establece el estado seleccionado por chequeo para un regsitro, indicando el valor de su clave primaria
  */
  void setPrimaryKeyChecked( const QVariant & primaryKeyValue, bool on );

protected:

  /**
  Filtrado de eventos
  */
  bool eventFilter( QObject * o, QEvent * e );

  /**
  Redefinido por conveniencia para pintar la celda
  */
  void paintCell( QPainter * p, int row, int col, const QRect & cr,
                  bool selected, const QColorGroup & cg );

  /**
  Redefinido por conveniencia para pintar el campo
  */
  void paintField( QPainter * p, const QSqlField * field, const QRect & cr, bool );

  /**
  Redefinido por conveniencia, para evitar que aparezca el menu contextual
  con las opciones para editar registros
  */
  void contentsContextMenuEvent( QContextMenuEvent * e );

  /**
  Redefine por conveniencia, el comportamiento al hacer doble clic sobre una
  celda
  */
  void contentsMouseDoubleClickEvent( QMouseEvent * e );

  /**
  Redefinida por conveniencia
  */
  void focusOutEvent( QFocusEvent * );

  /**
  dpinelo: Para guardar los anchos de columnas del usuario
   */
  void saveTableColumnWidth();

private:

  /**
  Numero de la fila (registro) seleccionada actualmente
  */
  int rowSelected;

  /**
  Numero de la columna (campo) seleccionada actualmente
  */
  int colSelected;

  /**
  Cursor, con los registros
  */
  FLSqlCursor *cursor_;

  /**
  Almacena la tabla está en modo sólo lectura
  */
  bool readonly_;

  /**
  Almacena la tabla está en modo sólo edición
  */
  bool editonly_;

  /**
  Indica si la tabla está en modo sólo inserción
  */
  bool insertonly_;

  /**
  Texto del último campo dibujado en la tabla
  */
  QString lastTextPainted;

  /**
  Brochas para el color resaltado de filas
  */
  QBrush bu_;

  /**
  Pixmap precargados
  */
  QPixmap ok;
  QPixmap no;

  /**
  Lista con las claves primarias de los registros seleccionados por chequeo
  */
  QValueList<QVariant> primarysKeysChecked_;

  /**
  Filtro persistente para el cursor
  */
  QString persistentFilter_;

  /**
  Indicador para evitar refrescos anidados
  */
  bool refreshing_;

  /**
  Indica si el componente es emergente ( su padre es un widget del tipo Popup )
  */
  bool popup_;

public slots:

  /**
  Selecciona la fila completa en la que estß la celda activa.

  @param r Fila de la celda activa
  @param c Columna de la celda activa
  */
  void selectRow( int r = -1, int c = -1 );

  /**
  Redefinida por conveniencia
  */
  void setFocus();

  /**
  Redefinida por conveniencia
  */
  void refresh();

  /**
  Hace que la fila seleccionada esté visible
  */
  void ensureRowSelectedVisible();

  /**
  Foco rápido sin refrescos para optimizar
  */
  void setQuickFocus();

  /**
  dpinelo: Establece el ancho de las columnas del usuario
   */
  void setSavedColumnWidths();
    
protected slots:

  /**
  Activado cuando se hace click en el chequeo de la columna de selección
  */
  void setChecked( bool on );

signals:

  /**
  Indica que se ha elegido un registro
  */
  void recordChoosed();

  /**
  Indica que ha cambiado el estado del campo de selección de un registro. Es decir
  se ha incluido o eliminado su clave primaria de la lista de claves primarias seleccionadas.
  Esta señal se emite cuando el usuario hace click en el control de chequeo y cuando se cambia
  programáticamente el chequeo mediante el método FLDataTable::setPrimaryKeyChecked.

  @param  primaryKeyValue El valor de la clave primaria del registro correspondiente
  @param  on  El nuevo estado; TRUE chequeo activado, FALSE chequeo desactivado
  */
  void primaryKeyToggled( const QVariant & primaryKeyValue, bool on );
};

// Uso interno
class FL_EXPORT FLCheckBox: public QCheckBox {

public:

  FLCheckBox( QWidget * parent, int row = 0, const char * name = 0 ) : QCheckBox( parent, name ), row_( row ) {}

  int row() const { return row_; }

protected:

  void drawButton( QPainter * p );
  bool hitButton( const QPoint & pos ) const;

private:

  int row_;
};

#endif
