• Autor: Doug Lee, en colaboración con el equipo de accesibilidad de Cisco
  • Versión actual: 2018.04.1
  • Descargar

Este complemento mejora el soporte que da NVDA a la aplicación de mensajería instantánea Cisco Jabber. El complemento añade los siguientes atajos de teclado, todos configurables desde el diálogo Gestos de Entrada, categoría Cisco Jabber:

  • NVDA+t: versión mejorada del script para leer el título de la ventana, en este caso verbaliza información sobre ventanas de alerta, si las hay.
  • ctrl+` y ctrl+shift+` cambia entre las ventanas de alerta disponibles.
  • ctrl+e y ctrl+h mueven el foco al cuadro de edición y al historial del chat, respectivamente.
  • NVDA+shift+v verbaliza el número de versión de Cisco Jabber.

Además, este complemento proporciona las siguientes mejoras:

  • Mejoras en la capacidad para seguir el foco mientras el usuario navega por las pantallas.
  • Soporte adecuado para el árbol de contactos.
  • Soporte adecuado para los botones de opción de contactos, chats, etc. de la pantalla principal, incluyendo el anunciado de la cantidad de eventos perdidos o no leídos.
  • Soporte para los cuadros combinados (desplegables) de Jabber.
  • Información mejorada sobre los cambios de estado de casillas de verificación.
  • Muchos campos etiquetados.
  • Información hablada mejorada en algunos diálogos al pulsar NVDA+b
  • Soporte básico para navegar por los diálogos de informe de errores de Cisco Jabber.

Para obtener más información, consulta la documentación que acompaña al complemento.
Nota: este complemento viene comprimido en un archivo .zip. Deberás descomprimirlo para obtener el archivo .nvda-addon que podrás instalar en NVDA.

El complemento no oficial Input Lock, que permite bloquear y desbloquear los dispositivos de entrada del equipo pulsando una simple combinación de teclas, se actualiza a la versión 1.2-dev. En esta actualización se han introducido varias mejoras que durante mucho tiempo nos habéis pedido, entre ellas:

  • Ahora el ratón ya no se libra de los efectos del complemento. También se bloqueará junto con el teclado, la pantalla táctil y la pantalla braille.
  • ¿Tocas accidentalmente el ratón, trackpad o touchpad cuando trabajas con tu portátil y haces que el puntero se vaya a cualquier parte de la pantalla y provoque desastres no deseados? Ahora hay un nuevo atajo, NVDA+shift+m, que ayudará a evitar esta molesta situación. Sí, finalmente se puede bloquear el ratón de manera independiente.

Este último cambio no bloquea el ratón por completo, ya que si no no podrías utilizar las órdenes estándar de NVDA que lo desplazan. Cuando esté bloqueado sólo el ratón, podrás desplazarlo con complementos como Golden Cursor o los atajos de movimiento hacia el objeto con el foco. También podrás hacer clic con los botones izquierdo y derecho, tanto los del ratón físico como los que utiliza NVDA del teclado numérico (dividir y multiplicar, respectivamente).
Por otro lado, y ya que se permite hacer clic en este modo, los toques simples en un touchpad también pueden ser fatales. Se recomienda desactivarlos desde la zona correspondiente en el panel de control ofrecido por el controlador del dispositivo, en los casos en los que esto sea posible.
Más información y descarga de Input Lock
Si te gusta Input Lock, no dudes en decírnoslo mediante un comentario, respondiendo por la lista de correo o en redes sociales. Y si no te gusta y quieres mejorar algo, también. ¡Tu opinión es muy importante!

Los complementos Emule y Read Feeds, mantenidos por Noelia Ruiz, se actualizan con traducciones mejoradas. En el caso de Read Feeds, además, ahora se muestran el título del feed predeterminado y el perfil actual en el título del diálogo feeds.
Más información y descarga de Read Feeds
Más información y descarga del complemento para Emule
Como siempre, te recordamos que es muy importante que mantengas tus complementos actualizados. De esta forma, garantizas que tu experiencia con NVDA sea óptima.
Si te gusta la información que te ofrecemos, por favor, plantéate hacer una donación y echarnos una mano para que podamos mantener la web y continuar impulsando y expandiendo la comunidad. Sin tu ayuda, no sería posible.

