Etiqueta

2 de septiembre de 2015

Uso de “String Tables” para la localización de aplicaciones en diferentes idiomas

Para poder seguir las explicaciones que se ofrecen en éste articulo, deberá descargar las librerías de ejemplo, disponibles en Aula Omnis. Encontrará dos ficheros que podrán ser usados a partir de la versión de Omnis Studio 2.1, para Windows descargue el fichero “Strngtab.zip” y para MacOS el “Strngtab.sit.hqx”, descomprimirlos sobre una misma carpeta, en ella deberá encontrar las siguientes librerías:

STRTEST.LBS
  • Esta librería muestra cómo hacer uso de las “String Tables” para añadir soporte multi-idioma a nuestras aplicaciones. Al hacer clic sobre el botón “language”, se nos permitirá seleccionar uno de entre lista desplegable, después bastará con pulsar el botón “Set Language” para que todos los controles se redibujen, mostrando el idioma seleccionado. El ejemplo muestra el uso de las principales características de la interfaz “String Table” y su función “$getText()”.

TABLE.LBS
  • Esta librería muestra cómo configurar los controles “String Label” para muestren la información obtenida de entre varias “String Table”.

A continuación mostramos las funciones implicadas en el uso de “String Tables”, atendiendo a su creación, almacenado, eliminación y uso.

 

Funciones para la creación de “String Tables”:


$loadtablefromlist(≤Nombre de Tabla≥,≤Ruta≥,≤List≥)
Crea una “String Table” a partir de una variable de tipo “List”. Como cabe suponer, la tabla es creada en memoria. Para guardarla se deberá usar la función “$savestringtable”.

$loadcolumn(≤Nombre de columna≥,≤Nombre de Tabla≥,≤Ruta≥) 
Crea una “String Table” usando una sola, de las columnas de la tabla.

$loadstringtable(≤Nombre de Tabla≥,≤Ruta≥) 
Carga completa de la “String Table” indicada.

 

Funciones para guardar “String Tables”:


$savestringtable(≤Nombre de Tabla≥) 
Guarda una “String Table” de entre las anteriormente creadas.
Nota: No se especifica ruta, puesto que éste parámetro solo es necesario durante su creación.

 

Funciones para la eliminación “String Tables”:


$removestringtable(≤Ruta≥) 
Elimina del disco una “String Table”.

$unloadstringtable(≤Nombre de Tabla≥) 
Descarga de la memoria una “String Table”.

$unloadall() 
Descarga de la memoria todas las “String Tables”.

Nota: Ambas funciones son opcionales, ya que todas las “String Tables” se descargan automáticamente al salir de Omnis.

 

Funciones para el acceso y uso de “String Tables”:


$setcolumn(≤Nombre de Columna≥) 
Establece la columna actual a la indicada ≤Nombre de Columna≥. Se puede indicar tanto un nombre, como un número.

Nota: Es sensible al uso de mayúsculas y minúsculas. Si se están utilizando varias “String Tables”, deberá usarse la forma ≤Nombre de Tabla≥.≤Nombre de Columna≥, por ejemplo, “StringTable.$setcolumn(“Table1.French”)” o bien “StringTable.$setcolumn(“Table1.3”)

$getcolumnname([≤Nombre de Tabla≥] ) 
Obtiene el nombre de la columna actual. No es necesario especificar ≤Nombre de Tabla≥ si se está trabajando con una sola “String Table”.

$getcolumnnumber([≤Nombre de Tabla≥] ) 
Trabaja del mismo modo que la función anterior, pero devuelve el número de la columna en lugar de su nombre.

$redraw(≤Hwnd≥) 
Esta función puede utilizarse para volver a dibujar una ventana completa. En la librería de ejemplo “STRTEST”, se usa la función “StringTable.$redrawAll()” para volver a dibujar todas las ventanas tras la selección un nuevo idioma. Seguramente es el mejor modo de refrescar los controles de tipo “String Label” de nuestras aplicaciones.

$colcnt([≤Nombre de Tabla≥]) 
Devuelve el número de columnas de .

 
$rowcnt([≤Nombre de Tabla≥]) 
Devuelve el número de filas en .

 
$loadlistfromtable(≤Nombre de Tabla≥) 
Copia una “String Table” sobre una variable de tipo “List”.

26 de agosto de 2015

Creando nuestro propio escritorio Omnis

Por defecto, Omnis Studio presenta un escritorio con el fondo gris, es decir, el área de trabajo de la ventana principal es de color gris (al menos en la plataforma Windows). Sin embargo es posible personalizar dicho color de fondo o incluso insertar una imagen. El “truco” que exponemos a continuación, nos puede ayudar a hacer esto con facilidad.

Para lograrlo, empezaremos por añadir una nueva clase-ventana a la librería que estemos construyendo, su nombre será: “wBackground”. Una vez creada, ábrala en modo diseño y (por ejemplo) coloque una foto en ella mediante la opción del menú “Edición”, “Pegar desde archivo”. La imagen seleccionada deberá ser lo suficientemente grande, como para cubrir todo el fondo de la ventana o incluso mayor, la idea es asegurarse de que se siga viendo correctamente aún cuando se amplíe la ventana principal de Omnis, una imagen en formato JPG de 1280x1024 píxeles y a 72 dpi, puede ser suficiente, al final de éste artículo puede un ejemplo. Una vez hecho esto, deberemos modificar las siguientes propiedades de nuestra ventana “wBackground”:

$closebox = kFalse
$growbox = kFalse
$style = kSimple


Además de éstas deberemos cambiar la propiedad “$edgefloat” para fijar su valor a “kEFrightBottom” de éste modo nos aseguraremos de que la imagen en la ventana será automáticamente ajustada, cada vez que cambie su tamaño por acción del usuario. Ahora, y en el método “$construct()” de la ventana “wBackground” deberemos añadir el siguiente código:

Do $cinst.$width.$assign($root.$modes.$width)
Do $cinst.$height.$assign($root.$modes.$height)
Do $cinst.$top.$assign(0)
Do $cinst.$left.$assign(0)


A continuación, añadiremos una segunda clase-ventana con el nombre “wSuper”, a la cual añadiremos un método “$event()”con el código siguiente:

On evWindowClick

   If pClickedWindow.$name='wBackground'
     Quit event handler (Discard event)
   End If


Este código nos permitirá asegurarnos de que la ventana “wBackground” permanezca en todo momento anclada al fondo.

Ahora tan sólo nos faltará asignar la ventana “wSuper”, como superclase en todas y cada una de las clases-ventana que contenga nuestra librería. Podemos optar por hacer esto manualmente, cambiando la propiedad “$superclase” para asignarle el valor “wSuper” o bien (mi preferida) mediante el siguiente comando:

Do $windows.$sendall($Ref.$superclass.$assign('wSuper'))

Finalmente deberemos  añadir el código necesario para hacer visible la ventana “wBackground”, lo cal haremos escribiendo el comando mostrado a continuación, sobre el método “$construct” de la clase “Startup_Task” de nuestra librería en construcción:

Do $windows.wBackground.$openonce()


18 de agosto de 2015

Polimorfismo en Omnis

Una ventaja de usar encapsulación en objetos con Omnis, es la posibilidad de que éstos puedan reaccionar de manera diferente ante un mismo mensaje. Veamos un ejemplo. Supongamos que disponemos de tres ventanas diferentes con información relativa a la actividad de nuestros clientes y una cuarta ventana con la lista con todos ellos, la idea es que tras pulsar sobre la línea de un cliente cualquiera, pueda reflejarse la información pertinente sobre las restantes tres ventanas. Este evento deberá enviar un mensaje a las otras ventanas con la información del cliente seleccionado, por su parte, cada una de ellas deberán reaccionar de manera diferente: La primera deberá mostrar la dirección del cliente (Address list) y otros detalles, la segunda (Invoices) deberá mostrar todas sus facturas, mientras que la tercera (Delivery notes) deberá mostrar una lista con todos los albaranes entregados.


Lo mejor que podemos hacer para enviar el mensaje a todas las instancias-ventana, (en nuestro caso a todos los objetos del cliente), es empezar primero por construir un método público para cada ventana, el cual será receptor de nuestro mensaje. Para evitar que se nos pueda olvidar alguna de las ventanas implicadas, podríamos optar por crear un clase común con un método público denominado “$setCustomer”, a fin de que sea la superclase de todas las ventanas implicadas. El método no contendrá código alguno, excepto el comentario sobre que éste puede ser anulado (desheredado). Después, (en cada subclase ventana) podremos observar éste mismo método mostrado en color azul y que por tanto podremos “desheredar”. El método deberá contener el parámetro “pCustID”, éste nos permitirá (en función de la ventana de que se trate) cargar los datos generales, datos de facturas y albaranes localizados en la base de datos, según en el identificador (pCustID) pasado a la ventana.


Ahora sólo nos falta saber, cómo enviar el mensaje desde la ventana con la lista de clientes, hacia las otras instancias-ventana. Para ello utilizaremos el método “$sendall” que (como sabemos) permite enviar un mensaje a todos los miembros de un grupo. En nuestro caso, lo escribiremos dentro del método “$event()” correspondiente a la lista de clientes (Customer list):

On evClick
    Do $iwindows.$sendall($ref.$setCustomer(ivCustomerList.ID))

Tras un clic sobre la lista de clientes, se enviará un mensaje a todas las instancias-ventana abiertas, para que sea ejecutado el método “$setCustomer()”, pasándose el ID del cliente seleccionado.

Tenga en cuenta que Omnis podrá mostrar un mensaje de error, en el caso de que alguna de las ventanas abiertas no contenga el método “$setCustomer”. Pero no hay que alarmarse, pues existen varias posibilidades para cambiar este comportamiento. Una modo sencillo, sería ir a las “Prefs” (Preferencias) de la biblioteca y cambiar su propiedad “$reportnotationerror” por “kFalse”.

Otra posibilidad, es enviar el mensaje sólo a los objetos que contengan el método “$setCustomer”. Para ello, deberemos añadir un parámetro adicional al “$sendall” el cual actuará a modo de filtro, enviando el mensaje sólo a las instancias que lo contengan:

On evClick
   Do $iwindows.$sendall($ref.$setCustomer(ivCustomerList.ID),
      $ref.$methods.//$setCustomer//)

Las dos barras invertidas dobles, permite indicar a Omnis, cual es el nombre del método que buscamos.