// -------------------------------------------------------------------------------------
// xsEasyCpp
// Demo de Objeto Tabla
// g++ -g Tabla.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 Tabla.exe
// g++ -g Tabla.cpp %PKG-XSEASYCPP% -o Tabla.exe
// -------------------------------------------------------------------------------------

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


// Numerado para las columnas de la tabla
Numerado
{
  COL_NUMERO,
  COL_NOMBRE,
  COL_LOGO,
  COL_ICONO,
  COL_PRECIO,
  COL_PROMOCION,
  COL_ACTUALIZACION,
  COL_FUENTE,
  COL_COLOR,
  COL_VALOR_ACTUALIZACION,
  NUM_COLUMNAS
};


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

// Variable para el Control del Timer
Estatica SinSigno Entero timeout = 0;

// Variable con la que se cambia el Valor de Pulse del Spinning
SinSigno Entero pulse;

// Variable para la tabla
xsTabla oTabla;

// Defino las celdas para los datos
xsTabla::celda celdaNumero, 
               celdaNombre, 
               celdaImagen, 
               celdaIcono,
               celdaPrecio,
               celdaPromocion,
               celdaActualizacion,
               celdaFuente,
               celdaColor,
               celdaValorActualizacion;

// Define un vector de celdas para agrega un Renglon
vector<xsTabla::celda> renglonTabla;

// Define la Matriz global
xsMatriz matriz;

// Crea las Entradas
xsEntrada entNumero;
xsEntrada entNombre;
xsEntrada entImagen;
xsEntrada entIcono;
xsEntrada entPrecio;


// Lista de Opciones para Promocion
xsListaOpcionesTexto lstPromocion;
  
// Lista de Opciones para Actualizacion
xsListaOpcionesTexto lstActualizacion;
  

// 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
void fnRenglonDobleClick (xsArbolVista*        tree_view,
                          xsArbolRuta*         path,
                          xsArbolVistaColumna* column,
                          xsApuntador          user_data);

// Función para cuando se cambia de renglón
void 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 validar que una cadena solo tenga números
Logico fnCadenaConSoloNumeros(xsCadena cadena);