¡Hola a todos!
Faltan un par de semanas para que NVDA 2018.2 vea la luz, y sin embargo nadie ha parado de hablar de los cambios que trae desde hace ya un tiempo. Uno de los más importantes es el nuevo diálogo de preferencias organizado en categorías, al que hemos hecho referencia ya en varias entradas al hablar de complementos que se actualizan. En este tutorial veremos qué hay que hacer para que el diálogo de preferencias de nuestro complemento se integre en el nuevo diálogo de opciones de NVDA. Nos apoyaremos en el complemento Enhanced Aria, ya que su código es bastante simple, está en un único módulo y los cambios realizados son relativamente sencillos de entender. ¡Comencemos!
Nota: este es un artículo avanzado de desarrollo. Se asume que el lector sabe hacer complementos sencillos, y conoce el lenguaje Python con todo lo que ello conlleva.

Creación de ajustes sensibles a cambios de perfil

NVDA nos da mucha flexibilidad a la hora de crear diálogos para nuestros complementos. De hecho, nos da tanta que nos podemos perder, hacernos un lío, y programar todo con wx para luego darnos cuenta de que existen módulos que nos abstraen de un montón de detalles complejos. Con la configuración pasa exactamente lo mismo, podemos saber que existe configobj, pero ignorar que hay una capa por encima que nos facilita la vida. Definir una especificación de configuración es tan sencillo como crear una variable global en el módulo de nuestro complemento, indicando de qué tipo son los valores y el valor por defecto de cada uno. Esta es la configuración de Enhanced Aria:
confspec={
 "reportBanner":"boolean(default=true)",
 "reportMain":"boolean(default=true)",
 "reportContentinfo":"boolean(default=true)",
 "reportNavigation":"boolean(default=true)",
 "reportComplementary":"boolean(default=true)",
...}
En el caso de Enhanced Aria, todo lo que se configura es booleano, casillas que se marcan o desmarcan. Una vez definida la especificación, hay que decirle a NVDA que la añada al conjunto de especificaciones. Una variable global definida por sí sola en un módulo no va a hacer nada: config.conf.spec['aria']=confspec
Después de este inciso, breve pero necesario para entender todo lo demás, vamos a los diálogos en sí.

El diálogo tradicional de ajustes

Un diálogo tradicional de ajustes es una clase que hereda de gui.settingsDialogs.SettingsDialog. ¡Cuidado con las mayúsculas al programar, nos pueden hacer pasar un mal rato! Todos los diálogos de preferencias de NVDA heredan de esta clase, y los complementos también suelen hacerlo. La clase SettingsDialog nos ofrece varios métodos y propiedades que podemos redefinir:

  • title: propiedad que define el título del diálogo. Debe ser una cadena de caracteres.
  • makeSettings(self, sizer): este método se usa para rellenar el sizer que se recibe como parámetro con los controles que queramos. Enseguida vemos un ejemplo.
  • postInit(self): se ejecuta tras crear y mostrar el diálogo en pantalla. Sirve para llevar el foco por defecto a un control que nos interese, por ejemplo.
  • onOk(self, evt): NVDA llama a este método cuando se pulse el botón aceptar. Los botones Aceptar y Cancelar vienen ya en la clase padre, no tenemos que añadirlos en makeSettings. Aquí se hacen cosas tales como guardar la configuración. Importante llamar al método de la clase padre cuando terminemos.
  • onCancel(self, evt): método que se ejecuta al pulsar el botón cancelar. Importante llamar al método de la clase padre si lo redefinimos.

