// -------------------------------------------------------------------------------------
// xsEasyCpp
// Demo de Objeto TablaGenerica
// g++ -g TablaGenerica.cpp -lxseasycpp -LC:/msys64/mingw64/lib -lgtk-3 -lgdk-3 -lz -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32 -lpangowin32-1.0 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lintl -lglib-2.0 -o TablaGenerica.exe
// g++ -g TablaGenerica.cpp %PKG-XSEASYCPP% -o TablaGenerica.exe
// -------------------------------------------------------------------------------------

// Incluye las librería de xsEasyCpp
#include "include/xsEasyCpp.hpp"


// Numerado para las columnas de la tabla
Numerado
{
  COL_CODIGO = 0,
  COL_FECHA,
  COL_NOMBRE,
  COL_EXISTENCIA,
  COL_COSTO,
  COL_PRECIO,
  COL_MEDIDA,
  COL_FUENTE,
  COL_COLOR,
  COL_FONDO,
  COL_ALINEAMIENTO,
  NUM_COLUMNAS
};

// Variable para el Modelo
Estatica xsModeloArbol* modeloDatos = NULO;

// Variable para la tabla
xsTablaGenerica oTablaGenerica;


// Define un vector de celdas para agrega un Renglon
xsCadena renglonTablaGenerica[NUM_COLUMNAS];

// Define la Matriz global
xsMatriz matriz;

// Crea las Entradas
xsEntrada entCodigo;
xsEntrada entFecha;
xsEntrada entNombre;
xsEntrada entExistencia;
xsEntrada entCosto;
xsEntrada entPrecio;
xsEntrada entMedida;

// función para validar si una cadena corresponde a un entero
Logico fnEsEntero(xsCadena cadena);

// función para validar si una cadena corresponde a un flotante
Logico fnEsFlotante(xsCadena cadena);

// función para validar si una cadena corresponde a una fecha
Logico fnEsFecha(xsCadena cadena, Entero formato);

// Función para controlar la Salida de una Ventana
Estatica Vacio fnSalida(xsObjetoGUI* ventana, xsApuntador datos);

// Función para controlar el Cierre de una Ventana
Estatica Entero fnCierre(xsObjetoGUI* ventana, xsEvento* evento);

// Función timer
Estatica Entero fnTimerActualizacion (xsApuntador datos);

// Función para actualizar la Celda del Precio
Estatica Vacio fnCellDataFunc(xsArbolVistaColumna* columna,
                              xsCeldaRenderiza*    celda,
                              xsModeloArbol*       modelo,
                              xsArbolIterador*     iter,
                              xsApuntador          datos);

// Función para cuando se da doble click a un renglon
Vacio fnRenglonDobleClick (xsArbolVista*        tree_view,
                           xsArbolRuta*         path,
                           xsArbolVistaColumna* column,
                           xsApuntador          user_data);

// Función para cuando se cambia de renglón
Vacio fnRenglonSeleccionado(xsArbolVista*        tree_view,
                            xsApuntador          user_data);

// Función para Insertar un Registro
Estatica Vacio fnInsertar(xsObjetoGUI* boton, xsApuntador datos);