// 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 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
  oTabla.crear(xsObjeto_Lista_crear (10,
                                     XS_COLUMNA_TIPO_ENTERO_SIN_SIGNO, // Código
                                     XS_COLUMNA_TIPO_CADENA,           // Nombre 
                                     XS_COLUMNA_TIPO_BUFFER_PIXELES,   // Logo Lenguaje 
                                     XS_COLUMNA_TIPO_CADENA,           // Icono Libreria
                                     XS_COLUMNA_TIPO_FLOTANTE,         // Precio
                                     XS_COLUMNA_TIPO_BOOLEAN,          // Promocion
                                     XS_COLUMNA_TIPO_BOOLEAN,          // Actualizacion
                                     XS_COLUMNA_TIPO_CADENA,           // Fuente
                                     XS_COLUMNA_TIPO_CADENA,           // Color
                                     XS_COLUMNA_TIPO_ENTERO_SIN_SIGNO  // Valor Actualizacion
                                     ));  

  // Obtiene el Modelo para actualizar spining
  modeloDatos = GTK_TREE_MODEL(oTabla.obtenerListaDatos());
    
  // Agrega una Columna a la tabla
  oTabla.agregarColumna("Numero",  // Título de la Columna
                        xsTabla::tipoVisualizacion::tvTexto,  // Tipo de Despliegue
                        75, // Ancho de la Columns
                        0,  // Alto de la Columna
                        XS_ALINEAMIENTO_DERECHA,
                        XS_ALINEAMIENTO_DERECHA,
                        XS_ALINEAMIENTO_CENTRO,
                        COL_NUMERO,  // Columna de Ordenamiento (-1 Sin Ordenar)
                        "text="+to_string(COL_NUMERO)+",font="+to_string(COL_FUENTE)+"foreground="+to_string(COL_COLOR),
                        NULO); // El texto se toma de la Columna 0 del Modelo

  // Agrega una Columna a la tabla
  oTabla.agregarColumna("Nombre",
                        xsTabla::tipoVisualizacion::tvTexto,
                        150,
                        0,
                        XS_ALINEAMIENTO_IZQUIERDA,
                        XS_ALINEAMIENTO_IZQUIERDA,
                        XS_ALINEAMIENTO_CENTRO,
                        COL_NOMBRE, // Columna de Ordenamiento 
                        "text="+to_string(COL_NOMBRE)+",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
  oTabla.agregarColumna("Imagen",
                        xsTabla::tipoVisualizacion::tvImagen,
                        120,
                        0,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_SIN_ORDENAR_COLUMNA_TABLA,
                        "pixbuf="+to_string(COL_LOGO),
                        NULO);

   // Agrega una Columna a la tabla
   oTabla.agregarColumna("Icono",
                        xsTabla::tipoVisualizacion::tvImagen,
                        50,
                        0,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_SIN_ORDENAR_COLUMNA_TABLA,
                        "icon-name="+to_string(COL_ICONO),
                        NULO);

  // Agrega una Columna a la tabla
  oTabla.agregarColumna("Precio",
                        xsTabla::tipoVisualizacion::tvTexto,
                        100,
                        0,
                        XS_ALINEAMIENTO_DERECHA,
                        XS_ALINEAMIENTO_DERECHA,
                        XS_ALINEAMIENTO_CENTRO,
                        COL_PRECIO,
                        "text="+to_string(COL_PRECIO)+",font="+to_string(COL_FUENTE)+"foreground="+to_string(COL_COLOR),
                        fnCellDataFunc);

  // Agrega una Columna a la tabla
  oTabla.agregarColumna("Promoción",
                        xsTabla::tipoVisualizacion::tvPalanca,
                        75,
                        0,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        COL_PROMOCION,
                        "active="+to_string(COL_PROMOCION),
                        NULO);

  // Agrega una Columna a la tabla
  oTabla.agregarColumna("Actualización",
                        xsTabla::tipoVisualizacion::tvSpinner,
                        50,
                        0,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        XS_ALINEAMIENTO_CENTRO,
                        COL_ACTUALIZACION,
                        "active="+to_string(COL_ACTUALIZACION)+",pulse="+to_string(COL_VALOR_ACTUALIZACION),
                        NULO);

  
  // Defino el contenido de una celda
  celdaNumero.tipo = xsTabla::tipoCelda::Numero;
  celdaNumero.posicion = COL_NUMERO;
  celdaNumero.valorNumero = 1234;

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaNumero);
  
  // Defino el contenido de una celda
  celdaNombre.tipo = xsTabla::tipoCelda::Texto;
  celdaNombre.posicion = COL_NOMBRE;
  celdaNombre.valorTexto = "Curso de C";

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaNombre);

  // Defino el contenido de una celda
  celdaImagen.tipo = xsTabla::tipoCelda::Imagen;
  celdaImagen.posicion = COL_LOGO;
  xsImagen imgLogo("img/LogoC.png");
  celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();


  // Agrego la celda al al renglon
  renglonTabla.push_back(celdaImagen);

  // Defino el contenido de una celda
  celdaIcono.tipo = xsTabla::tipoCelda::Icono;
  celdaIcono.posicion = COL_ICONO;
  celdaIcono.valorTexto="computer";

  // Agrego la celda al al renglon
  renglonTabla.push_back(celdaIcono);
  
  // Defino el contenido de una celda
  celdaPrecio.tipo = xsTabla::tipoCelda::Decimal;
  celdaPrecio.posicion = COL_PRECIO;
  celdaPrecio.valorDecimal = 149.65;

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaPrecio);
  
  // Defino el contenido de una celda
  celdaPromocion.tipo = xsTabla::tipoCelda::Palanca;
  celdaPromocion.posicion = COL_PROMOCION;
  celdaPromocion.valorPalanca = 1;

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaPromocion);

  // Defino el contenido de una celda
  celdaActualizacion.tipo = xsTabla::tipoCelda::Spinner;
  celdaActualizacion.posicion = COL_ACTUALIZACION;
  celdaActualizacion.valorSpinner = 1;

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaActualizacion);

  // Defino el contenido de una celda
  celdaFuente.tipo = xsTabla::tipoCelda::Texto;
  celdaFuente.posicion = COL_FUENTE;
  celdaFuente.valorTexto = "Lucida Console 12";

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaFuente);
  
  // Defino el contenido de una celda
  celdaColor.tipo = xsTabla::tipoCelda::Texto;
  celdaColor.posicion = COL_COLOR;
  celdaColor.valorTexto = "blue";

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaColor);

  // Defino el contenido de una celda
  celdaValorActualizacion.tipo = xsTabla::tipoCelda::Numero;
  celdaValorActualizacion.posicion = COL_VALOR_ACTUALIZACION;
  celdaValorActualizacion.valorNumero = 0;

  // Agrego la celda al alrenglon
  renglonTabla.push_back(celdaValorActualizacion);

  // Inserta el Renglon en la Tabla
  oTabla.insertarRenglon(renglonTabla);

  // Limpio el Renglon
  renglonTabla.clear();

  // Coloco los datos para el Siguiente Renglon
  celdaNumero.valorNumero = 3421;
  renglonTabla.push_back(celdaNumero);
  
  // Defino el contenido de una celda
  celdaNombre.valorTexto = "Curso de C++";
  renglonTabla.push_back(celdaNombre);

  // Defino el contenido de una celda
  imgLogo.crear("img/LogoC++.png");
  celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();
  renglonTabla.push_back(celdaImagen);

  // Indica el Icono
  celdaIcono.valorTexto="battery";
  renglonTabla.push_back(celdaIcono);

  // Defino el contenido de una celda
  celdaPrecio.valorDecimal = 712.32;
  renglonTabla.push_back(celdaPrecio);
  
  // Defino el contenido de una celda
  celdaPromocion.valorPalanca = 0;
  renglonTabla.push_back(celdaPromocion);

  // Defino el contenido de una celda
  celdaActualizacion.valorSpinner = 1;
  renglonTabla.push_back(celdaActualizacion);

  // Agrego la celda de la fuente y el color iguales  
  renglonTabla.push_back(celdaFuente);
  renglonTabla.push_back(celdaColor);
  
  // Inserta el Renglon en la Tabla
  oTabla.insertarRenglon(renglonTabla);
  
  // Limpio el Renglon
  renglonTabla.clear();

  // Coloco los datos para el Siguiente Renglon
  celdaNumero.valorNumero = 4321;
  renglonTabla.push_back(celdaNumero);
  
  // Defino el contenido de una celda
  celdaNombre.valorTexto = "Curso de Php";
  renglonTabla.push_back(celdaNombre);

  // Defino el contenido de una celda
  imgLogo.crear("img/LogoPhp.png");
  celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();
  renglonTabla.push_back(celdaImagen);

  // Agrego el Icono
  celdaIcono.valorTexto = "document-print";
  renglonTabla.push_back(celdaIcono);

  
  // Defino el contenido de una celda
  celdaPrecio.valorDecimal = 275.19;
  renglonTabla.push_back(celdaPrecio);
  
  // Defino el contenido de una celda
  celdaPromocion.valorPalanca = 0;
  renglonTabla.push_back(celdaPromocion);

  // Agrego la celda
  renglonTabla.push_back(celdaActualizacion);

  // Agrego la celda de la fuente y el color iguales  
  renglonTabla.push_back(celdaFuente);
  renglonTabla.push_back(celdaColor);
  
  // Inserta el Renglon en la Tabla
  oTabla.insertarRenglon(renglonTabla);

  // Coloco los datos para el Siguiente Renglon
  celdaNumero.valorNumero = 7777;
  renglonTabla.push_back(celdaNumero);
  
  // Defino el contenido de una celda
  celdaNombre.valorTexto = "Curso de Python";
  renglonTabla.push_back(celdaNombre);

  // Defino el contenido de una celda
  imgLogo.crear("img/LogoPython.png");
  celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();
  renglonTabla.push_back(celdaImagen);

  // Agrego el Icono
  celdaIcono.valorTexto = "folder-new";
  renglonTabla.push_back(celdaIcono);

  
  // Defino el contenido de una celda
  celdaPrecio.valorDecimal = 173.98;
  renglonTabla.push_back(celdaPrecio);
  
  // Defino el contenido de una celda
  celdaPromocion.valorPalanca = 0;
  renglonTabla.push_back(celdaPromocion);

  // Agrego la celda
  renglonTabla.push_back(celdaActualizacion);

  // Agrego la celda de la fuente y el color iguales  
  renglonTabla.push_back(celdaFuente);
  renglonTabla.push_back(celdaColor);
  
  // Inserta el Renglon en la Tabla
  oTabla.insertarRenglon(renglonTabla);

  // Coloco los datos para el Siguiente Renglon
  celdaNumero.valorNumero = 99999;
  renglonTabla.push_back(celdaNumero);
  
  // Defino el contenido de una celda
  celdaNombre.valorTexto = "Curso de Go";
  renglonTabla.push_back(celdaNombre);

  // Defino el contenido de una celda
  imgLogo.crear("img/LogoGo.png");
  celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();
  renglonTabla.push_back(celdaImagen);

  // Agrego el Icono
  celdaIcono.valorTexto = "go-down";
  renglonTabla.push_back(celdaIcono);

  
  // Defino el contenido de una celda
  celdaPrecio.valorDecimal = 185.00;
  renglonTabla.push_back(celdaPrecio);
  
  // Defino el contenido de una celda
  celdaPromocion.valorPalanca = 0;
  renglonTabla.push_back(celdaPromocion);

  // Agrego la celda
  renglonTabla.push_back(celdaActualizacion);

  // Agrego la celda de la fuente y el color iguales  
  renglonTabla.push_back(celdaFuente);
  renglonTabla.push_back(celdaColor);
  
  // Inserta el Renglon en la Tabla
  oTabla.insertarRenglon(renglonTabla);
  
  // Crea una Ventana de Desplazamiento (scroll)
  xsVentanaDesplazamiento scroll(NULO,NULO);
  scroll.colocarDimensiones(500,200);

  // Agrega la tabla a la Ventana
  scroll.agregarEn(oTabla.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 etqNumero("Numero:");
  etqNumero.colocarDimensiones(100,0);
  etqNumero.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  xsEtiqueta etqNombre("Nombre:");
  etqNombre.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  xsEtiqueta etqImagen("Imagen:");
  etqImagen.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  xsEtiqueta etqIcono("Icono:");
  etqIcono.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  xsEtiqueta etqPrecio("Precio:");
  etqPrecio.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  xsEtiqueta etqPromocion("Promocion:");
  etqPromocion.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);
  xsEtiqueta etqActualizacion("Actualización:");
  etqActualizacion.alinearHorizontalmente(XS_ALINEAMIENTO_IZQUIERDA);

  // Agrega las Etiquetas a la Matriz
  matriz.insertarEn(etqNumero.obtenerManejador(),0,0,1,1);  
  matriz.insertarEn(etqNombre.obtenerManejador(),0,1,1,1);
  matriz.insertarEn(etqImagen.obtenerManejador(),0,2,1,1);
  matriz.insertarEn(etqIcono.obtenerManejador(),0,3,1,1);
  matriz.insertarEn(etqPrecio.obtenerManejador(),0,4,1,1);
  matriz.insertarEn(etqPromocion.obtenerManejador(),0,5,1,1);
  matriz.insertarEn(etqActualizacion.obtenerManejador(),0,6,1,1);

  // Crea las Entradas
  entNumero.crear("Capture el Numero");
  entNumero.colocarDimensiones(400,0);
  entNombre.crear("Capture el Nombre");
  entImagen.crear("Capture la Ruta de la Imagen del Curso");
  entIcono.crear("Capture el nombre del icono en Librería:");
  entPrecio.crear("Capture el Precio:");

  // Lista de Opciones para Promocion
  lstPromocion.crear();
  lstPromocion.agregar("No");
  lstPromocion.agregar("Si");
  
  // Lista de Opciones para Actualizacion
  lstActualizacion.crear();
  lstActualizacion.agregar("Estable");
  lstActualizacion.agregar("En Actualización");
  
  // Agrega las Entradas y Listas
  matriz.insertarEn(entNumero.obtenerManejador(),1,0,1,1);
  matriz.insertarEn(entNombre.obtenerManejador(),1,1,1,1);
  matriz.insertarEn(entImagen.obtenerManejador(),1,2,1,1);
  matriz.insertarEn(entIcono.obtenerManejador(),1,3,1,1);
  matriz.insertarEn(entPrecio.obtenerManejador(),1,4,1,1);
  matriz.insertarEn(lstPromocion.obtenerManejador(),1,5,1,1);
  matriz.insertarEn(lstActualizacion.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);
  
  // Agrega los Botones de Operación a la Matriz
  matriz.insertarColumna(2);
  xsEtiqueta etqPrueba("Test");
  matriz.insertarEn(etqPrueba.obtenerManejador()        ,2,0,1,1);
  matriz.insertarEn(btnInsertar.obtenerManejador()      ,3,0,1,1);
  matriz.insertarEn(btnEliminar.obtenerManejador()      ,3,1,1,1);
  matriz.insertarEn(btnEliminarSel.obtenerManejador()   ,3,2,1,1);
  matriz.insertarEn(btnModificar.obtenerManejador()     ,3,3,1,1);
  matriz.insertarEn(btnModificarSel.obtenerManejador()  ,3,4,1,1);
  matriz.insertarEn(btnEliminarTodos.obtenerManejador(),3,5,1,1);
  matriz.insertarEn(btnSeleccionar.obtenerManejador(),3,6,1,1);

  // Conectando Señales
  oTabla.conectarSenal(XS_EVENTO_RENGLON_ACTIVADO,XS_FUNCION_RETORNO(fnRenglonDobleClick),NULO); // Doble Click
  oTabla.conectarSenal(XS_EVENTO_RENGLON_SELECIONADO,XS_FUNCION_RETORNO(fnRenglonSeleccionado),NULO); // Al Seleccionar Row  
  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());
  oVentana.conectarSenal(XS_EVENTO_DESTRUIR,xsFuncionSalida, NULO);
  
  // Visualiza las Lineas
  oTabla.visualizarLineas(VERDAD);
  
  // Muestra todos los objetos
  oVentana.mostrarTodo();

  // Llama a la función para lanzar el timer
  timeout = xsTimer (80, fnTimerActualizacion, NULL);
  
  // 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 timer
