Archivo por años: 2007

Puliendo versiones

Acabo de lanzar dos nuevas versiones de FBZX y DeVeDe. No traen grandes cambios, pero seguro que serán agradecidos por los usuarios.

Precisamente es FBZX el programa que más me preocupa en estos momentos (dejando de lado los serios problemas de GTKpsProc), pues el emulador de Z80 que lleva, escrito por Marat Fayzullin, no es GPL. Por desgracia no es fácil sustituirlo por otro. Estoy evaluando la dificultad de escribir uno nuevo (tarea árdua pero no imposible) o intentar adaptar alguno extraído de BlueMSX u OpenMSX. Esta última opción parece la más sencilla a priori, pero en la práctica hay muchos cambios que hacer, así que tendré que evaluarlo con calma.

Respecto a DeVeDe los cambios son mínimos: nuevas lenguas, corrección de un par de pequeños bugs, y el añadido de dos comandos extra en la conversión: CGOP y SC_THRESOLD. Estos hacen que los GOPs estén siempre cerrados y midan siempre lo mismo, lo que debería aumentar la compatibilidad con viejos reproductores.

DeVeDe 3.4

Ayer me tuve que quedar hasta las tantas corrigiendo un par de detalles que quedaban en DeVeDe, pero hoy, por fin, he podido lanzar la versión 3.4. Aparte de las pequeñas novedades (poder usar sonido 5.1 y generar DVDs con GOPs de 12 fotogramas para mejorar la compatibilidad) y errores corregidos (no se podía previsualizar la película si se convertía a DIVX, o no generaba bien las imágenes VCD), el principal cambio ha sido el código: por fin está limpito y ordenado, con lo que añadir nuevas cosas será una bicoca 🙂

Y la primera cosa que tengo que añadir en la próxima versión será el poder mezclar vídeos con diferentes relaciones de aspecto en el mismo disco. En efecto, a última hora de ayer descubrí que si se mete un vídeo con relación de aspecto clásica (4:3) en el mismo título que un vídeo WideScreen (16:9), ambos se verán con el mismo aspecto. Se trata de una limitación del estándar DVD. La solución consiste en meterlos en titlesets diferentes. Por desgracia, no es posible saltar directamente de un titleset a otro, por lo que implementarlo directamente en DeVeDe rompería la posibilidad de saltar de un título al siguiente, o al anterior, etc.

Una solución que probé fue añadir la opción jumppad en el XML de DVDAuthor. Esa opción añade automáticamente algo de código que permite saltar desde cualquier parte del DVD a cualquier parte, sin las limitaciones del estándar. Funcionaba bien, pero para asegurarme rebusqué en google y descubrí que, en ciertos casos, puede romper la compatibilidad con algunos reproductores. En la misma página se explicaban algunos métodos para conseguir lo mismo «manualmente» (básicamente, añadir un menú virtual con una función que salte al título que se le pase en un registro). Por desgracia es algo demasiado complejo como para implementar sin haberlo probado exhaustivamente, así que no irá hasta la próxima versión.

Otros cambios que quiero añadir son, por ejemplo, el soporte de matrices de codificación alternativas, permitir múltiples subtítulos, o poder elegir la pista de audio que se desee cuando el video original tiene varias.

Bugs y trancazos

Parece que estoy incubando algo. Espero que sea un simple resfriado y no una gripe. En este momento, después de tomarme una aspirina, ya estoy mejor, por eso aprovecho para añadir una nueva entradilla aquí.

Hace unos días, mientras ultimaba la nueva versión de DeVeDe, encontré un molesto bug en el widget Gtk.FileChooserButton; en concreto en el método set_filename(). Cuando el usuario pulsa el botón Propiedades para cambiar las propiedades de una película (tasa binaria, resolución…), uso ese método para rellenar dicho FileChooserButton con la ruta completa del archivo correspondiente; sin embargo, a veces (no siempre) fallaba, quedando el widget vacío. Tras hacer varias pruebas llegué a la conclusión de que era totalmente aleatorio: no dependía de la longitud del nombre, ni del directorio en que se encontrase, ni del número de niveles… el mismo archivo a veces aparecía correctamente en el widget y otras veces no. Con Ubuntu 7.04 (que usa GTK 2.10) dicho fallo no ocurría (que yo recordase, al menos).