NVDA 2018.2 extiende este diálogo añadiendo un botón de aplicar, el evento asociado (onApply), y la posibilidad de que el diálogo pueda abrirse varias veces simultáneamente. Todas estas novedades son opcionales para conservar la compatibilidad con complementos que no se adapten a ellas.
Veamos algunos ejemplos. El título de Enhanced Aria es traducible a otros idiomas, y quedaría así: title=(u"Enhanced Aria settings")
El método makeSettings sería el siguiente. Para no hacer muy pesada la lectura, se pondrá sólo una parte:
 def makeSettings(self, sizer):
  #TRANSLATORS: report banners checkbox
  self.bannerenabled=wx.CheckBox(self, wx.NewId(), label=
(u"Report banners"))
  self.bannerenabled.SetValue(config.conf['aria']['reportBanner'])
  sizer.Add(self.bannerenabled,border=10,flag=wx.BOTTOM)
  #TRANSLATORS: report main content checkbox
  self.mainenabled=wx.CheckBox(self, wx.NewId(), label=(u"Report main content"))
  self.mainenabled.SetValue(config.conf['aria']['reportMain'])
  sizer.Add(self.mainenabled,border=10,flag=wx.BOTTOM)
#TRANSLATORS: report search forms checkbox
  self.searchenabled=wx.CheckBox(self, wx.NewId(), label=
(u"Report search forms"))
  self.searchenabled.SetValue(config.conf['aria']['reportSearch'])
  sizer.Add(self.searchenabled,border=10,flag=wx.BOTTOM)
...

Como se puede ver, no sólo creamos, etiquetamos y añadimos casillas de verificación, sino que establecemos su valor basándonos en la configuración actual. Una vez creadas, postInit hace lo siguiente:
 def postInit(self):
  self.bannerenabled.SetFocus()

Nuestro diálogo ya está listo. Como se puede intuir, no se ha redefinido el método onCancel, que simplemente descarta todo y no tiene que hacer nada más. Sin embargo, el método onOk sí tiene trabajo.
def onOk(self, evt):
  config.conf['aria']['reportBanner']=self.bannerenabled.GetValue()
  config.conf['aria']['reportMain']=self.mainenabled.GetValue()
  config.conf['aria']['reportSearch']=self.searchenabled.GetValue()
  config.conf['aria']['reportForm']=self.formenabled.GetValue()
  ...
  applyConfig()
  super(enhancedAriaSettings, self).onOk(evt) # Importante, llamada al padre!

Y ahora, ¿qué hacemos para poder llegar a este diálogo?
Como bien se ha dicho antes, la magia no existe. En el método init de la clase GlobalPlugin, hay que crear un elemento de menú y asociarlo al submenú preferencias de NVDA.
  self.prefsMenu = gui.mainFrame.sysTrayIcon.menu.GetMenuItems()[0]
  #TRANSLATORS: The configuration option in NVDA Preferences menu
  self.enhancedAriaSettingsItem = self.prefsMenu.Append(wx.ID_ANY, _(u"Enhanced aria settings..."), _(u"Change enhanced Aria settings"))
  gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, self.onEnhancedAriaMenu, self.enhancedAriaSettingsItem) # Asociamos abrir el menú a activar el diálogo

No debemos olvidarnos de eliminar el elemento de menú en el método terminate, de lo contrario aparecerá duplicado al recargar las extensiones: self.prefsMenu.RemoveItem(self.enhancedAriaSettingsItem)
Para activar el diálogo, hacemos algo como esto: gui.mainFrame._popupSettingsDialog(enhancedAriaSettings)
Esta es la clase que contiene nuestro diálogo, enhancedAriaSettings. Pero lo hará por poco tiempo, ¡es hora de dar el salto al diálogo de categorías!

El panel de configuración en el diálogo de categorías

Para añadir paneles de configuración al diálogo de opciones, simplemente debemos crear una clase que herede de gui.settingsDialogs.SettingsPanel, y añadir nuestro panel al diálogo de opciones de NVDA, que está definido como variable global en el módulo gui. Esta clase nos ofrece los siguientes métodos y propiedades:

  • title: el título del panel de configuración.
  • makeSettings(self, sizer): al igual que antes, se nos pasa un sizer que rellenaremos con controles.
  • onSave(self): código que se ejecuta al pulsar los botones aceptar o aplicar del diálogo. Ya no es necesario llamar al método padre, como sí pasaba en onOk.
  • onPanelActivated(self): código que se ejecuta cuando se selecciona este panel. Aquí sí se debería llamar al método padre. Sin embargo, no deberíamos mover el foco como se hacía en postInit.
  • onPanelDeactivated(self): código que se ejecuta al abandonar el panel. Se debe llamar al método padre si lo redefinimos.
  • onDiscard(self): método que se llama al salir del diálogo de opciones sin guardar los cambios.