Estatica Entero fnTimerActualizacion (xsApuntador data)
{
    // Variable para el iterador del Árbol
    xsArbolIterador iter;
  
    // Verifica que haya modelo de datos
    si (modeloDatos == NULL)

       // Finaliza el Procesamiento del Timer
       retorna G_SOURCE_REMOVE;

    // Verifica que la longitud de la tabla sea por lo menos de 1
    si (oTabla.longitud()>0)
    {
       // Obtiene el primer iterador del modelo de datos
       xsObjeto_Arbol_obtener_iterador_primero (modeloDatos, &iter);
       // Similar a la siguiente
       //xsObjeto_Arbol_obtener_iterador_cadena (modeloDatos, &iter,"0");


       // Obtiene el valor correspondiente a la columna
       xsObjeto_Arbol_obtener_modelo (modeloDatos, 
                                      &iter,                
                                      COL_VALOR_ACTUALIZACION, 
                                      &pulse,
                                      XS_FIN_DE_DATOS);
      
       // Verifica si llegó al tope para inicializar
       si (pulse == G_MAXUINT)
          // Inicialzia
          pulse = 0;
       deOtroModo
          // Incrementa
          pulse++;
   
       // Modifica el Dato en el iterador
       xsObjeto_Lista_colocar (GTK_LIST_STORE (modeloDatos),
                               &iter,
                               COL_VALOR_ACTUALIZACION, 
                               pulse,
                               XS_FIN_DE_DATOS);
    }
                     
    // Continua el Procesamiento del Timer
    retorna G_SOURCE_CONTINUE;
}