Dado que no tenía claro si el error estaba en GTK o en los bindings para Python (PyGTK), durante el fin de semana hice un pequeño programa de prueba en C. El resultado es que, efectivamente, el error es de GTK. Además probé el mismo código en una Ubuntu 7.04 y, tal y como sospechaba, no falla (por lo que vi en la lista de cambios de GTK 2.10 a 2.12, los desarrolladores hicieron muchas mejoras en la clase FileChooser). El problema realmente gordo es que todos los intentos por esquivar el problema han fallado, lo que significa que mientras no lo corrijan, DeVeDe no funcionará correctamente 🙁

De momento he notificado el bug y he añadido una nota en la FAQ de DeVeDe. Mañana o pasado (cuando la cabeza deje de darme vueltas) publicaré la nueva versión.

No hay dos sin tres

Nueva versión de GtkPSproc. Algo pasa con Cups, que se empeña en dar error al usar lpadmin para crear una nueva impresora si se especifica un fichero PPD. Afortunadamente GtkPSproc funciona bien sin él, por lo que lo he eliminado, de manera que reciba el PostScript original directamente.

Otra cosa que he descubierto es que el PPD para impresora PostScript genérica creado por FooMatic no pasa la prueba de cupstestppd. Parece que no le gusta que se especifique un parámetro por defecto con el nombre default.

Y por último, parece que python-fam no funciona bien con Python 2.5 en algunos equipos, así que he decidido sustituirlo por python-gamin, que se supone que es lo que se usa hoy en día.

De todas maneras, el código actual de GtkPSproc está demasiado sucio, así que estoy considerando reescribirlo en condiciones (en python, por supuesto), igual que he hecho con DeVeDe. De momento estoy rehaciendo la interfaz con Glade-3, porque no se que ocurre que si cargo el fichero XML de la vieja interfaz (creado con Glade-2) y modifico cualquier cosa, dejan de funcionar los eventos en el programa, como si no ejecutase el signal_autoconnect(). Supongo que será alguna incompatibilidad rara, no se.

Y ya que hablo de DeVeDe, hay noticia: en cuanto reciba los tres ficheros de traducciones que faltan lanzaré la versión 3.4, con soporte completo de sonido 5.1, aunque la verdadera novedad de esta versión es que, por fin, terminé de refactorizar todo el código y ahora ya se puede mirar para él sin sentir verguenza ajena; y lo que es más importante: ahora es extremadamente fácil añadir nuevas opciones de codificación. Espero que en las nuevas versiones se empiece a notar ésto.

¡Tenemos un problema!

A veces los fallos se quedan muy, pero que muy escondidos. Así, la última versión de GtkPSproc tenía uno garrafal que impedía por completo su uso. ¿Y como se me pudo colar? Pues porque sólo aparecía cuando no había un fichero de configuración en la cuenta.

Lo increible es que no me lo comunicaron hasta ayer, cuando esa versión tiene casi un año…

Selección multiple

En Trabajando con GtkTreeView en Python explicaba como utilizar el complejo pero versatil widget GtkTreeView. Sin embargo, faltaba un detalle importante: ¿como usar selección múltiple?

Lo primero es poner el selector del GtkTreeView en modo de selección múltiple:

treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

Ahora ya podremos marcar más de una fila simultáneamente usando las teclas Mayúsculas y Control.

Leer los elementos marcados es tan sencillo como obtener primero el iterador y el arbol:

tree,iter = self.z88tree.get_selection().get_selected_rows()

Si el iterador es None, no hay ninguna fila seleccionada, pero si lo está, no tenemos más que recorrer los elementos del iterador para acceder a las filas. Con ellas, podemos usar el método get_value del arbol para obtener el valor de cada una.

