El presente caso de estudio corresponde al trabajo desarrollado por Susana Sánchez para la realización de una agenda básica, con la peculiaridad de incorporar la programación de mensajes para una hora (fecha) dada y que, en su momento, serán expuestos en forma de audio al usuario. El usuario crea estos mensajes en formato de texto (en la forma en que se muestra en la Figura 19-1) y es la aplicación la que se ha de encargar de transformalos en audio (en este caso en voz) para reproducirlos en el momento oportuno.
Figura 19-1. Formato de la tarjeta que permite la especificación de un mensaje y su programación en el tiempo.
La aplicación está diseñada en torno a una sencilla pila que dispone en cada tarjeta los controles necesarios para cada tarea y son:
Entrada en la aplicación, que agrupa al título y los créditos.
Controles del audio a generar, como velocidad de locución y formato del fichero.
Creación y programación del evento.
La pila da incio a todo el proceso teniendo en cuenta que en posteriores ejecuciones de la misma pueden haber eventos ya planificados (programados con anterioridad) que hay que dar opción a que lo sean, por ello, el principio se dedica a confirmar que en el directorio que acoje a los ficheros de datos de la pila existan o no ficheros de audio: eventos ya preparados.
# # Pila principal # global i, fichero, citas, hora_actual On preopenstack if there is a directory "c:\Agenda" then set the directory to "c:\Agenda\" else create directory "c:\Agenda\" set the directory to "c:\Agenda\" end if end preopenstack on openStack set the directory to "c:\Agenda\" put the files into url "binfile:c:\Agenda\audios.txt" send "testfecha" to fld "comprobarFecha" of card "titulo" of stack "agenda" # go to card 1 end openStack
El esquema de nombres para los ficheros debe ser lo suficiente como para dar cumplimiento a la tarea. Por este motivo los ficheros se nombrarán como una expresión de fecha (que incluirá día, mes y año) y hora(en formato de hora y minutos) más la extensión del fichero.
Figura 19-2. Tarjetas que componen la aplicación, la pila principal: entrada (título), configuración del audio y controles del recordatorio.
El título de la aplicación se presenta en una tarjeta que, diligentemente, da paso a la que permite establecer un recordatorio: la tarjeta "tarjeta". De paso, se ha aprovechado para contener funciones que se utilizarán más tarde en esa propia tarjeta.
# # Tarjeta "titulo" # on openCard send mouseUp to me in 3 seconds end openCard on mouseUp go to card "tarjeta" end mouseUp # # Campo de texto "comprobarFecha" (oculto) # global citas, mes, dia,year, anyo, au_fecha on testfecha convert time() to dateitems put it into citas if item 3 of citas <10 then put "0"&item 3 of citas into dia else put item 3 of citas into dia if item 2 of citas <10 then put "0"&item 2 of citas into mes else put item 2 of citas into mes put item 1 of citas into year put char 3 of year &char 4 of year into anyo send "testhora" to fld "quien" of card "titulo" of stack "agenda" end testfecha # #Campo de texto "voces" # on formatos global hora_actual if matchtext (url "c:\Agenda\audios.txt", hora_actual&".aiff") then play hora_actual&".aiff" delete file hora_actual&".aiff" end if send "testfecha" to fld "comprobarFecha" of card "titulo" of stack "agenda" in 60 seconds end formatos # # Campo de texto "VS" (que contiene la versión de la aplicación) # on fechayhoraok global hora_actual delete file "c:\Agenda\audios.txt" open file "c:\Agenda\audios.txt" for read put the files into url "binfile:c:/Agenda/audios.txt" if matchtext (url "c:\Agenda\audios.txt", hora_actual&".wav") then play hora_actual&".wav" delete file hora_actual&".wav" end if if matchtext (url "c:\Agenda\audios.txt", hora_actual&".au") then play hora_actual&".au" delete file hora_actual&".au" end if send "formatos" to fld "voces" of card "titulo" of stack "agenda" end fechayhoraok # #Campo de texto "quien" (que guarda la autoría de la obra) # global dia, citas, mes,year, anyo, au_fecha, hora, minu, au_hora, hora_actual on testhora put dia&mes&anyo into au_fecha if item 4 of citas <10 then put "0"&item 4 of citas into hora else put item 4 of citas into hora if item 5 of citas <10 then put "0"&item 5 of citas into minu else put item 5 of citas into minu --put hora&minu into au_hora put au_fecha&","&hora&minu into hora_actual send "fechayhoraok" to fld "vs" of card "titulo" of stack "agenda" end testhora
En la tarjeta que es protagonista de todo este caso, se puede encontrar la serie de controles que permiten la edición de un mensaje, su programación en el tiempo (incluyendo la conversión a audio), la configuración del audio a generar, la ayuda y una opción para terminar la aplicación.
Nada más entrar en la tarjeta se limpian los campos editables para que el usuario pueda empezar desde esa situación. La cual puede recuperar en cualquier momento utilizando el botón cuya leyenda reza Nueva. Ambos códigos son idénticos.
# # Tarjeta "tarjeta" # #global i, fichero, citas, hora_actual, cinco, au_hora,au_fecha on openCard put empty into fld "cita" put empty into fld "hora" put empty into fld "fecha" end openCard # # Botón "nuevo" (que muestra "Nueva") # on mouseUp put empty into fld "cita" put empty into fld "hora" put empty into fld "fecha" end mouseUp # # Botón "recordar" (que muestra un texto de "Grabar") # on mouseUp global fichero, texto1, audio, velocidad if the length of fld "fecha" <> 8 then \ answer warning "El formato de la fecha debe ser dd/mm/aa" \ with "OK" titled "Fecha errónea" if the length of fld "hora" <> 5 then \ answer warning "El formato de la hora debe ser hh:mm" \ with "OK" titled "Hora errónea" palette stack "descargando" if audio is empty then put ".wav" into audio if velocidad is empty then put "normal" into velocidad put urlEncode(text of fld "cita" of this card) into texto1 put (char 1 of fld "fecha"& char 2 of fld "fecha"&\ char 4 of fld "fecha"& char 5 of fld "fecha"&\ char 7 of fld "fecha"& char 8 of fld "fecha"&\ ","&char 1 of fld "hora"& char 2 of fld "hora"&\ char 4 of fld "hora"& char 5 of fld "hora") into fichero put url ("http://wwwtts.research.bell-labs.com/cgi-user/tts/spanishtts?text=" &\ texto1 &\ "&rate=normal&dialect=Castilian&audio="&\ audio) into url ("binfile:"&fichero&audio) close stack "descargando" end mouseUp # #Botón "config" ("Configuración del texto") # global cinco on mouseUp visual effect scroll left go to card "Configura" end mouseUp on cinco convert time() to dateitems put it into minuto if (minuto mod 5) =0 then put si into cinco else put (minuto mod 5) into x send cinco to me in 1 minute end cinco
En la parte baja de la tarjeta hay están los otros dos controles que hemos enunciado:
# # Botón "ayuda" # on mouseUp palette stack "ayuda" end mouseUp # #Botón "salir" # on mouseUp quit end mouseUp
Si se ha utilizado el botón Configuración del audio, se accede a la sencilla tarjeta que pemite establecer la velocidad y el tipo de fichero:
# # Tarjeta "Configura" # # Botón "au" global audio on mouseUp put ".au" into audio end mouseUp # Botón "wav" global audio on mouseUp put ".wav" into audio end mouseUp # Botón "aiff" global audio on mouseUp put ".aiff" into audio end mouseUp # Botón "f" (con el texto "Rápido") global velocidad on mouseUp put "fast" into velocidad end mouseUp # Botón "s" (con el texto "Lento") global velocidad on mouseUp put "slow" into velocidad end mouseUp # Botón "n" (con el texto "Normal") global velocidad on mouseUp put "normal" into velocidad end mouseUp
La aplicación se apoya en otras pilas del sistema para realizar su tarea y se ha creado una a propósito de la obtención de los ficheros desde la web, que es de particular interés en este caso (Figura 19-3).
La pila de "descargando" se utiliza para mostrar los mensajes al usuario que a este respecto se den. Sólo se emplea código para estas tareas que se concreta en la presentación del primer mensaje, que realiza el:
on openCard hide fld texto show fld texto with visual effect scroll left very slow end openCard
y en los botones de Aceptar que cerrarán esta propia pila con
on mouseUp quit end mouseUp
Figura 19-3. Otras pilas forman parte del proyecto, aparte de las habituales del sistema, para informar del estado de la descarga de ficheros desde la web.
Como en toda aplicación se agradece que exista un apartado de ayuda, en este caso relativa a la secuencia de acciones a desarrollar para emplear la misma. La pila destinada a contener la ayuda es las más sencilla: tiene botones que perimten una navegación muy básica y se puede ver en la Figura 19-4. El código que esta contiene es tan sencillo como:
# # Pila "Ayuda" # # Botón "Aceptar" (de la primera tarjeta) y "Salir" (de la segunda) on mouseUp close this stack end mouseUp # Botón "Continuar" on mouseUp go to next card end mouseUp
En esta sección se ha presentado la primera parte y se propone una "Agenda 2ª parte". Esta es una continuación de la agenda de Susana planteada como grabadora de mensajes con un par de variantes:
Graba los recordatorios directamente en audio, para lo cual habrá que recurrir al ejemplo visto en la Capítulo 8 y recordarle al usuario que debe disponer de un micrófono, además de la tarjeta de audio y los altavoces o auticulares que ya dábamos por supuesto. Aunque en este caso deberíamos liberar al usuario de tomar la decisición de los parámetros de captura de audio, quizá dejar una opción de más o menos calidad, pero ocultando todos los valores numéricos que lo implementan.
Envia mensatges escrits o grabats (per media player / snd / similar) en un attach (en format HTML que s'activa per el onLoad del body).
Al respecto del código original, a mi parecer, no es buena idea utilizar objetos que tienen dos misiones diferentes por la complicación que supone asociar dichas tareas a un objeto: me refiero a los controles que, ocultos o no, en la primera tarjeta guardan código para comprobar la fecha al tiempo que muestran un texto estático en la aplicación.
Por otra parte, el lector que ha seguido la obra habrá podido apreciar que esta aplicación, tal como está, sólo puede utilizarse en un sistema operativo que tenga por costrumbre poner nombre (con un criterio variable en función de su punto de montaje) a sus unidades de disco y en un directorio que no están bajo el control del usuario. Sería muy interesante deshacerse de esta lacra en las futuras versiones.
Aunque la aplicación fue desarrollada a finales del año 2000, el formato en que se exprea el año no sobreviviría al "efecto 2000" o similar. Debido a la aplicación en cuestión, tampoco parece necesario insistir más sobre que el comentarlo.
Lo que si es posible es mejorar cuestiones en las que se utiliza código de forma muy recurrente, como en la asignación de valores a variables globales de la configuración del audio. Para poder ampliar esta sección sería necesario crear nuevos controles y darles código. En cambio, si este fuese en función de su nombre hubiese facilitado la creación de los existentes y la posible ampliación, si fuera el caso. Por ejemplo, agrupando los controles que dan la extensión al archivo y nombrándolos como tales extensiones se podría haber hecho:
# # En el grupo correspondiente ... # global audio on mouseUp put the short name of target into audio end mouseUp