// 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;

   // Variables para los datos
   Entero           numero;
   Caracter*        nombre;   
   xsPixelesBuffer* imagenEnPixeles;
   Caracter*        icono;
   Flotante         precio;
   Entero           promocion;
   Entero           actualizacion;
   Caracter*        texto; 
      
   // 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_NUMERO, &numero, XS_FIN_DE_DATOS);
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_NOMBRE, &nombre, XS_FIN_DE_DATOS);
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_LOGO, &imagenEnPixeles, XS_FIN_DE_DATOS);
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_ICONO,  &icono, XS_FIN_DE_DATOS);
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_PRECIO, &precio, XS_FIN_DE_DATOS);
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_PROMOCION, &promocion, XS_FIN_DE_DATOS);
   xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_VALOR_ACTUALIZACION, &actualizacion, XS_FIN_DE_DATOS);

   // Convierte a texto el numero
   texto = g_strdup_printf ("%05d", numero);
   entNumero.colocarTexto(texto);
   entNombre.colocarTexto(nombre);
   entIcono.colocarTexto(icono);
   texto = g_strdup_printf ("%05.2f", precio);
   entPrecio.colocarTexto(texto);
   lstPromocion.seleccionar(promocion);
   si (actualizacion>0)
      actualizacion=1;
   lstActualizacion.seleccionar(actualizacion);

   // Elimina la Columna para despues agregar la imagen en la columna 2
   matriz.insertarColumna(3);
   xsImagen imgTemporal;

   // Carga la imagen desde el buffer de pixeles
   imgTemporal.cargarImagenDesdeBufferPixeles(imagenEnPixeles);

   // Inserta la imagen en la columna 3
   matriz.insertarEn(imgTemporal.obtenerManejador(),3,2,1,1);

   // Elimina la columna 2 para que de nuevo la imagen quede en la Columna 2
   matriz.eliminarColumna(2);
   
   // Es indispensable actualizar
   matriz.mostrarTodo();
   
}