Una vez definido nuestro panel, debemos agregarlo al diálogo de opciones de NVDA. Por ejemplo, en el método init de la clase GlobalPlugin: NVDASettingsDialog.categoryClasses.append(enhancedAriaPanel)
Y por supuesto, eliminarlo en el método terminate, de lo contrario nos arriesgamos a que se duplique: NVDASettingsDialog.categoryClasses.remove(enhancedAriaPanel)
El código queda más simple, ¿verdad? Es muy sencillo hacer un complemento con preferencias que se adapte a NVDA 2018.2. Y como a mí no me gusta lo fácil, vamos a complicarlo un poco: vamos a añadir compatibilidad entre versiones. Puede haber gente que no quiera actualizar NVDA, y no debemos olvidarnos de ellos.

Soporte para todas las versiones de NVDA posibles

Llegados a este punto, podríamos tener dos clases: una con el diálogo y otra con el panel. Podríamos añadir el panel al diálogo de opciones y crear un elemento de menú en el submenú preferencias, y no pasaría nada. Como ya se ha dicho, NVDA nos da flexibilidad. ¿Permitiría esto que nuestro complemento adaptado funcionase con versiones antiguas? La respuesta ya te la puedes imaginar, si fuera afirmativa no existiría este apartado en el tutorial.
Por un lado, tal y como está, nuestro complemento muere estrepitosamente en NVDA 2018.1.1, diciendo que hay módulos que no encuentra. Por otro, queremos que el elemento de menú aparezca en versiones antiguas, y el panel del diálogo de opciones en las nuevas. Para lo último, en los métodos init y terminate de GlobalPlugin, podemos hacer algo como esto.
Método init:
  if hasattr(settingsDialogs, 'SettingsPanel'): # Es el nuevo NVDA
   NVDASettingsDialog.categoryClasses.append(enhancedAriaPanel)
  else:
   self.prefsMenu = gui.mainFrame.sysTrayIcon.menu.GetMenuItems()[0].GetSubMenu()
   #TRANSLATORS: The configuration option in NVDA Preferences menu
   self.enhancedAriaSettingsItem = self.prefsMenu.Append(wx.ID_ANY, _(u"Enhanced aria settings..."), _(u"Change enhanced Aria settings"))
   gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, self.onEnhancedAriaMenu, self.enhancedAriaSettingsItem)

Método terminate:
   if hasattr(settingsDialogs, 'SettingsPanel'):
    NVDASettingsDialog.categoryClasses.remove(enhancedAriaPanel)
 else: # Es el antiguo
    self.prefsMenu.RemoveItem(self.enhancedAriaSettingsItem)

Como se puede comprobar, miramos si existen atributos que sólo podrían existir en NVDA 2018.2.
De cara a la importación de módulos, podríamos hacer algo como esto:
import gui
from gui import settingsDialogs
try:
 from gui import NVDASettingsDialog
 from gui.settingsDialogs import SettingsPanel
except:
 pass # No hacer nada si falla

El planteamiento está muy bien. Si falla al importar las clases es porque no existen, ya que estamos en un NVDA antiguo. Por lo tanto, nos olvidamos del panel y usamos el elemento de menú y el diálogo clásico. ¿Todos estamos deacuerdo? Sí, excepto el intérprete Python.
Cuando Python lea nuestro archivo de complemento, verá que intentamos definir la clase del panel, y que indicamos un padre que no existe porque no lo hemos importado. Por suerte, Python es tan flexible como NVDA: cualquier variable se puede asignar a cualquier cosa, sin importar el tipo e incluso sin que importe que sea una clase o función. Lo único que nos pide es algo de lo que pueda heredar el panel, así que vamos a darle el objeto base del lenguaje: object. En la cláusula except, en vez de poner pass para que no haga nada, hacemos: SettingsPanel=object