// Función para Seleccionar
Estatica Vacio fnSeleccionar(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Eliminar
Estatica Vacio fnEliminar(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Eliminar Todos (limpiar)
Estatica Vacio fnLimpiar(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Eliminar Elemento Seleccionado
Estatica Vacio fnEliminarSeleccionado(xsObjetoGUI* boton, xsApuntador datos);

// Función para Eliminar Elemento Seleccionado
Estatica Vacio fnModificarSeleccionado(xsObjetoGUI* boton, xsApuntador datos);

// Función para Modificar
Estatica Vacio fnModificar(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Insertar un Registro Vacío
Estatica Vacio fnInsertarVacio(xsObjetoGUI* boton, xsApuntador datos);

// Función para Desplegar el Valor de una Celda
Estatica Vacio fnDesplegarValorCelda(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Colocar un Valor en Celda
Estatica Vacio fnColocarValorCelda(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Alinear Celda
Estatica Vacio fnAlinearCelda(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Fuente de la Celda
Estatica Vacio fnFuenteCelda(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Color Fuente Celda
Estatica Vacio fnColorFuenteCelda(xsObjetoGUI* boton, xsApuntador ventana);

// Función para Color Fondo Celda
Estatica Vacio fnColorFondoCelda(xsObjetoGUI* boton, xsApuntador ventana);

// Función principal de xsEasyWindow
xsPrincipal
{
  // Iniciamos xsEasyWindows
  xsAppInicia;

  // Definimos un objeto de la Clase xsVentana
  xsVentana oVentana(XS_CON_CONTENEDOR);

  // Estableciendo un tamaño para la Ventana                                  
  oVentana.colocarDimensiones(700,450);

  // Centrar la Ventana
  oVentana.centrar();

  // Establece el borde de la Ventana
  oVentana.colocarBordeVentana(10);

  // Coloca el Título
  oVentana.colocarTitulo("xsEasyCpp Demo Tabla");

  // Establece el Icono
  oVentana.colocarIcono("img/js.ico");
    
  // Establece la función de Salida
  oVentana.colocarFuncionSalida(XS_FUNCION_RETORNO (fnSalida));

  // Establece la función de Cierre
  oVentana.colocarFuncionCierre(XS_FUNCION_RETORNO (fnCierre));

  // Crea un objeto de Tabla indicando las columnas
  oTablaGenerica.crear(xsObjeto_Lista_crear (NUM_COLUMNAS,
                                             XS_COLUMNA_TIPO_CADENA, // Código
                                             XS_COLUMNA_TIPO_CADENA, // Fecha 
                                             XS_COLUMNA_TIPO_CADENA, // Nombre
                                             XS_COLUMNA_TIPO_CADENA, // Existencia
                                             XS_COLUMNA_TIPO_CADENA, // Costo 
                                             XS_COLUMNA_TIPO_CADENA, // Precio
                                             XS_COLUMNA_TIPO_CADENA, // Medida
                                             XS_COLUMNA_TIPO_CADENA, // Fuente
                                             XS_COLUMNA_TIPO_CADENA,  // Color
                                             XS_COLUMNA_TIPO_CADENA,  // Color
                                             XS_COLUMNA_TIPO_FLOTANTE  // Color
                                             ),NUM_COLUMNAS);  

  // Obtiene el Modelo para actualizar spining
  modeloDatos = XS_ARBOL_MODELO(oTablaGenerica.obtenerListaDatos());

  // Agrega una Columna a la tabla
  oTablaGenerica.agregarColumna("Código",  // Título de la Columna
                                75, // Ancho de la Columns
                                0,  // Alto de la Columna
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_CENTRO,
                                COL_CODIGO,  // Columna de Ordenamiento (-1 Sin Ordenar)
                                "text="+to_string(COL_CODIGO)+",font="+to_string(COL_FUENTE)+",background="+to_string(COL_FONDO)+",xalign="+to_string(COL_ALINEAMIENTO),
                                NULO); // El texto se toma de la Columna 0 del Modelo

  // Agrega una Columna a la tabla
  oTablaGenerica.agregarColumna("Fecha",
                                100,
                                0,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_CENTRO,
                                COL_FECHA, // Columna de Ordenamiento                
                                "text="+to_string(COL_FECHA)+",font="+to_string(COL_FUENTE)+",foreground="+to_string(COL_COLOR),
                                NULO); // El texto se toma de la Columna 1 del Modelo

   // Agrega una Columna a la tabla
   oTablaGenerica.agregarColumna("Nombre",
                                250,
                                0,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_CENTRO,
                                COL_NOMBRE,
                                "text="+to_string(COL_NOMBRE)+",font="+to_string(COL_FUENTE)+",foreground="+to_string(COL_COLOR),
                                NULO);

   // Agrega una Columna a la tabla
   oTablaGenerica.agregarColumna("Existencia",
                                65,
                                0,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_DERECHA,
                                XS_ALINEAMIENTO_CENTRO,
                                COL_EXISTENCIA,
                                "text="+to_string(COL_EXISTENCIA)+",font="+to_string(COL_FUENTE)+",foreground="+to_string(COL_COLOR),
                                NULO);

   // Agrega una Columna a la tabla
   oTablaGenerica.agregarColumna("Costo",
                                65,
                                0,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_DERECHA,
                                XS_ALINEAMIENTO_CENTRO,
                                COL_COSTO,
                                "text="+to_string(COL_COSTO)+",font="+to_string(COL_FUENTE)+",foreground="+to_string(COL_COLOR),
                                NULO);

  // Agrega una Columna a la tabla
  oTablaGenerica.agregarColumna("Precio",
                                65,
                                0,
                                XS_ALINEAMIENTO_IZQUIERDA,
                                XS_ALINEAMIENTO_DERECHA,
                                XS_ALINEAMIENTO_CENTRO,
                                COL_PRECIO,
                                "text="+to_string(COL_PRECIO)+",font="+to_string(COL_FUENTE)+",foreground="+to_string(COL_COLOR),
                                NULO);

  // Agrega una Columna a la tabla
  oTablaGenerica.agregarColumna("Medida",
                                50,
                                0,
                                XS_ALINEAMIENTO_CENTRO,
                                XS_ALINEAMIENTO_CENTRO,
                                XS_ALINEAMIENTO_CENTRO,
                                XS_SIN_ORDENAR_COLUMNA_TABLA,
                                "text="+to_string(COL_MEDIDA)+",font="+to_string(COL_FUENTE)+",foreground="+to_string(COL_COLOR),
                                NULO);

  // Agrego la celda al alrenglon
  renglonTablaGenerica[COL_CODIGO]     = "MB001";
  renglonTablaGenerica[COL_FECHA]      = "2020-12-12";
  renglonTablaGenerica[COL_NOMBRE]     = "REFRESCO COCA COLA BOTE";
  renglonTablaGenerica[COL_EXISTENCIA] = "24";
  renglonTablaGenerica[COL_COSTO]      = "5.00";
  renglonTablaGenerica[COL_PRECIO]     = "12.50";
  renglonTablaGenerica[COL_MEDIDA]     = "PZA";
  renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
  renglonTablaGenerica[COL_COLOR]      = "Green";
  renglonTablaGenerica[COL_FONDO]      = "light gray";
  
  // Inserta el Renglon en la Tabla
  oTablaGenerica.insertarRenglon(renglonTablaGenerica);

  // Agrego otro renglón a la tabla
  renglonTablaGenerica[COL_CODIGO]     = "MB002";
  renglonTablaGenerica[COL_FECHA]      = "2020-12-14";
  renglonTablaGenerica[COL_NOMBRE]     = "REFRESCO COCA COLA 500 ML";
  renglonTablaGenerica[COL_EXISTENCIA] = "44";
  renglonTablaGenerica[COL_COSTO]      = "9.00";
  renglonTablaGenerica[COL_PRECIO]     = "16.50";
  renglonTablaGenerica[COL_MEDIDA]     = "PZA";
  renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
  renglonTablaGenerica[COL_COLOR]      = "Green";
  renglonTablaGenerica[COL_FONDO]      = "light gray";

  // Inserta el Renglon en la Tabla
  oTablaGenerica.insertarRenglon(renglonTablaGenerica);

  // Agrego otro renglón a la tabla
  renglonTablaGenerica[COL_CODIGO]     = "MB003";
  renglonTablaGenerica[COL_FECHA]      = "2020-12-15";
  renglonTablaGenerica[COL_NOMBRE]     = "PINGUINOS";
  renglonTablaGenerica[COL_EXISTENCIA] = "24";
  renglonTablaGenerica[COL_COSTO]      = "7.50";
  renglonTablaGenerica[COL_PRECIO]     = "15.00";
  renglonTablaGenerica[COL_MEDIDA]     = "PZA";
  renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
  renglonTablaGenerica[COL_COLOR]      = "Green";
  renglonTablaGenerica[COL_FONDO]      = "light gray";

  // Inserta el Renglon en la Tabla
  oTablaGenerica.insertarRenglon(renglonTablaGenerica);

  // Agrego otro renglón a la tabla
  renglonTablaGenerica[COL_CODIGO]     = "MB004";
  renglonTablaGenerica[COL_FECHA]      = "2020-12-19";
  renglonTablaGenerica[COL_NOMBRE]     = "GANSITO";
  renglonTablaGenerica[COL_EXISTENCIA] = "18";
  renglonTablaGenerica[COL_COSTO]      = "6.00";
  renglonTablaGenerica[COL_PRECIO]     = "12.00";
  renglonTablaGenerica[COL_MEDIDA]     = "PZA";
  renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
  renglonTablaGenerica[COL_COLOR]      = "blue";
  renglonTablaGenerica[COL_FONDO]      = "light gray";

  // Inserta el Renglon en la Tabla
  oTablaGenerica.insertarRenglon(renglonTablaGenerica);
    
  // Crea una Ventana de Desplazamiento (scroll)
  xsVentanaDesplazamiento scroll(NULO,NULO);
  scroll.colocarDimensiones(500,200);

  // Agrega la tabla a la Ventana
  scroll.agregarEn(oTablaGenerica.obtenerManejador());
	
  // Agrega la tabla al contenedor
  oVentana.agregarAlContenedor(scroll.obtenerManejador());

  // Creamos la Matriz
  matriz.crear();
  matriz.colocarDimensiones(400,0);
  matriz.colocarMargenSuperior(10);
  matriz.colocarMargenInicial(10);

  // Crea las Etiquetas para Insertar
  xsEtiqueta etqCodigo("Código:");
  etqCodigo.colocarDimensiones(75,0);
  etqCodigo.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  xsEtiqueta etqFecha("Fecha:");
  etqFecha.colocarDimensiones(75,0);
  etqFecha.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  xsEtiqueta etqNombre("Nombre:");
  etqNombre.colocarDimensiones(75,0);
  etqNombre.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  xsEtiqueta etqExistencia("Existencia:");
  etqExistencia.colocarDimensiones(75,0);
  etqExistencia.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  xsEtiqueta etqCosto("Costo:");
  etqCosto.colocarDimensiones(75,0);
  etqCosto.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  
  xsEtiqueta etqPrecio("Precio:");
  etqPrecio.colocarDimensiones(75,0);
  etqPrecio.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  xsEtiqueta etqMedida("Medida:");
  etqMedida.colocarDimensiones(75,0);
  etqMedida.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  // Agrega las Etiquetas a la Matriz
  matriz.insertarEn(etqCodigo.obtenerManejador()    ,0,0,1,1);  
  matriz.insertarEn(etqFecha.obtenerManejador()     ,0,1,1,1);
  matriz.insertarEn(etqNombre.obtenerManejador()    ,0,2,1,1);
  matriz.insertarEn(etqExistencia.obtenerManejador(),0,3,1,1);
  matriz.insertarEn(etqCosto.obtenerManejador()     ,0,4,1,1);
  matriz.insertarEn(etqPrecio.obtenerManejador()    ,0,5,1,1);
  matriz.insertarEn(etqMedida.obtenerManejador()    ,0,6,1,1);

  // Crea las Entradas
  entCodigo.crear("Capture Código");
  // Este define ancho de los demás
  entCodigo.colocarDimensiones(300,0); 
  entFecha.crear("Capture Fecha");
  entNombre.crear("Capture Nombre");
  entExistencia.crear("Capture Existencia:");
  entExistencia.colocarAlineamientoTexto(XS_ALINEAMIENTO_DERECHA);
  entCosto.crear("Capture Costo:");
  entCosto.colocarAlineamientoTexto(XS_ALINEAMIENTO_DERECHA);
  entPrecio.crear("Capture Precio:");
  entPrecio.colocarAlineamientoTexto(XS_ALINEAMIENTO_DERECHA);
  entMedida.crear("Capture Medida:");
  
  // Agrega las Entradas y Listas
  matriz.insertarEn(entCodigo.obtenerManejador()    ,1,0,1,1);
  matriz.insertarEn(entFecha.obtenerManejador()     ,1,1,1,1);
  matriz.insertarEn(entNombre.obtenerManejador()    ,1,2,1,1);
  matriz.insertarEn(entExistencia.obtenerManejador(),1,3,1,1);
  matriz.insertarEn(entCosto.obtenerManejador()     ,1,4,1,1);
  matriz.insertarEn(entPrecio.obtenerManejador()    ,1,5,1,1);
  matriz.insertarEn(entMedida.obtenerManejador()    ,1,6,1,1);

  // Agregar la Matriz a la Ventana
  oVentana.agregarAlContenedor(matriz.obtenerManejador());

  // Crea los botones de Operaciones
  xsBoton btnInsertar("Insertar  ",XS_SIN_MNEMONICO);
  xsBoton btnEliminar("Eliminar  ",XS_SIN_MNEMONICO);
  xsBoton btnEliminarSel("Eliminar Seleccionado",XS_SIN_MNEMONICO);
  xsBoton btnModificar("Modificar ",XS_SIN_MNEMONICO);
  xsBoton btnModificarSel("Modificar Seleccionado",XS_SIN_MNEMONICO);
  xsBoton btnEliminarTodos("Eliminar  Todos",XS_SIN_MNEMONICO);
  xsBoton btnSeleccionar("Seleccionar",XS_SIN_MNEMONICO);

  xsBoton btnInsertarVacio("Insertar Vacío",XS_SIN_MNEMONICO);
  xsBoton btnDesplegarValorCelda("Desplegar Valor Celda",XS_SIN_MNEMONICO);
  xsBoton btnColocarValorCelda("Colocar Valor Celda",XS_SIN_MNEMONICO);  
  xsBoton btnAlinearCelda("Alinear Celda de Código",XS_SIN_MNEMONICO);
  xsBoton btnFuenteCelda("Fuente Celda",XS_SIN_MNEMONICO);
  xsBoton btnColorCelda("Color Fuente Celda",XS_SIN_MNEMONICO);
  xsBoton btnColorFondoCelda("Color Fondo  Celda",XS_SIN_MNEMONICO);
  
  // Agrega los Botones de Operación a la Matriz
  matriz.insertarColumna(2);
  matriz.insertarEn(btnInsertar.obtenerManejador()      ,2,0,1,1);
  matriz.insertarEn(btnEliminar.obtenerManejador()      ,2,1,1,1);
  matriz.insertarEn(btnEliminarSel.obtenerManejador()   ,2,2,1,1);
  matriz.insertarEn(btnModificar.obtenerManejador()     ,2,3,1,1);
  matriz.insertarEn(btnModificarSel.obtenerManejador()  ,2,4,1,1);
  matriz.insertarEn(btnEliminarTodos.obtenerManejador() ,2,5,1,1);
  matriz.insertarEn(btnSeleccionar.obtenerManejador()   ,2,6,1,1);

  // No es necesario indicar que se inserte la columna 3
  matriz.insertarEn(btnInsertarVacio.obtenerManejador()      ,3,0,1,1);
  matriz.insertarEn(btnDesplegarValorCelda.obtenerManejador(),3,1,1,1);
  matriz.insertarEn(btnColocarValorCelda.obtenerManejador()  ,3,2,1,1);  
  matriz.insertarEn(btnAlinearCelda.obtenerManejador()       ,3,3,1,1);
  matriz.insertarEn(btnFuenteCelda.obtenerManejador()        ,3,4,1,1);
  matriz.insertarEn(btnColorCelda.obtenerManejador()         ,3,5,1,1);
  matriz.insertarEn(btnColorFondoCelda.obtenerManejador()    ,3,6,1,1);

  // Conectando Señales
  oTablaGenerica.conectarSenal(XS_EVENTO_RENGLON_ACTIVADO,XS_FUNCION_RETORNO(fnRenglonDobleClick),NULO); // Doble Click
  oTablaGenerica.conectarSenal(XS_EVENTO_RENGLON_SELECIONADO,XS_FUNCION_RETORNO(fnRenglonSeleccionado),NULO);
  
  // Botones 1a Columna
  btnInsertar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnInsertar),NULO);
  btnSeleccionar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnSeleccionar),oVentana.obtenerManejador());
  btnEliminar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnEliminar),oVentana.obtenerManejador());
  btnEliminarTodos.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnLimpiar),oVentana.obtenerManejador());
  btnEliminarSel.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnEliminarSeleccionado),NULO);
  btnModificarSel.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnModificarSeleccionado),NULO);
  btnModificar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnModificar),oVentana.obtenerManejador());
  
  // Botones 2a Columna
  btnInsertarVacio.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnInsertarVacio),oVentana.obtenerManejador());
  btnColocarValorCelda.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnColocarValorCelda),oVentana.obtenerManejador());
  btnDesplegarValorCelda.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnDesplegarValorCelda),oVentana.obtenerManejador());
  btnAlinearCelda.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnAlinearCelda),oVentana.obtenerManejador());
  btnFuenteCelda.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnFuenteCelda),oVentana.obtenerManejador());
  btnColorCelda.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnColorFuenteCelda),oVentana.obtenerManejador());
  btnColorFondoCelda.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO(fnColorFondoCelda),oVentana.obtenerManejador());

  // Cierre de la Ventana
  oVentana.conectarSenal(XS_EVENTO_DESTRUIR,xsFuncionSalida, NULO);
  
  // Visualiza las Lineas
  oTablaGenerica.visualizarLineas(VERDAD);

  // Muestra todos los objetos
  oVentana.mostrarTodo();
  
  // Ciclo
  xsAppCiclo;

  // Finaliza retornando 0
  retorna 0;

}