En este ejemplo almacenamos en la lista ret el valor de la columna cero de cada fila seleccionada:

ret = []
for item in iter:
    ret.append(tree.get_value(tree.get_iter(item),0))

Fácil, fácil, para toda la familia.

Escribiendo con PyGTK como $DEITY manda

Hoy he lanzado una nueva versión de Z88Transfer. Los cambios observables por los usuarios son más bien pequeños: ahora muestra una barra de progreso durante la transferencia, permite transferir varios archivos de una sola tacada, comprueba más exhaustivamente si un archivo nuevo sobreescribe a uno viejo, y, sobre todo, simplifica muchísimo su uso en windows.

Sin embargo, por dentro los cambios son mucho más radicales, pues prácticamente he reescrito la aplicación. Las razones han sido tres:

  • Por un lado, varias partes del código estaban muy sucias y eran muy poco modulares.
  • Por otra, quería internacionalizar la aplicación, para poder traducirla a otros idiomas (aunque en esta versión todavía no hay traducciones).
  • Por último, quería organizar en condiciones el código de las ventanas poniendo los manejadores de eventos de cada una en su propia clase (haciéndolo así más modular mantenible), además de simplificarlo usando diálogos para los distintos mensajes que pueden aparecer, en lugar de ventanas modales.

La última razón es especialmente importante. En el caso de SuperShow, el código era ya bastante bueno pues es la última aplicación que he escrito hasta la fecha, pero en el caso de Z88Transfer el código era realmente sucio, pues fue la primera aplicación que hice con PyGTK. Sin embargo, gracias a que es una aplicación relativamente sencilla, el código aún era razonable (la transferencia de ficheros y la conversión de formatos van en sendas clases separadas, lo que simplificó la reescritura).

¿Y a qué viene ésto? Pues viene porque también estoy reescribiendo el código de DeVeDe. Cuando comencé a escribir con PyGTK no sabía como generar una única ventana ni como conectar los eventos de ésta con métodos de una clase, pues la documentación del módulo PyGlade era escasa, por no decir nula. El resultado fue que la única manera que tenía de programar era generando una instancia de absolutamente todas las ventanas disponibles en el archivo de Glade, y metiendo todas las funciones de eventos directamente en un único fichero, lo que dio lugar a un código… bueno, llamémoslo caótico (por ser benévolo conmigo mismo), y muy poco mantenible.

Ahora lo veo en retrospectiva y me parece increible que haya sido capaz de escalar el código original de DeVeDe hasta el nivel actual, aunque siendo yo el programador supongo que no tiene mucho mérito. El que sí que tiene mérito es, sin duda, Peter Gill, que lo revisó y modificó para que funcionase también en windows. Un código que fue escrito originalmente como una solución chapucera y rápida para hacerle con comodidad a mi madre una pequeña colección de DVDs con los programas de Arguiñano que bajaba de la mula.

En estos momentos ya he reescrito toda la parte de conversión de vídeos y de generación de la imagen de DVD usando una orientación a objetos bastante razonable, y posiblemente lance una versión sólo con esas modificaciones, pues el nuevo código debería ser mucho más resistente a fallos tontos (el propio Peter, cuando lo revisó para asegurarse de que funcionase en Windows, comentó que sería una tarea muchísimo más sencilla gracias a la nueva arquitectura). El siguiente paso será cambiar a una clase independiente todo el código de la ventana de propiedades de los vídeos, para permitir añadir con más facilidad nuevas opciones de codificación. Por último, meteré en su propia clase la ventana principal y pondré la ventana de selección de tipo de disco como un diálogo. Entonces podré dar por terminada la refactorización del código y seguir añadiendo cosas nuevas.

Esos pequeños placeres

Mi caja actual tiene un pequeño fallo de diseño: el conector frontal de USBs está muy cerca de la salida de auriculares, por lo que no puedo conectar a la vez los cascos y mi reproductor de MP3 para grabar cosas en él. Sin embargo, un poco más separada está la conexión de micrófono, por lo que se me ocurrió hacer un par de puentes para que el sonido salga por ésta, y así no tener problemas. Llevaba tiempo queriendo hacerlo, pero hasta hoy no saqué ganas.