Optimización de código

Es tentador copiar y pegar código de unos métodos a otros. En el caso de EnhancedAria, siempre define las mismas casillas, y siempre guarda la misma configuración. Sin embargo, no es una buena práctica, ya que si tenemos un fallo este también se duplica, y hay que corregirlo tantas veces como se haya hecho el copia-pega. Por lo tanto, se ha sacado el código repetido y se ha metido en funciones globales del módulo:

  • addonSettingsTitle: título del diálogo y del panel. Es el mismo en ambos casos. Si lo dejamos duplicado, un traductor tendría que modificarlo dos veces.
  • createSettings(obj, sizer): obj es una referencia al objeto que llama a la función. Es como el self que vimos antes. Esta función crea las casillas.
  • storeSettings(obj): almacena los ajustes al pulsar el botón aceptar.

Haciendo estos cambios, el tamaño de las clases se reduce. Así quedaría el método onSave:
 def onSave(self):
  storeSettings(self)

Conclusión

Existen muchas formas de adaptar nuestros complementos para que aprovechen las nuevas características introducidas en NVDA 2018.2. Podemos modificarlos, o podemos dejarlos como están. Sin embargo, para proporcionar una experiencia de usuario consistente, se recomienda lo primero más que lo segundo. En este tutorial se ha visto sólo una de las muchísimas alternativas existentes. Tanto Python como NVDA son flexibles, permitiendo que cada desarrollador haga las cosas a su manera y optimice el código como le parezca oportuno. Por ejemplo, la simplificación de código vista anteriormente podría haberse hecho definiendo una clase y aplicando herencia múltiple, si bien es cierto que este enfoque podría complicar un poco las cosas. Espero que hayáis disfrutado leyendo este tutorial tanto como yo al escribirlo, y que os sirva para poner vuestros complementos al día. Para cualquier pregunta o sugerencia, no dudéis en dejarnos un comentario debajo.
¡Hasta la próxima!

El complemento Emoticons se actualiza a la versión 6.4. En esta nueva versión se incluyen traducciones actualizadas, y un cambio en una línea de código que lo hará compatible con NVDA 2018.2. Si tienes pensado actualizar tu copia de NVDA cuando llegue el momento, cosa que desde esta web te recomendamos, es importante que instales la nueva versión de este complemento.
Más información y descarga de Emoticons
Muchos complementos se están actualizando estos días para funcionar con NVDA 2018.2 y utilizar el nuevo diálogo multicategoría. Te recomendamos que estés atento para instalarlos, nosotros intentaremos informarte lo antes posible cada vez que alguno se actualice.

El complemento Focus Highlight, que ayuda a educadores y personas con discapacidad visual leve o moderada a saber dónde están los cursores de NVDA dibujando rectángulos en pantalla, se actualiza a la versión 5.0. Entre sus novedades destacan el uso de la tecnología GDI Plus para dibujar, el soporte para varios monitores y un cambio en los indicadores del foco y el navegador de objetos.
Más información y descarga de Focus Highlight
Como siempre, te recomendamos que mantengas tus complementos actualizados para beneficiarte de las últimas mejoras en seguridad, estabilidad y funcionamiento en general.
Si te gusta la información que te ofrecemos sobre NVDA, plantéate hacer una donación para contribuir al mantenimiento de esta web. ¡Te lo agradeceremos!

El complemento Place Markers, creado por Noelia Ruiz y Chris Leo, se actualiza a la versión 9.0. Esta versión incluye traducciones actualizadas, mejoras en la documentación y la ayuda, y dos nuevas características solicitadas por un usuario: la posibilidad de borrar marcas desde el diálogo que se abre al pulsar NVDA+alt+k, y la de crear y desplazarse a una marca temporal para cada documento. Para guardar o desplazarse a marcas temporales es necesario asignar gestos, por ejemplo una combinación de teclas, en el diálogo Gestos de entrada. Por defecto vienen sin asignar.
Como siempre, te recordamos que es muy importante mantener actualizados tus complementos para que disfrutes de una experiencia de usuario óptima con NVDA. Si quieres más información sobre el diálogo de gestos de entrada, puedes consultar la guía de usuario.