// Detiene el Ciclo Principal iniciado por gtk_main cuando la ventana es destruida
// Puede no ser estática
Estatica Vacio fnSalida(xsObjetoGUI *ventana, xsApuntador datos)
{
    // Llama a la función de la Librería que sale del Ciclo Main  
    xsAppSalida;
}

// Función para controlar el Cierre de una Ventana
Estatica Entero fnCierre(xsObjetoGUI *ventana, xsEvento *evento)
{
    // Para que se cierre, lo contrario para que no se cierre
    retorna Falso; 
}

// Función para controlar la celda
Estatica Vacio fnCellDataFunc(xsArbolVistaColumna* columna,
                              xsCeldaRenderiza*    celda,
                              xsModeloArbol*       modelo,
                              xsArbolIterador*     iter,
                              xsApuntador          data)
 {
    // Variable para el valor numerico flotante
    Flotante  num;

    // Variable para obtener el valor en Texto
    Caracter* texto; 

    /* Get the color string stored by the column and make it the foreground color. */
    xsObjeto_Arbol_obtener_modelo (modelo, iter, COL_PRECIO, &num, XS_FIN_DE_DATOS);
    texto = g_strdup_printf ("%05.2f", num);
    
    xsObjeto_colocar (celda, 
                      "foreground", "#FF0000", 
                      "foreground-set", VERDAD,
                      "text", texto, 
                      NULO);    

    // Liberar el Objeto                  
    xsObjeto_liberar (texto);
 }

// Función para el Doble Click sobre el Renglón
void fnRenglonDobleClick (xsArbolVista*        tree_view,
                          xsArbolRuta*         path,
                          xsArbolVistaColumna* column,
                          xsApuntador          user_data)
{
   // Variable para el iterador del Árbol
   xsArbolIterador iter;

   // Variable para los datos
   Caracter* texto; 
   string    codigo;
   string    fecha;
   string    nombre;
   string    existencia;
   string    costo;
   string    precio;
   string    medida;
      
   // Obtengo el iter
   xsObjeto_Arbol_obtener_iterador (modeloDatos, &iter,path);   

   // Variable para el valor numerico flotante
   Flotante  num;

   // Obteniendo los datos del Renglon
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_CODIGO, &texto, XS_FIN_DE_DATOS);
   codigo = texto;
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_FECHA , &texto, XS_FIN_DE_DATOS);
   fecha = texto;
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_NOMBRE, &texto, XS_FIN_DE_DATOS);
   nombre = texto;
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_EXISTENCIA, &texto, XS_FIN_DE_DATOS);
   existencia = texto;
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_COSTO, &texto, XS_FIN_DE_DATOS);
   costo = texto;
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_PRECIO, &texto, XS_FIN_DE_DATOS);
   precio = texto;
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_MEDIDA, &texto, XS_FIN_DE_DATOS);
   medida = texto;

   // Colocando los datos en las entradas
   entCodigo.colocarTexto(codigo);
   entFecha.colocarTexto(fecha);
   entNombre.colocarTexto(nombre);
   entExistencia.colocarTexto(existencia);   
   entCosto.colocarTexto(costo);
   entPrecio.colocarTexto(texto);
   entMedida.colocarTexto(medida);
      
   // Es indispensable actualizar
   matriz.mostrarTodo();
}

// Función para el Renglón Seleccionado
Vacio fnRenglonSeleccionado(xsArbolVista*        tree_view,
                            xsApuntador          user_data)
{
   xsArbolIterador            iter;
   xsArbolOpcionSeleccionada* seleccionado;
   Caracter*                  texto;    
   string codigo;
   string fecha;
   string nombre;
   string existencia;
   string costo;
   string precio;
   string medida;

   // Obtiene el Elemento Seleccionado
   seleccionado = xsObjeto_ArbolOpciones_obtener_seleccionado (tree_view);

   // Obtiene el Iterador del Elemento Seleccionado
   si (xsObjeto_ArbolOpciones_verifica_seleccionado (seleccionado, &modeloDatos, &iter))
   {
      // Obtiene los datos del Seleccionado
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_CODIGO, &texto, XS_FIN_DE_DATOS);
      codigo = texto;
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_FECHA , &texto, XS_FIN_DE_DATOS);
      fecha = texto;
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_NOMBRE, &texto, XS_FIN_DE_DATOS);
      nombre = texto;
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_EXISTENCIA, &texto, XS_FIN_DE_DATOS);
      existencia = texto;
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_COSTO, &texto, XS_FIN_DE_DATOS);
      costo = texto;
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_PRECIO, &texto, XS_FIN_DE_DATOS);
      precio = texto;
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_MEDIDA, &texto, XS_FIN_DE_DATOS);
      medida = texto;

      // Colocando los datos en las entradas
      entCodigo.colocarTexto(codigo);
      entFecha.colocarTexto(fecha);
      entNombre.colocarTexto(nombre);
      entExistencia.colocarTexto(existencia);   
      entCosto.colocarTexto(costo);
      entPrecio.colocarTexto(precio);
      entMedida.colocarTexto(medida);
      
      // Es indispensable actualizar
      matriz.mostrarTodo();
   } 
}