// Función para el Renglón Seleccionado
Vacio fnRenglonSeleccionado(xsArbolVista*        tree_view,
                            xsApuntador          user_data)
{
   Entero                     numero;
   Caracter*                  nombre;   
   xsPixelesBuffer*           imagenEnPixeles;
   Caracter*                  icono;
   Flotante                   precio;
   Entero                     promocion;
   Entero                     actualizacion;
   xsArbolIterador            iter;
   xsArbolOpcionSeleccionada* seleccionado;
   Caracter*                  texto;    

   // 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_NUMERO, &numero, XS_FIN_DE_DATOS);
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_NOMBRE, &nombre, XS_FIN_DE_DATOS);
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_LOGO, &imagenEnPixeles, XS_FIN_DE_DATOS);
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_ICONO, &icono, XS_FIN_DE_DATOS);
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_PRECIO, &precio, XS_FIN_DE_DATOS);
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_PROMOCION, &promocion, XS_FIN_DE_DATOS);
      xsObjeto_Arbol_obtener_modelo (modeloDatos, &iter, COL_VALOR_ACTUALIZACION, &actualizacion, XS_FIN_DE_DATOS);

      // Convierte a texto el numero
      texto = g_strdup_printf ("%010d", numero);
      entNumero.colocarTexto(texto);
      entNombre.colocarTexto(nombre);
      entIcono.colocarTexto(icono);
      texto = g_strdup_printf ("%010.2f", precio);
      entPrecio.colocarTexto(texto);
      lstPromocion.seleccionar(promocion);
      si (actualizacion>0)
         actualizacion=1;
      lstActualizacion.seleccionar(actualizacion);

      // Elimina la Columna para despues agregar la imagen en la columna 2
      matriz.insertarColumna(3);
      xsImagen imgTemporal;

      // Carga la imagen desde el buffer de pixeles
      imgTemporal.cargarImagenDesdeBufferPixeles(imagenEnPixeles);

      // Inserta la imagen en la columna 3
      matriz.insertarEn(imgTemporal.obtenerManejador(),3,2,1,1);

      // Elimina la columna 2 para que de nuevo la imagen quede en la Columna 2
      matriz.eliminarColumna(2);
      
      // 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 Numero
   si (entNumero.obtenerLongitudTexto()<=0)
   {
      // Manda el Foco al dato
      entNumero.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje="El Número \n";      
   }
   
   // Valida el Nombre
   si (entNombre.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      if (mensaje.length()==0)
         // Manda el Foco
         entNombre.colocarFoco();

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

   // Valida la Imagen del Curso
   si (entImagen.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      if (mensaje.length()==0)
         // Manda el Foco
         entImagen.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje=+"La Imagen del Curso \n";      
   }

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

      // Agrega el Dato al Mensaje
      mensaje=+"El Lenguaje \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",mensaje);
      
   }
   deOtroModo
   {
      // Limpio el Renglón 
      renglonTabla.clear();
      
      // Defino el contenido de una celda
      celdaNumero.tipo = xsTabla::tipoCelda::Numero;
      celdaNumero.posicion = COL_NUMERO;
      celdaNumero.valorNumero = atoi(entNumero.obtenerTexto().c_str());

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaNumero);
      
      // Defino el contenido de una celda
      celdaNombre.tipo = xsTabla::tipoCelda::Texto;
      celdaNombre.posicion = COL_NOMBRE;
      celdaNombre.valorTexto = entNombre.obtenerTexto();

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaNombre);

      // Defino el contenido de una celda
      celdaImagen.tipo = xsTabla::tipoCelda::Imagen;
      celdaImagen.posicion = COL_LOGO;
      xsImagen imgLogo(entImagen.obtenerTexto());
      celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();

      // Agrego la celda al al renglon
      renglonTabla.push_back(celdaImagen);

      // Defino el contenido de una celda
      celdaIcono.tipo = xsTabla::tipoCelda::Icono;
      celdaIcono.posicion = COL_ICONO;
      celdaIcono.valorTexto=entIcono.obtenerTexto();

      // Agrego la celda al al renglon
      renglonTabla.push_back(celdaIcono);
      
      // Defino el contenido de una celda
      celdaPrecio.tipo = xsTabla::tipoCelda::Decimal;
      celdaPrecio.posicion = COL_PRECIO;
      celdaPrecio.valorDecimal = atof(entPrecio.obtenerTexto().c_str());;

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaPrecio);
      
      // Defino el contenido de una celda
      celdaPromocion.tipo = xsTabla::tipoCelda::Palanca;
      celdaPromocion.posicion = COL_PROMOCION;
      celdaPromocion.valorPalanca = lstPromocion.obtenerIndiceSeleccionado();

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaPromocion);

      // Defino el contenido de una celda
      celdaActualizacion.tipo = xsTabla::tipoCelda::Spinner;
      celdaActualizacion.posicion = COL_ACTUALIZACION;
      celdaActualizacion.valorSpinner = 1; // Siempre es uno para que aparezca el icono

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaActualizacion);

      // Defino el contenido de una celda
      celdaFuente.tipo = xsTabla::tipoCelda::Texto;
      celdaFuente.posicion = COL_FUENTE;
      celdaFuente.valorTexto = "Lucida Console 12";

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaFuente);
      
      // Defino el contenido de una celda
      celdaColor.tipo = xsTabla::tipoCelda::Texto;
      celdaColor.posicion = COL_COLOR;
      celdaColor.valorTexto = "blue";

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaColor);

      // Defino el contenido de una celda
      celdaValorActualizacion.tipo = xsTabla::tipoCelda::Numero;
      celdaValorActualizacion.posicion = COL_VALOR_ACTUALIZACION;
      celdaValorActualizacion.valorNumero = 0;

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaValorActualizacion);

      // Inserta el Renglon en la Tabla
      oTabla.insertarRenglon(renglonTabla);

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla","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 (fnCadenaConSoloNumeros(numero))
     {        
        // Convierte a entero
        posicion = atoi(numero.c_str());

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

// Función para validar que una cadena solo tenga números
Logico fnCadenaConSoloNumeros(xsCadena cadena)
{
	// resultado
	Logico resultado = Verdad;

	// Ciclo para verificar cada caracter
	for(int i = 0; i < cadena.size(); i++)
	{
      // Verifica que no sea dígito
		si (cadena[i] <'0' || cadena[i]>'9')
		{
			// Cambia el Resultado
			resultado = Falso;
			salirCiclo;
		}
	}

	// retorna el resultado
	retorna resultado;
}


// 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 (fnCadenaConSoloNumeros(numero))
     {        
        // Convierte a entero
        posicion = atoi(numero.c_str());

        // Verifica que la posición a seleccionar este dentro del rango
        si (posicion >= 0 && posicion < oTabla.longitud())        
            // Selecciona un Registro
            oTabla.eliminar(numero);        
        deOtroModo
            xsVentana::mensajeInformacion("Demo Tabla","El número está fuera de rango");        
     }
     deOtroModo
        xsVentana::mensajeInformacion("Demo Tabla","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","¿ Desea eliminar todos los Registros ?");        

   // Verifica que contesto
   si (respuesta==xsVentana::BOTON_SI)                                  
      // Limpia los Registros
      oTabla.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","¿ Desea eliminar el Elemento Seleccionado ?");        

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

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

   // Valida el Numero
   si (entNumero.obtenerLongitudTexto()<=0)
   {
      // Manda el Foco al dato
      entNumero.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje="El Número \n";      
   }
   
   // Valida el Nombre
   si (entNombre.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      if (mensaje.length()==0)
         // Manda el Foco
         entNumero.colocarFoco();

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

   // Valida la Imagen del Curso
   si (entImagen.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      if (mensaje.length()==0)
         // Manda el Foco
         entImagen.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje=+"La Imagen del Curso \n";      
   }

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

      // Agrega el Dato al Mensaje
      mensaje=+"El Lenguaje \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",mensaje);
      
   }
   deOtroModo
   {
      // Limpio primeramente el Renglon
      renglonTabla.clear();

      // Defino el contenido de una celda
      celdaNumero.tipo = xsTabla::tipoCelda::Numero;
      celdaNumero.posicion = COL_NUMERO;
      celdaNumero.valorNumero = atoi(entNumero.obtenerTexto().c_str());

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaNumero);
      
      // Defino el contenido de una celda
      celdaNombre.tipo = xsTabla::tipoCelda::Texto;
      celdaNombre.posicion = COL_NOMBRE;
      celdaNombre.valorTexto = entNombre.obtenerTexto();

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaNombre);

      // Defino el contenido de una celda
      celdaImagen.tipo = xsTabla::tipoCelda::Imagen;
      celdaImagen.posicion = COL_LOGO;
      xsImagen imgLogo(entImagen.obtenerTexto());
      celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();

      // Agrego la celda al al renglon
      renglonTabla.push_back(celdaImagen);

      // Defino el contenido de una celda
      celdaIcono.tipo = xsTabla::tipoCelda::Icono;
      celdaIcono.posicion = COL_ICONO;
      celdaIcono.valorTexto=entIcono.obtenerTexto();

      // Agrego la celda al al renglon
      renglonTabla.push_back(celdaIcono);
      
      // Defino el contenido de una celda
      celdaPrecio.tipo = xsTabla::tipoCelda::Decimal;
      celdaPrecio.posicion = COL_PRECIO;
      celdaPrecio.valorDecimal = atof(entPrecio.obtenerTexto().c_str());;

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaPrecio);
      
      // Defino el contenido de una celda
      celdaPromocion.tipo = xsTabla::tipoCelda::Palanca;
      celdaPromocion.posicion = COL_PROMOCION;
      celdaPromocion.valorPalanca = lstPromocion.obtenerIndiceSeleccionado();

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaPromocion);

      // Defino el contenido de una celda
      celdaActualizacion.tipo = xsTabla::tipoCelda::Spinner;
      celdaActualizacion.posicion = COL_ACTUALIZACION;
      celdaActualizacion.valorSpinner = 1; // Siempre es uno para que aparezca el icono

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaActualizacion);

      // Defino el contenido de una celda
      celdaFuente.tipo = xsTabla::tipoCelda::Texto;
      celdaFuente.posicion = COL_FUENTE;
      celdaFuente.valorTexto = "Lucida Console 12";

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaFuente);
      
      // Defino el contenido de una celda
      celdaColor.tipo = xsTabla::tipoCelda::Texto;
      celdaColor.posicion = COL_COLOR;
      celdaColor.valorTexto = "blue";

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaColor);

      // Defino el contenido de una celda
      celdaValorActualizacion.tipo = xsTabla::tipoCelda::Numero;
      celdaValorActualizacion.posicion = COL_VALOR_ACTUALIZACION;
      celdaValorActualizacion.valorNumero = 0;

      // Agrego la celda al alrenglon
      renglonTabla.push_back(celdaValorActualizacion);

      // Modifica el Renglón Seleccionado
      oTabla.modificarRenglonSeleccionado(renglonTabla);

      // Despliega el Mensaje de que faltan datos
      xsVentana::mensajeAdvertencia("Demo Tabla","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 Numero
   si (entNumero.obtenerLongitudTexto()<=0)
   {
      // Manda el Foco al dato
      entNumero.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje="El Número \n";      
   }
   
   // Valida el Nombre
   si (entNombre.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      if (mensaje.length()==0)
         // Manda el Foco
         entNumero.colocarFoco();

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

   // Valida la Imagen del Curso
   si (entImagen.obtenerLongitudTexto()<=0)
   {
      // Valida si debe enviar el foco
      if (mensaje.length()==0)
         // Manda el Foco
         entImagen.colocarFoco();

      // Agrega el Dato al Mensaje
      mensaje=+"La Imagen del Curso \n";      
   }

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

      // Agrega el Dato al Mensaje
      mensaje=+"El Lenguaje \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",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 (fnCadenaConSoloNumeros(numero))
         {        
            // Convierte a entero
            posicion = atoi(numero.c_str());

            // Verifica que la posición a seleccionar este dentro del rango
            si (posicion >= 0 && posicion < oTabla.longitud())        
            {
                  // Limpio primeramente el Renglon
                  renglonTabla.clear();

                  // Defino el contenido de una celda
                  celdaNumero.tipo = xsTabla::tipoCelda::Numero;
                  celdaNumero.posicion = COL_NUMERO;
                  celdaNumero.valorNumero = atoi(entNumero.obtenerTexto().c_str());

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaNumero);
                  
                  // Defino el contenido de una celda
                  celdaNombre.tipo = xsTabla::tipoCelda::Texto;
                  celdaNombre.posicion = COL_NOMBRE;
                  celdaNombre.valorTexto = entNombre.obtenerTexto();

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaNombre);

                  // Defino el contenido de una celda
                  celdaImagen.tipo = xsTabla::tipoCelda::Imagen;
                  celdaImagen.posicion = COL_LOGO;
                  xsImagen imgLogo(entImagen.obtenerTexto());
                  celdaImagen.valorImagen = imgLogo.obtenerBufferPixeles();

                  // Agrego la celda al al renglon
                  renglonTabla.push_back(celdaImagen);

                  // Defino el contenido de una celda
                  celdaIcono.tipo = xsTabla::tipoCelda::Icono;
                  celdaIcono.posicion = COL_ICONO;
                  celdaIcono.valorTexto=entIcono.obtenerTexto();

                  // Agrego la celda al al renglon
                  renglonTabla.push_back(celdaIcono);
                  
                  // Defino el contenido de una celda
                  celdaPrecio.tipo = xsTabla::tipoCelda::Decimal;
                  celdaPrecio.posicion = COL_PRECIO;
                  celdaPrecio.valorDecimal = atof(entPrecio.obtenerTexto().c_str());;

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaPrecio);
                  
                  // Defino el contenido de una celda
                  celdaPromocion.tipo = xsTabla::tipoCelda::Palanca;
                  celdaPromocion.posicion = COL_PROMOCION;
                  celdaPromocion.valorPalanca = lstPromocion.obtenerIndiceSeleccionado();

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaPromocion);

                  // Defino el contenido de una celda
                  celdaActualizacion.tipo = xsTabla::tipoCelda::Spinner;
                  celdaActualizacion.posicion = COL_ACTUALIZACION;
                  celdaActualizacion.valorSpinner = 1; // Siempre es uno para que aparezca el icono

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaActualizacion);

                  // Defino el contenido de una celda
                  celdaFuente.tipo = xsTabla::tipoCelda::Texto;
                  celdaFuente.posicion = COL_FUENTE;
                  celdaFuente.valorTexto = "Lucida Console 12";

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaFuente);
                  
                  // Defino el contenido de una celda
                  celdaColor.tipo = xsTabla::tipoCelda::Texto;
                  celdaColor.posicion = COL_COLOR;
                  celdaColor.valorTexto = "blue";

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaColor);

                  // Defino el contenido de una celda
                  celdaValorActualizacion.tipo = xsTabla::tipoCelda::Numero;
                  celdaValorActualizacion.posicion = COL_VALOR_ACTUALIZACION;
                  celdaValorActualizacion.valorNumero = 0;

                  // Agrego la celda al alrenglon
                  renglonTabla.push_back(celdaValorActualizacion);

                  // Modifica el Renglón
                  oTabla.modificarRenglon(atoi(numero.c_str()), renglonTabla);        
            }    
            deOtroModo
                  xsVentana::mensajeInformacion("Demo Tabla","El número está fuera de rango");        
         }
         deOtroModo
            xsVentana::mensajeInformacion("Demo Tabla","Capture solo Numeros");
         
      // Destruye el diálogo
      dlgUsuario.destruir();
      
   }
}