Este complemento permite obtener información según el texto
seleccionado. Simplemente selecciona algo y usa un atajo de teclado para
obtener información. Con suerte, se debería presentar algo que encaje con el
contexto.

Nota: este paquete se distribuye bajo los términos de la GNU General Public
License, versión 2 o posterior. Por favor, consulta el archivo copying.txt
para más detalles.

Atajos de teclado

Nota: estos atajos de teclado asumen que usas la distribución de teclado en
inglés, y podrían no funcionar en otros casos. Si hay un problema, intenta
cambiarlos primero en el diálogo de gestos de entrada.

  • NVDA+; (punto y coma): proporciona información basada en el texto
    seleccionado
  • NVDA+shift+; (punto y coma): proporciona información basada en el
    contenido del portapapeles
  • NVDA+ctrl+; (punto y coma): verbaliza la última información que se
    recibió. Pulsa este atajo dos veces para mostrarla en un diálogo.

Servicios soportados

Actualmente, se soportan las siguientes funciones:

  • Información de una dirección ip usando la API de IPInfoDB. Se proporciona
    una clave de API. Sin embargo, no se puede garantizar que vaya a funcionar
    siempre. Puedes generar la tuya propia, e introducirla en la parte
    superior de init.py, reemplazando la antigua.
  • Definiciones de diccionario en inglés de la Princeton Wordnetweb. Nota:
    estas definiciones no son las mejores, y la base de datos carece de
    definiciones para palabras simples, como could, you, etc.
  • Búsqueda de ISBN mediante la API de libros de Google
  • Verificación del tipo de tarjeta de crédito

Nota: se emplean expresiones regulares para verificar los datos. Hay algunas
que en este momento no se usan, como las de correos electrónicos o números
de teléfono. Esto podría cambiar en el futuro.

Cómo contribuir

Las contribuciones son muy bienvenidas. Puedes enviar una solicitud de
cambios, o contactar con el autor mediante las siguientes vías:

Twitter: @cartertemm

Correo electrónico: [email protected]

El complemento Clip Contents Designer, que permite copiar texto al portapapeles sin eliminar el que ya se haya copiado previamente, se actualiza a la versión 7.1 con traducciones mejoradas. Su autora también ha liberado una versión de desarrollo, la 8.0-dev, que añade compatibilidad con el nuevo diálogo multicategoría de preferencias presente en las versiones de desarrollo de NVDA. La versión 8.0-dev de este complemento no es compatible con NVDA 2018.1 o 2018.1.1 y versiones anteriores, y fallará al intentar instalarla en estas versiones.
Como siempre, te recordamos la importancia de mantener tus complementos al día. Al actualizarlos, garantizas que tu copia de NVDA es segura y estable.

Se acerca el mes de mayo, y con él se actualizan dos de los complementos de Joseph Lee.
El primero es Windows 10 App Essentials. El principal cambio que trae esta versión es la posibilidad de verbalizar el escritorio virtual en el que nos encontramos, bien sea al abrirlo (ctrl+win+d), al cerrarlo (ctrl+win+f4) o al cambiar de un escritorio a otro (ctrl+win+flechas izquierda y derecha). Si esta nueva función no presenta errores, se intentará integrar en el núcleo de NVDA para la versión 2018.3.
El segundo es StationPlaylist Studio, que tampoco deja de sorprendernos con nuevas funciones y características. Esta versión introduce las transcripciones de lista de reproducción, una función que nos permite tomar una instantánea de la lista de reproducción actual y visualizarla en varios formatos. Eventualmente, esta función te permitirá copiar la información al portapapeles o guardarla en archivos. Además, la versión 18.05 también da la posibilidad de tomar una instantánea sólo con parte de la lista de reproducción.
Te recordamos, como siempre, la importancia de mantener tus complementos actualizados. En este caso no te costará mucho, ya que llevan incorporado un mecanismo de actualización automática.
Si te gusta la información que te ofrecemos en nuestra web, plantéate hacer una donación. ¡Te lo agradeceremos!