// Función para Insertar un Registro
Estatica Vacio fnInsertar(xsObjetoGUI* boton, xsApuntador datos)
{
   // Variable para el mensaje
   xsCadena mensaje="";

   // Valida el Código
   si (entCodigo.obtenerLongitudTexto()<=0)
   {
      // Manda el Foco al dato
      entCodigo.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje="El Código \n";      
   }

   // Valida la Fecha
   si (entFecha.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entFecha.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Fecha \n";      
   }
   deOtroModo
      // Valida fecha válida
      si (NO fnEsFecha(entFecha.obtenerTexto(),2))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entFecha.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "La Fecha no es válida (yyyy/mm/dd)\n";      

      }
   
   // Valida el Nombre
   si (entNombre.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entNombre.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Nombre \n";      
   }

   // Valida el Precio
   si (entExistencia.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entExistencia.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Existencia \n";      
   }
   deOtroModo
      si (NO fnEsEntero(entExistencia.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entExistencia.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "La Existencia deben ser un número \n";      
      }

   // Valida el Costo
   si (entCosto.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entCosto.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Costo \n";      
   }
   deOtroModo
      si (NO fnEsFlotante(entCosto.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entCosto.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje= mensaje + "El Costo de ser un número decimal \n";      
      }

   // Valida el Precio
   si (entPrecio.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entPrecio.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Precio \n";      
   }
   deOtroModo
      si (NO fnEsFlotante(entPrecio.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entPrecio.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "El Precio de ser un número decimal \n";      
      }


   // Valida la Medida
   si (entMedida.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entMedida.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Medida \n";      
   }

   // Verifica si hay mostrar el Mensaje
   si (mensaje.length()>0)
   {
      // Actualiza el Mensaje
      mensaje ="Debe capturar los siguientes datos:\n"+mensaje;

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla Genérica",mensaje);      
   }
   deOtroModo
   {
      // Creo el Renglón con los datos de Entrada
      renglonTablaGenerica[COL_CODIGO]     = entCodigo.obtenerTexto();
      renglonTablaGenerica[COL_FECHA]      = entFecha.obtenerTexto();
      renglonTablaGenerica[COL_NOMBRE]     = entNombre.obtenerTexto();
      renglonTablaGenerica[COL_EXISTENCIA] = entExistencia.obtenerTexto();
      renglonTablaGenerica[COL_COSTO]      = entCosto.obtenerTexto();
      renglonTablaGenerica[COL_PRECIO]     = entPrecio.obtenerTexto();
      renglonTablaGenerica[COL_MEDIDA]     = entMedida.obtenerTexto();
      renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
      renglonTablaGenerica[COL_COLOR]      = "Blue";
  
      // Inserta el Renglon en la Tabla
      oTablaGenerica.insertarRenglon(renglonTablaGenerica);
      oTablaGenerica.mostrarTodo();      

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla Genérica","El Registro ha sido agregado");
   }
}

// Función para Seleccionar
Estatica Vacio fnSeleccionar(xsObjetoGUI* boton, xsApuntador ventana)
{
  // Variable para el Número
  xsCadena numero;

  // Variable para la posición entera del numero
  Entero   posicion;

  // Declaro un Dialogo Nuevo
  xsDialogos dlgUsuario;

  // Creo el Dialogo
  dlgUsuario.crear("Capture el Número de Renglón a Seleccionar",
                   XS_VENTANA(ventana),
                   XS_DIALOGO_DESTRUIR_CON_PADRE,
                   "Aceptar",
                   XS_BOTON_RESPUESTA_ACEPTAR);

  // Agregar el botón de Cancelar
  dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

  // Declara y creo el contenedor para el diálogo
  xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

  // Asigna el Contenedor al Dialogo
  dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
  
  // Establece el borde
  contenedorDlg.colocarBorde(18);

  // Crea una imagen
  xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

  // Agrega la imagen al contenedor
  contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

  // Crea una matriz
  xsMatriz matriz;
  matriz.crear();

  // Coloca espaciamiento entre Renglones y Columnas
  matriz.colocarEspaciosEntreRenglones(4);
  matriz.colocarEspaciosEntreColumnas(4);

  // Se agrega la matriz al contenedor
  contenedorDlg.insertarEnEl(matriz.obtenerManejador());

  // Declaro 1 Etiqueta
  xsEtiqueta etqNumero("Numero :");

  // Agrega las etiquetas a la Matriz
  matriz.insertarEn(etqNumero.obtenerManejador(),0,0,1,1);

  // Declaro 1 Entrada
  xsEntrada entNumeroSeleccionar("");

  // Se agregan las entradas a la matriz
  matriz.insertarEn(entNumeroSeleccionar.obtenerManejador(),1,0,1,1);
     
  // Muestra todo el Contenedor
  contenedorDlg.mostrarTodo();

  // Ejecuta el Diálogo
  Entero respuesta = dlgUsuario.ejecutar();

  // Verifica que haya aceptado
  si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
     // Obtiene el Número
     numero = entNumeroSeleccionar.obtenerTexto();     
  
  // Verifica si hay algo en numero
  si (numero.length() > 0)
     // Verifica que sean solo numeros
     si (fnEsEntero(numero))
     {        
        // Convierte a entero
        posicion = atoi(numero.c_str());

        // Verifica que la posición a seleccionar este dentro del rango
        si (posicion >= 0 && posicion < oTablaGenerica.longitud())        
            // Selecciona un Registro
            oTablaGenerica.seleccionar(numero);
        
        deOtroModo
            xsVentana::mensajeInformacion("Demo Tabla Genérica","El número está fuera de rango");        
     }
     deOtroModo
        xsVentana::mensajeInformacion("Demo Tabla Genérica","Capture solo Numeros");    
  
  // Destruye el diálogo
  dlgUsuario.destruir();
}



// Función para Eliminar
Estatica Vacio fnEliminar(xsObjetoGUI* boton, xsApuntador ventana)
{
  // Variable para el Número
  xsCadena numero;

  // Variable para la posición entera del numero
  Entero   posicion;

  // Declaro un Dialogo Nuevo
  xsDialogos dlgUsuario;

  // Creo el Dialogo
  dlgUsuario.crear("Capture el Número de Renglón a Eliminar",
                   XS_VENTANA(ventana),
                   XS_DIALOGO_DESTRUIR_CON_PADRE,
                   "Aceptar",
                   XS_BOTON_RESPUESTA_ACEPTAR);

  // Agregar el botón de Cancelar
  dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

  // Declara y creo el contenedor para el diálogo
  xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

  // Asigna el Contenedor al Dialogo
  dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
  
  // Establece el borde
  contenedorDlg.colocarBorde(18);

  // Crea una imagen
  xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

  // Agrega la imagen al contenedor
  contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

  // Crea una matriz
  xsMatriz matriz;
  matriz.crear();

  // Coloca espaciamiento entre Renglones y Columnas
  matriz.colocarEspaciosEntreRenglones(4);
  matriz.colocarEspaciosEntreColumnas(4);

  // Se agrega la matriz al contenedor
  contenedorDlg.insertarEnEl(matriz.obtenerManejador());

  // Declaro 1 Etiqueta
  xsEtiqueta etqNumero("Numero :");

  // Agrega las etiquetas a la Matriz
  matriz.insertarEn(etqNumero.obtenerManejador(),0,0,1,1);

  // Declaro 1 Entrada
  xsEntrada entNumeroEliminar("");

  // Se agregan las entradas a la matriz
  matriz.insertarEn(entNumeroEliminar.obtenerManejador(),1,0,1,1);
     
  // Muestra todo el Contenedor
  contenedorDlg.mostrarTodo();

  // Ejecuta el Diálogo
  Entero respuesta = dlgUsuario.ejecutar();

  si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
     numero = entNumeroEliminar.obtenerTexto();     
  
  // Verifica si hay algo en numero
  si (numero.length() > 0)
     // Verifica que sean solo numeros
     si (fnEsEntero(numero))
     {        
        // Convierte a entero
        posicion = atoi(numero.c_str());

        // Verifica que la posición a seleccionar este dentro del rango
        si (posicion >= 0 && posicion < oTablaGenerica.longitud())        
            // Selecciona un Registro
            oTablaGenerica.eliminar(numero);        
        deOtroModo
            xsVentana::mensajeInformacion("Demo Tabla Genérica","El número está fuera de rango");        
     }
     deOtroModo
        xsVentana::mensajeInformacion("Demo Tabla Genérica","Capture solo Numeros");
    
  // Destruye el diálogo
  dlgUsuario.destruir();
}


// Función para Limpiar
Estatica Vacio fnLimpiar(xsObjetoGUI* boton, xsApuntador ventana)
{
   // VAriable para respuesta
   Entero respuesta;
    
   // Despliega el Mensaje Pregunta y obtiene la respuesta
   respuesta = xsVentana::mensajePregunta("Demo Tabla Genérica","¿ Desea eliminar todos los Registros ?");        

   // Verifica que contesto
   si (respuesta==xsVentana::BOTON_SI)                                  
      // Limpia los Registros
      oTablaGenerica.limpiar();
}

// Función para Eliminar Elemento Seleccionado
Estatica Vacio fnEliminarSeleccionado(xsObjetoGUI* boton, xsApuntador datos)
{
   // VAriable para respuesta
   Entero respuesta;
    
   // Despliega el Mensaje Pregunta y obtiene la respuesta
   respuesta = xsVentana::mensajePregunta("Demo Tabla Genérica","¿ Desea eliminar el Elemento Seleccionado ?");        

   // Verifica que contesto
   si (respuesta==xsVentana::BOTON_SI)                                  
      // Limpia los Registros
      oTablaGenerica.eliminarRenglonSeleccionado();
}

// Función para Modificar el Renglón Seleccionado
Estatica Vacio fnModificarSeleccionado(xsObjetoGUI* boton, xsApuntador datos)
{
   // Variable para el mensaje
   xsCadena mensaje="";

   // Valida el Código
   si (entCodigo.obtenerLongitudTexto()<=0)
   {
      // Manda el Foco al dato
      entCodigo.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje="El Código \n";      
   }

   // Valida la Fecha
   si (entFecha.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entFecha.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Fecha \n";      
   }
   
   // Valida el Nombre
   si (entNombre.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entNombre.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Nombre \n";      
   }

   // Valida el Precio
   si (entExistencia.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entExistencia.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Existencia \n";      
   }
   deOtroModo
      si (NO fnEsEntero(entExistencia.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entExistencia.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "La Existencia deben ser un número \n";      
      }

   // Valida el Costo
   si (entCosto.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entCosto.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Costo \n";      
   }
   deOtroModo
      si (NO fnEsFlotante(entCosto.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entCosto.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "El Costo de ser un número decimal \n";      
      }

   // Valida el Precio
   si (entPrecio.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entPrecio.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Precio \n";      
   }
   deOtroModo
      si (NO fnEsFlotante(entPrecio.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entPrecio.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "El Precio de ser un número decimal \n";      
      }


   // Valida la Medida
   si (entMedida.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entMedida.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Medida \n";      
   }

   // Verifica si hay mostrar el Mensaje
   si (mensaje.length()>0)
   {
      // Actualiza el Mensaje
      mensaje ="Debe capturar los siguientes datos:\n"+mensaje;

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla Genérica",mensaje);
      
   }
   deOtroModo
   {
      // Agrego la celda al alrenglon
      renglonTablaGenerica[COL_CODIGO]     = entCodigo.obtenerTexto();
      renglonTablaGenerica[COL_FECHA]      = entFecha.obtenerTexto();
      renglonTablaGenerica[COL_NOMBRE]     = entNombre.obtenerTexto();
      renglonTablaGenerica[COL_EXISTENCIA] = entExistencia.obtenerTexto();
      renglonTablaGenerica[COL_COSTO]      = entCosto.obtenerTexto();
      renglonTablaGenerica[COL_PRECIO]     = entPrecio.obtenerTexto();
      renglonTablaGenerica[COL_MEDIDA]     = entMedida.obtenerTexto();
      renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
      renglonTablaGenerica[COL_COLOR]      = "Green";
              
      // Modifica el Renglón Seleccionado
      oTablaGenerica.modificarRenglonSeleccionado(renglonTablaGenerica);
      oTablaGenerica.mostrarTodo();

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla Genérica","El Registro ha sido modificado");
   }
}

// Función para Modificar
Estatica Vacio fnModificar(xsObjetoGUI* boton, xsApuntador ventana)
{
   // Variable para el Número
   xsCadena numero;

   // Variable para la posición entera del numero
   Entero   posicion;

   // Variable para el mensaje
   xsCadena mensaje="";

   
   // Valida el Código
   si (entCodigo.obtenerLongitudTexto()<=0)
   {
      // Manda el Foco al dato
      entCodigo.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje="El Código \n";      
   }

   // Valida la Fecha
   si (entFecha.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entFecha.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Fecha \n";      
   }
   
   // Valida el Nombre
   si (entNombre.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entNombre.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Nombre \n";      
   }

   // Valida la Existencia
   si (entExistencia.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entExistencia.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Existencia \n";      
   }
   deOtroModo
      si (NO fnEsEntero(entExistencia.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entExistencia.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "La Existencia deben ser un número \n";      
      }

   // Valida el Costo
   si (entCosto.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entCosto.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Costo \n";      
   }
   deOtroModo
      si (NO fnEsFlotante(entCosto.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entCosto.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "El Costo de ser un número decimal \n";      
      }

   // Valida el Precio
   si (entPrecio.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entPrecio.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "El Precio \n";      
   }
   deOtroModo
      si (NO fnEsFlotante(entPrecio.obtenerTexto()))
      {
         // Valida si debe enviar el foco
         si (mensaje.length()==0)
            // Manda el Foco
            entPrecio.colocarFoco();

         // Agrega el Dato al Mensaje
         mensaje = mensaje + "El Precio de ser un número decimal \n";      
      }


   // Valida la Medida
   si (entMedida.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      si (mensaje.length()==0)
         // Manda el Foco
         entMedida.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje = mensaje + "La Medida \n";      
   }

   // Verifica si hay mostrar el Mensaje
   si (mensaje.length()>0)
   {
      // Actualiza el Mensaje
      mensaje ="Debe capturar los siguientes datos:\n"+mensaje;

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla Genérica",mensaje);
      
   }
   deOtroModo
   {
      // Declaro un Dialogo Nuevo
      xsDialogos dlgUsuario;

      // Creo el Dialogo
      dlgUsuario.crear("Capture el Número de Renglón a Modificar",
                        XS_VENTANA(ventana),
                        XS_DIALOGO_DESTRUIR_CON_PADRE,
                        "Aceptar",
                        XS_BOTON_RESPUESTA_ACEPTAR);

      // Agregar el botón de Cancelar
      dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

      // Declara y creo el contenedor para el diálogo
      xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

      // Asigna el Contenedor al Dialogo
      dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
      
      // Establece el borde
      contenedorDlg.colocarBorde(18);

      // Crea una imagen
      xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

      // Agrega la imagen al contenedor
      contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

      // Crea una matriz
      xsMatriz matriz;
      matriz.crear();

      // Coloca espaciamiento entre Renglones y Columnas
      matriz.colocarEspaciosEntreRenglones(4);
      matriz.colocarEspaciosEntreColumnas(4);

      // Se agrega la matriz al contenedor
      contenedorDlg.insertarEnEl(matriz.obtenerManejador());

      // Declaro 1 Etiqueta
      xsEtiqueta etqNumero("Numero :");

      // Agrega las etiquetas a la Matriz
      matriz.insertarEn(etqNumero.obtenerManejador(),0,0,1,1);

      // Declaro 1 Entrada
      xsEntrada entNumeroModificar("");

      // Se agregan las entradas a la matriz
      matriz.insertarEn(entNumeroModificar.obtenerManejador(),1,0,1,1);
         
      // Muestra todo el Contenedor
      contenedorDlg.mostrarTodo();

      // Ejecuta el Diálogo
      Entero respuesta = dlgUsuario.ejecutar();

      si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
         numero = entNumeroModificar.obtenerTexto();     
      
      // Verifica si hay algo en numero
      si (numero.length() > 0)

         // Verifica que sean solo numeros
         si (fnEsEntero(numero))
         {        
            // Convierte a entero
            posicion = atoi(numero.c_str());

            // Verifica que la posición a seleccionar este dentro del rango
            si (posicion >= 0 && posicion < oTablaGenerica.longitud())        
            {
                  // Creo el Renglón con los datos de Entrada
                  renglonTablaGenerica[COL_CODIGO]     = entCodigo.obtenerTexto();
                  renglonTablaGenerica[COL_FECHA]      = entFecha.obtenerTexto();
                  renglonTablaGenerica[COL_NOMBRE]     = entNombre.obtenerTexto();
                  renglonTablaGenerica[COL_EXISTENCIA] = entExistencia.obtenerTexto();
                  renglonTablaGenerica[COL_COSTO]      = entCosto.obtenerTexto();
                  renglonTablaGenerica[COL_PRECIO]     = entPrecio.obtenerTexto();
                  renglonTablaGenerica[COL_MEDIDA]     = entMedida.obtenerTexto();
                  renglonTablaGenerica[COL_FUENTE]     = "Lucida Console 10";
                  renglonTablaGenerica[COL_COLOR]      = "Red";
            
                  // Modifica el Renglon en la Tabla
                  oTablaGenerica.modificarRenglon(atoi(numero.c_str()), renglonTablaGenerica);        
                  oTablaGenerica.mostrarTodo();                  
            }    
            deOtroModo
                  xsVentana::mensajeInformacion("Demo Tabla Genérica","El número está fuera de rango");        
         }
         deOtroModo
            xsVentana::mensajeInformacion("Demo Tabla Genérica","Capture solo Numeros");
         
      // Destruye el diálogo
      dlgUsuario.destruir();
      
   }
}


// Función para Insertar un Registro Vacío
Estatica Vacio fnInsertarVacio(xsObjetoGUI* boton, xsApuntador datos)
{
   // Inserta un Renglón vacío a la tabla
   oTablaGenerica.insertarRenglon();
}


// Función para Desplegar el Valor de una Celda
Estatica Vacio fnDesplegarValorCelda(xsObjetoGUI* boton, xsApuntador ventana)
{
   // Enteros para renglon y columna
   xsCadena renglonCadena, columnaCadena;
   xsCadena mensaje="";
   xsCadena valorCelda;

   // Declaro un Dialogo Nuevo
   xsDialogos dlgUsuario;

   // Creo el Dialogo
   dlgUsuario.crear("Capture el Número de Renglón y Columna a Desplegar",
                     XS_VENTANA(ventana),
                     XS_DIALOGO_DESTRUIR_CON_PADRE,
                     "Aceptar",
                     XS_BOTON_RESPUESTA_ACEPTAR);

   // Agregar el botón de Cancelar
   dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

   // Declara y creo el contenedor para el diálogo
   xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

   // Asigna el Contenedor al Dialogo
   dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
   
   // Establece el borde
   contenedorDlg.colocarBorde(18);

   // Crea una imagen
   xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

   // Agrega la imagen al contenedor
   contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

   // Crea una matriz
   xsMatriz matriz;
   matriz.crear();

   // Coloca espaciamiento entre Renglones y Columnas
   matriz.colocarEspaciosEntreRenglones(4);
   matriz.colocarEspaciosEntreColumnas(4);

   // Se agrega la matriz al contenedor
   contenedorDlg.insertarEnEl(matriz.obtenerManejador());

   // Declaro Etiqueta de Renglon
   xsEtiqueta etqRenglon("Renglón :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqRenglon.obtenerManejador(),0,0,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entRenglon("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entRenglon.obtenerManejador(),1,0,1,1);

   // Declaro Etiqueta de Columna
   xsEtiqueta etqColumna("Columna :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqColumna.obtenerManejador(),0,1,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entColumna("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entColumna.obtenerManejador(),1,1,1,1);
      
   // Muestra todo el Contenedor
   contenedorDlg.mostrarTodo();

   // Ejecuta el Diálogo
   Entero respuesta = dlgUsuario.ejecutar();

   // Verifica si la respuesta fué aceptar
   si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
   {
       // Obtiene los datos   
       renglonCadena = entRenglon.obtenerTexto();     
       columnaCadena = entColumna.obtenerTexto();
   }      

   // Valida
   si (renglonCadena.length() <= 0)
      mensaje = "El Renglón\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(renglonCadena))         
         // Agrega el Mensaje
         mensaje ="El Renglón no es numérico\n";      
      deOtroModo
         si (atoi(renglonCadena.c_str())<0 || 
             atoi(renglonCadena.c_str())>=oTablaGenerica.longitud())         
            // Agrega el Mensaje
            mensaje ="El Renglón está fuera de rango\n";      

   si (columnaCadena.length() <= 0)
      mensaje = mensaje + "La Columna\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(columnaCadena))         
         // Agrega el Mensaje
         mensaje = mensaje + "La Columna no es numérica\n";      
      deOtroModo
         si (atoi(columnaCadena.c_str()) < 0 || 
             atoi(columnaCadena.c_str()) > 6)         
            // Agrega el Mensaje
            mensaje = mensaje + "La Columna está fuera de rango\n";               
   

   // Verifica si hay algo en numero
   si (mensaje.length() <= 0)
   {
      // Obtengo el valor de la celda
      valorCelda = oTablaGenerica.obtenerCelda(atoi(renglonCadena.c_str()),
                                               atoi(columnaCadena.c_str()));

      // Desplegando
      xsVentana::mensajeInformacion("Demo Tabla Genérica","El valor de la Celda es:\n"+valorCelda);
   }
   deOtroModo
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Los siguientes datos no son correctos:\n"+mensaje);
      
   // Destruye el diálogo
   dlgUsuario.destruir();
}

// Función para Colocar un Valor en Celda
Estatica Vacio fnColocarValorCelda(xsObjetoGUI* boton, xsApuntador ventana)
{
   // Enteros para renglon y columna
   xsCadena renglonCadena, columnaCadena;
   xsCadena mensaje="";
   xsCadena valorCelda;

   // Declaro un Dialogo Nuevo
   xsDialogos dlgUsuario;

   // Creo el Dialogo
   dlgUsuario.crear("Capture el Número de Renglón, Columna y Dato a Colocar",
                     XS_VENTANA(ventana),
                     XS_DIALOGO_DESTRUIR_CON_PADRE,
                     "Aceptar",
                     XS_BOTON_RESPUESTA_ACEPTAR);

   // Agregar el botón de Cancelar
   dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

   // Declara y creo el contenedor para el diálogo
   xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

   // Asigna el Contenedor al Dialogo
   dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
   
   // Establece el borde
   contenedorDlg.colocarBorde(18);

   // Crea una imagen
   xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

   // Agrega la imagen al contenedor
   contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

   // Crea una matriz
   xsMatriz matriz;
   matriz.crear();

   // Coloca espaciamiento entre Renglones y Columnas
   matriz.colocarEspaciosEntreRenglones(4);
   matriz.colocarEspaciosEntreColumnas(4);

   // Se agrega la matriz al contenedor
   contenedorDlg.insertarEnEl(matriz.obtenerManejador());

   // Declaro Etiqueta de Renglon
   xsEtiqueta etqRenglon("Renglón :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqRenglon.obtenerManejador(),0,0,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entRenglon("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entRenglon.obtenerManejador(),1,0,1,1);

   // Declaro Etiqueta de Columna
   xsEtiqueta etqColumna("Columna :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqColumna.obtenerManejador(),0,1,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entColumna("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entColumna.obtenerManejador(),1,1,1,1);

   // Declaro Etiqueta de Valor
   xsEtiqueta etqValor("Valor :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqValor.obtenerManejador(),0,2,1,1);

   // Declaro Entrada de Valor
   xsEntrada entValor("");

   // Se agregan la entrada a la matriz
   matriz.insertarEn(entValor.obtenerManejador(),1,2,1,1);
      
   // Muestra todo el Contenedor
   contenedorDlg.mostrarTodo();

   // Ejecuta el Diálogo
   Entero respuesta = dlgUsuario.ejecutar();

   // Verifica si la respuesta fué aceptar
   si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
   {
       // Obtiene los datos   
       renglonCadena = entRenglon.obtenerTexto();     
       columnaCadena = entColumna.obtenerTexto();
       valorCelda = entValor.obtenerTexto();
   }      

   // Valida
   si (renglonCadena.length() <= 0)
      mensaje = "El Renglón\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(renglonCadena))         
         // Agrega el Mensaje
         mensaje ="El Renglón no es numérico\n";      
      deOtroModo
         si (atoi(renglonCadena.c_str())<0 || 
             atoi(renglonCadena.c_str())>=oTablaGenerica.longitud())         
            // Agrega el Mensaje
            mensaje ="El Renglón está fuera de rango\n";      

   si (columnaCadena.length() <= 0)
      mensaje = mensaje + "La Columna\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(columnaCadena))         
         // Agrega el Mensaje
         mensaje = mensaje + "La Columna no es numérica\n";      
      deOtroModo
         si (atoi(columnaCadena.c_str()) < 0 || 
             atoi(columnaCadena.c_str()) > 6)         
            // Agrega el Mensaje
            mensaje = mensaje + "La Columna está fuera de rango\n";               
   
   si (valorCelda.length() <= 0)
      mensaje = mensaje + "El Valor\n";
   
   // Verifica si hay algo en numero
   si (mensaje.length() <= 0)
   {
      // Coloco el valor de la Celda
      oTablaGenerica.colocarCelda(valorCelda,atoi(renglonCadena.c_str()),
                                             atoi(columnaCadena.c_str()));

      // Desplegando
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Se ha modificado el valor de la celda");
   }
   deOtroModo
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Los siguientes datos no son correctos:\n"+mensaje);
      
   // Destruye el diálogo
   dlgUsuario.destruir();

}

// Función para Alinear Celda
Estatica Vacio fnAlinearCelda(xsObjetoGUI* boton, xsApuntador ventana)
{
   // Enteros para renglon y columna
   xsCadena renglon;
   xsCadena mensaje="";
   xsCadena alineamiento;

   // Declaro un Dialogo Nuevo
   xsDialogos dlgUsuario;

   // Creo el Dialogo
   dlgUsuario.crear("Capture el Número de Renglón y Alineamiento (Valor decimal entre 0 y 1)",
                     XS_VENTANA(ventana),
                     XS_DIALOGO_DESTRUIR_CON_PADRE,
                     "Aceptar",
                     XS_BOTON_RESPUESTA_ACEPTAR);

   // Agregar el botón de Cancelar
   dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

   // Declara y creo el contenedor para el diálogo
   xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

   // Asigna el Contenedor al Dialogo
   dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
   
   // Establece el borde
   contenedorDlg.colocarBorde(18);

   // Crea una imagen
   xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

   // Agrega la imagen al contenedor
   contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

   // Crea una matriz
   xsMatriz matriz;
   matriz.crear();

   // Coloca espaciamiento entre Renglones y Columnas
   matriz.colocarEspaciosEntreRenglones(4);
   matriz.colocarEspaciosEntreColumnas(4);

   // Se agrega la matriz al contenedor
   contenedorDlg.insertarEnEl(matriz.obtenerManejador());

   // Declaro Etiqueta de Renglon
   xsEtiqueta etqRenglon("Renglón :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqRenglon.obtenerManejador(),0,0,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entRenglon("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entRenglon.obtenerManejador(),1,0,1,1);
   
   // Declaro Etiqueta de Alineamiento
   xsEtiqueta etqAlineamiento("Alineamiento :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqAlineamiento.obtenerManejador(),0,1,1,1);

   // Declaro Entrada de Valor
   xsEntrada entAlineamiento("");

   // Se agregan la entrada a la matriz
   matriz.insertarEn(entAlineamiento.obtenerManejador(),1,1,1,1);
      
   // Muestra todo el Contenedor
   contenedorDlg.mostrarTodo();

   // Ejecuta el Diálogo
   Entero respuesta = dlgUsuario.ejecutar();

   // Verifica si la respuesta fué aceptar
   si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
   {
       // Obtiene los datos   
       renglon = entRenglon.obtenerTexto();     
       alineamiento = entAlineamiento.obtenerTexto();
   }      

   // Valida
   si (renglon.length() <= 0)
      mensaje = "El Renglón\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(renglon))         
         // Agrega el Mensaje
         mensaje ="El Renglón no es numérico\n";      
      deOtroModo
         si (atoi(renglon.c_str())<0 || 
             atoi(renglon.c_str())>=oTablaGenerica.longitud())         
            // Agrega el Mensaje
            mensaje ="El Renglón está fuera de rango\n";      

   si (alineamiento.length() <= 0)
      mensaje = mensaje + "El Valor\n";
   deOtroModo
      // Valida que sea flotante
      si (NO fnEsFlotante(alineamiento))         
         // Agrega el Mensaje
         mensaje ="El Alineamiento no es flotante\n";      
      deOtroModo
         // Verifica el valor   
         si (atof(alineamiento.c_str()) > 1 || 
             atof(alineamiento.c_str()) < 0)   
             // Agrega el Mensaje
             mensaje ="El Valor debe ser entre 0 y 1\n";            
   
   // Verifica si hay algo en numero
   si (mensaje.length() <= 0)
   {
      // Coloco el valor de la Celda
      oTablaGenerica.colocarAtributoFlotante(atof(alineamiento.c_str()),
                                             atoi(renglon.c_str()),
                                             COL_ALINEAMIENTO);

      // Desplegando
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Se ha modificado el valor de la celda");
   }
   deOtroModo
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Los siguientes datos no son correctos:\n"+mensaje);
      
   // Destruye el diálogo
   dlgUsuario.destruir();

}

// Función para Fuente de la Celda
Estatica Vacio fnFuenteCelda(xsObjetoGUI* boton, xsApuntador ventana)
{
  
   // Enteros para renglon y columna
   xsCadena renglon;
   xsCadena mensaje="";
   xsCadena fuente;

   // Declaro un Dialogo Nuevo
   xsDialogos dlgUsuario;

   // Creo el Dialogo
   dlgUsuario.crear("Capture el Número de Renglón y Nombre y Tamaño de la Fuente",
                     XS_VENTANA(ventana),
                     XS_DIALOGO_DESTRUIR_CON_PADRE,
                     "Aceptar",
                     XS_BOTON_RESPUESTA_ACEPTAR);

   // Agregar el botón de Cancelar
   dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

   // Declara y creo el contenedor para el diálogo
   xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

   // Asigna el Contenedor al Dialogo
   dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
   
   // Establece el borde
   contenedorDlg.colocarBorde(18);

   // Crea una imagen
   xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

   // Agrega la imagen al contenedor
   contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

   // Crea una matriz
   xsMatriz matriz;
   matriz.crear();

   // Coloca espaciamiento entre Renglones y Columnas
   matriz.colocarEspaciosEntreRenglones(4);
   matriz.colocarEspaciosEntreColumnas(4);

   // Se agrega la matriz al contenedor
   contenedorDlg.insertarEnEl(matriz.obtenerManejador());

   // Declaro Etiqueta de Renglon
   xsEtiqueta etqRenglon("Renglón :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqRenglon.obtenerManejador(),0,0,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entRenglon("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entRenglon.obtenerManejador(),1,0,1,1);

   // Declaro Etiqueta de Valor
   xsEtiqueta etqFuente("Fuente :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqFuente.obtenerManejador(),0,1,1,1);

   // Declaro Entrada de Valor
   xsEntrada entFuente("");

   // Se agregan la entrada a la matriz
   matriz.insertarEn(entFuente.obtenerManejador(),1,1,1,1);
      
   // Muestra todo el Contenedor
   contenedorDlg.mostrarTodo();

   // Ejecuta el Diálogo
   Entero respuesta = dlgUsuario.ejecutar();

   // Verifica si la respuesta fué aceptar
   si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
   {
       // Obtiene los datos   
       renglon = entRenglon.obtenerTexto();     
       fuente  = entFuente.obtenerTexto();
   }      

   // Valida
   si (renglon.length() <= 0)
      mensaje = "El Renglón\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(renglon))         
         // Agrega el Mensaje
         mensaje ="El Renglón no es numérico\n";      
      deOtroModo
         si (atoi(renglon.c_str())<0 || 
             atoi(renglon.c_str())>=oTablaGenerica.longitud())         
            // Agrega el Mensaje
            mensaje ="El Renglón está fuera de rango\n";      
   
   si (fuente.length() <= 0)
      mensaje = mensaje + "La Fuente\n";
   
   // Verifica si hay algo en numero
   si (mensaje.length() <= 0)
   {
      // Coloco el valor de la Celda
      oTablaGenerica.colocarAtributo(fuente, 
                                     atoi(renglon.c_str()),
                                     COL_FUENTE);

      // Desplegando
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Se ha modificado la Fuente del Renglón");
   }
   deOtroModo
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Los siguientes datos no son correctos:\n"+mensaje);
      
   // Destruye el diálogo
   dlgUsuario.destruir();
}

// Función para Color Fuente Celda
Estatica Vacio fnColorFuenteCelda(xsObjetoGUI* boton, xsApuntador ventana)
{
   // Enteros para renglon y columna
   xsCadena renglon;
   xsCadena mensaje="";
   xsCadena color;

   // Declaro un Dialogo Nuevo
   xsDialogos dlgUsuario;

   // Creo el Dialogo
   dlgUsuario.crear("Capture el Número de Renglón y Color para la Fuente",
                     XS_VENTANA(ventana),
                     XS_DIALOGO_DESTRUIR_CON_PADRE,
                     "Aceptar",
                     XS_BOTON_RESPUESTA_ACEPTAR);

   // Agregar el botón de Cancelar
   dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

   // Declara y creo el contenedor para el diálogo
   xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

   // Asigna el Contenedor al Dialogo
   dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
   
   // Establece el borde
   contenedorDlg.colocarBorde(18);

   // Crea una imagen
   xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

   // Agrega la imagen al contenedor
   contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

   // Crea una matriz
   xsMatriz matriz;
   matriz.crear();

   // Coloca espaciamiento entre Renglones y Columnas
   matriz.colocarEspaciosEntreRenglones(4);
   matriz.colocarEspaciosEntreColumnas(4);

   // Se agrega la matriz al contenedor
   contenedorDlg.insertarEnEl(matriz.obtenerManejador());

   // Declaro Etiqueta de Renglon
   xsEtiqueta etqRenglon("Renglón :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqRenglon.obtenerManejador(),0,0,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entRenglon("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entRenglon.obtenerManejador(),1,0,1,1);

   // Declaro Etiqueta de Valor
   xsEtiqueta etqColor("Color :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqColor.obtenerManejador(),0,1,1,1);

   // Declaro Entrada de Valor
   xsEntrada entColor("");

   // Se agregan la entrada a la matriz
   matriz.insertarEn(entColor.obtenerManejador(),1,1,1,1);
      
   // Muestra todo el Contenedor
   contenedorDlg.mostrarTodo();

   // Ejecuta el Diálogo
   Entero respuesta = dlgUsuario.ejecutar();

   // Verifica si la respuesta fué aceptar
   si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
   {
       // Obtiene los datos   
       renglon = entRenglon.obtenerTexto();     
       color   = entColor.obtenerTexto();
   }      

   // Valida
   si (renglon.length() <= 0)
      mensaje = "El Renglón\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(renglon))         
         // Agrega el Mensaje
         mensaje ="El Renglón no es numérico\n";      
      deOtroModo
         si (atoi(renglon.c_str())<0 || 
             atoi(renglon.c_str())>=oTablaGenerica.longitud())         
            // Agrega el Mensaje
            mensaje ="El Renglón está fuera de rango\n";      
   
   si (color.length() <= 0)
      mensaje = mensaje + "El Color\n";
   
   // Verifica si hay algo en numero
   si (mensaje.length() <= 0)
   {
      // Coloco el valor de la Celda
      oTablaGenerica.colocarAtributo(color, 
                                     atoi(renglon.c_str()),
                                     COL_COLOR);

      // Desplegando
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Se ha modificado el Color de la Fuente del Renglón");
   }
   deOtroModo
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Los siguientes datos no son correctos:\n"+mensaje);
      
   // Destruye el diálogo
   dlgUsuario.destruir();
}

// Función para Color Fondo Celda
Estatica Vacio fnColorFondoCelda(xsObjetoGUI* boton, xsApuntador ventana)
{
      // Enteros para renglon y columna
   xsCadena renglon;
   xsCadena mensaje="";
   xsCadena color;

   // Declaro un Dialogo Nuevo
   xsDialogos dlgUsuario;

   // Creo el Dialogo
   dlgUsuario.crear("Capture el Número de Renglón y Color para el Fondo de la celda de Código",
                     XS_VENTANA(ventana),
                     XS_DIALOGO_DESTRUIR_CON_PADRE,
                     "Aceptar",
                     XS_BOTON_RESPUESTA_ACEPTAR);

   // Agregar el botón de Cancelar
   dlgUsuario.agregarBoton("Cancelar",XS_BOTON_RESPUESTA_CANCELAR);

   // Declara y creo el contenedor para el diálogo
   xsContenedorFluido contenedorDlg(XS_ORIENTACION_HORIZONTAL,8);

   // Asigna el Contenedor al Dialogo
   dlgUsuario.asignarContenedor(contenedorDlg.obtenerManejador());
   
   // Establece el borde
   contenedorDlg.colocarBorde(18);

   // Crea una imagen
   xsImagen imgDialogo("dialog-question",XS_TAMANIO_ICONO_48PX);

   // Agrega la imagen al contenedor
   contenedorDlg.insertarEnEl(imgDialogo.obtenerManejador());

   // Crea una matriz
   xsMatriz matriz;
   matriz.crear();

   // Coloca espaciamiento entre Renglones y Columnas
   matriz.colocarEspaciosEntreRenglones(4);
   matriz.colocarEspaciosEntreColumnas(4);

   // Se agrega la matriz al contenedor
   contenedorDlg.insertarEnEl(matriz.obtenerManejador());

   // Declaro Etiqueta de Renglon
   xsEtiqueta etqRenglon("Renglón :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqRenglon.obtenerManejador(),0,0,1,1);

   // Declaro Entrada de Renglón
   xsEntrada entRenglon("");

   // Se agregan las entradas a la matriz
   matriz.insertarEn(entRenglon.obtenerManejador(),1,0,1,1);

   // Declaro Etiqueta de Valor
   xsEtiqueta etqColor("Color :");

   // Agrega las etiquetas a la Matriz
   matriz.insertarEn(etqColor.obtenerManejador(),0,1,1,1);

   // Declaro Entrada de Valor
   xsEntrada entColor("");

   // Se agregan la entrada a la matriz
   matriz.insertarEn(entColor.obtenerManejador(),1,1,1,1);
      
   // Muestra todo el Contenedor
   contenedorDlg.mostrarTodo();

   // Ejecuta el Diálogo
   Entero respuesta = dlgUsuario.ejecutar();

   // Verifica si la respuesta fué aceptar
   si (respuesta == XS_BOTON_RESPUESTA_ACEPTAR)
   {
       // Obtiene los datos   
       renglon = entRenglon.obtenerTexto();     
       color   = entColor.obtenerTexto();
   }      

   // Valida
   si (renglon.length() <= 0)
      mensaje = "El Renglón\n";
   deOtroModo
      // Valida que sea entero
      si (NO fnEsEntero(renglon))         
         // Agrega el Mensaje
         mensaje ="El Renglón no es numérico\n";      
      deOtroModo
         si (atoi(renglon.c_str())<0 || 
             atoi(renglon.c_str())>=oTablaGenerica.longitud())         
            // Agrega el Mensaje
            mensaje ="El Renglón está fuera de rango\n";      
   
   si (color.length() <= 0)
      mensaje = mensaje + "El Color\n";
   
   // Verifica si hay algo en numero
   si (mensaje.length() <= 0)
   {
      // Coloco el valor de la Celda
      oTablaGenerica.colocarAtributo(color, 
                                     atoi(renglon.c_str()),
                                     COL_FONDO);

      // Desplegando
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Se ha modificado el Color de la Fuente del Renglón");
   }
   deOtroModo
      xsVentana::mensajeInformacion("Demo Tabla Genérica","Los siguientes datos no son correctos:\n"+mensaje);
      
   // Destruye el diálogo
   dlgUsuario.destruir();
   
}

// función para validar si una cadena corresponde a un entero
Logico fnEsEntero(string cadena)
{
    // Variable de Resultado
    Logico resultado = Verdad;

    // Cadena Auxiliar
    string cadenaAux;
    
    // Variable entera
    Entero valorEntero;

    // Bandera que indica que ya encontró un numero
    Logico yaEncontroNumero = Falso;

    // Ciclo que depura la cadena
    ciclo (Entero indice=0; indice < cadena.length(); indice++)
    {
        // Filtra el +
        si (cadena.at(indice)!='+')
        {            
            si (cadena.at(indice)=='0')
            {
                si (yaEncontroNumero)           
                    cadenaAux = cadenaAux + cadena.at(indice);
            }
            deOtroModo
            {
                si (cadena.at(indice)!='-')   
                {
                    yaEncontroNumero = Verdad;
                }
                // Agrega la cadena a auxiliar
                cadenaAux = cadenaAux + cadena.at(indice);
            }
        }        
    }
    
    // Verifica si quedó vacía por 0's
    si (cadenaAux.length()==0)
       cadenaAux = "0";

    // Convertimos a entero
    valorEntero = atoi(cadena.c_str());

    // Comprobamos si es igual al convertir a entero
    si (cadenaAux.compare(to_string(valorEntero))!=0)
       // Cambiamos resultado
       resultado = Falso;

    // retornamos el resultado
    retorna resultado;
}

// función para validar si una cadena corresponde a un flotante
Logico fnEsFlotante(string cadena)
{
    // Variable de Resultado
    Logico resultado = Verdad;

    // Cadena Auxiliar Entera y Decimal
    string parteEntera;
    string parteDecimal;

    // Variable para posición del punto
    Entero posPunto;

    // Obtiene la posición del Punto
    posPunto = cadena.find_first_of(".");

    si (posPunto>0)
    {
        parteEntera  = cadena.substr(0,posPunto);
        parteDecimal = cadena.substr(posPunto+1);
    }
    deOtroModo
       si (posPunto==0)
       {
          // No tiene parte Entera
          parteEntera = "0";
          parteDecimal = cadena.substr(1);
       }   
       deOtroModo
       {
           // Solo hay parte Entera
           parteEntera = cadena;
           parteDecimal = "0";
       }
    
    // Valida que las partes sean numeros
    si (fnEsEntero(parteEntera) && fnEsEntero(parteDecimal))
    {
        cadena = parteEntera +"."+parteDecimal;
        Validar
        {
           // Trata de Convertir
           stoi(cadena);
        }
        Capturar(Constante std::exception& e)
        {
           //std::cerr << "Error" << e.what() << '\n';
           resultado = Falso;
        }       
    }
    deOtroModo
       resultado = Falso;    
    
    // retornamos el resultado
    retorna resultado;
}

Logico fnEsFecha(string cadena, Entero formato)
{
    // Variable de Resultado inicializado a Verdad
    Logico resultado=Verdad;

    // Variables para las cadenas
    string dia, mes, anio, sep1, sep2;

    // Variables para la fecha con enteros
    Entero intDia, intMes, intAnio;

    // Variable para crear la Fecha
    Estructura tm tmFecha;
    
    // Para el Despliegue de la Fecha
    Caracter strFecha[80];

    // Primero se valida la longitud de la cadena
    si (cadena.length() == 10)
    {
        // Ejecuta de acuerdo al formato
        evaluar(formato)
        {
            siEs 0: // Obtiene los 3 datos y los separadores
                    dia = cadena.substr(0,2);
                    mes = cadena.substr(3,2);
                    anio = cadena.substr(6);
                    sep1 = cadena[2];
                    sep2 = cadena[5];
                    break;
            
            siEs 1: // Obtiene los 3 datos y los separadores
                    dia = cadena.substr(3,2);
                    mes = cadena.substr(0,2);
                    anio = cadena.substr(6);
                    sep1 = cadena[2];
                    sep2 = cadena[5];
                    break;

            siEs 2: // Obtiene los 3 datos y los separadores
                    dia = cadena.substr(8,2);
                    mes = cadena.substr(5,2);
                    anio = cadena.substr(0,4);
                    sep1 = cadena[4];
                    sep2 = cadena[7];
                    break;   
            default:
                    // Cambiamos el valor de Resultado
                    resultado = Falso;                                            
        }

        // Verificamos que todavía el resultado sea válido
        si (resultado)
        {
            // Validamos que sean numeros el día mes y anio
            si (fnEsEntero(dia) && fnEsEntero(mes) && fnEsEntero(anio))
            {
                // Verificamos que los separadores sean iguales
                si (sep1.compare(sep2)==0)
                {
                    // Verificamos que sean validos
                    si (sep1[0]=='/' || sep1[0]=='-' || sep1[0]=='.')
                    {
                        // Convierte los datos a entero
                        intDia = atoi(dia.c_str());
                        intMes = atoi(mes.c_str()) - 1;
                        intAnio = atoi(anio.c_str()) - 1900;

                        // Colocamos los datos en la variable de Fecha
                        tmFecha.tm_year  = intAnio;
                        tmFecha.tm_mon   = intMes;
                        tmFecha.tm_mday  = intDia;
                        tmFecha.tm_hour  = 0;
                        tmFecha.tm_min   = 0;
                        tmFecha.tm_sec   = 0;
                        tmFecha.tm_isdst = -1;

                        // Se intenta crear la fecha
                        si (mktime(&tmFecha) != -1)
                        {
                            // Verifica que no haya modificado la fecha
                            si (tmFecha.tm_year != intAnio ||
                                tmFecha.tm_mon  != intMes  ||
                                tmFecha.tm_mday != intDia)
                            {
                                // Error
                                resultado = Falso;                                                             
                            }
                        }
                        deOtroModo                        
                           // Error
                           resultado = Falso;                            
                    }
                    deOtroModo
                       // Cambia el Resultado
                       resultado = Falso;

                }
                deOtroModo
                   // Error en Separadores
                   resultado = Falso;
            }
            deOtroModo
               // Error en algunos de los datos
               resultado = Falso;
        }
    }
    deOtroModo
       // Error en Longitud
       resultado=Falso;

    // Retorna
    retorna resultado;   
}