¿Y qué tiene que ver ésto con el título? Bueno, la última vez que usé un soldador para hacer alguna chapucilla propia fue hace casi dos años, cuando amplié la memoria de mi Z88, y es también la primera vez que lo uso desde que me independicé. Volver a cogerlo, aunque fuese para algo tan sencillo, ha sido realmente agradable. No te das cuenta de lo mucho que echas de menos hacer algo hasta que lo vuelves a hacer y disfrutas. Llevo tanto tiempo concentrado en mi trabajo y en mis proyectos de programación que tengo la electrónica completamente abandonada.

Después de ésto quiero hacer algún proyectillo nuevo, pero antes tengo que comprar una mesa adecuada. ¿Por qué no hay un Ikea cerca cuando lo necesitas?

SuperShow

Finalmente he sacado la versión 2.0 de SuperShow. En ella he pulido la interfaz y he limpiado algo más el código. Entre las novedades está un código Flash muy mejorado, que ahora permite pausar la presentación, retroceder y avanzar, y reproducirla de nuevo cuando termina.

Otra importante novedad es que ahora permite grabar y volver a cargar las temporizaciones. Esto es especialmente interesante porque así es posible generar de nuevo una presentación con una versión posterior de SuperShow, aprovechando las ventajas que traiga (por ejemplo, nuevos controles de la presentación, corrección de bugs en el código Flash…).

Además, ahora la temporización es precisa, y no como en la versión anterior, en que las diapositivas cambiaban aproximadamente en el punto deseado.

Por último, ahora las presentaciones son compatibles con Gnash, el reproductor de Flash libre de GNU. Esto significa que, aún usando un formato propietario, mantengo la libertad de los usuarios. Más que en el código Flash, los cambios para ésto estuvieron en el propio Gnash, y precisamente tengo que reconocer que el equipo del proyecto se ha portado increiblemente bien: no solo resolvieron en un tiempo record los bugs más complicados que notifiqué, sino que admitieron todos los parches que envié para corregir otros bugs que sí eran lo suficientemente evidentes como para que pudiese arreglarlos yo. El resultado es que las presentaciones del nuevo SuperShow funcionarán casi al 100% en la próxima versión estable de Gnash.

Y digo «casi» porque, de momento, el avance, retroceso y pausa no funcionan correctamente debido a un bug en el método que activa un sonido. Sin embargo, están trabajando en ello y seguro que en breve estará implementado. Otro fallo es que, cuando simplemente se especifica un color de fondo en lugar de usar una primitiva o una imagen, Gnash lo pinta de negro (en las presentaciones hechas con Impress, si no se pone ingún fondo, debería ser blanco). Este bug es, por lo que comentan en el Bugzilla, bastante complejo, por lo que, como solución temporal, es recomendable utilizar un fondo hecho con un rectángulo de color que ocupe toda la diapositiva.

Version 4.9 de GAG

Hace un par de días tuve que sacar una nueva versión de GAG, la 4.9. La razón fue que, al cambiar toda la parte de configuración al principio del código, cometí un pequeño fallo: la posición de memoria en donde se almacena el tipo de teclado también quedó desplazada, pero el código de GAG seguía leyendo de la antigua. Para colmo, el instalador metía el valor del teclado en la posición antigua, con lo que el resultado era que, al arrancar GAG desde el instalador, el teclado funcionaba perfectamente, pero en cuanto se instalaba en disco duro y se reiniciaba, pasaba a usar un teclado aleatorio. En mi caso, por puro azar fue siempre QWERTY, por lo que no advertí el error; pero a varios usuarios les tocó el teclado ruso, con lo que se encontrarón con que, una vez instalado, no era posible modificar la configuración (sí podían arrancar los sistemas operativos previamente configurados, porque los números están en las mismas teclas en todas las lenguas).