From bef43435fa3d88ea2e9c7d7669667a186a292e8b Mon Sep 17 00:00:00 2001 From: André Araújo Date: Tue, 24 Jan 2017 15:20:56 -0300 Subject: [PATCH] Primeira versão do plugin --- vlibras.nvda-addon/.gitignore | 12 ++++++++++++ vlibras.nvda-addon/bin/7z.dll | Bin 0 -> 1073664 bytes vlibras.nvda-addon/bin/7z.exe | Bin 0 -> 265216 bytes vlibras.nvda-addon/doc/pt_BR/readme.html | 23 +++++++++++++++++++++++ vlibras.nvda-addon/doc/pt_BR/readme.md | 12 ++++++++++++ vlibras.nvda-addon/doc/style.css | 46 ++++++++++++++++++++++++++++++++++++++++++++++ vlibras.nvda-addon/globalPlugins/vlibras.py | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vlibras.nvda-addon/make.cmd | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vlibras.nvda-addon/manifest.ini | 7 +++++++ vlibras.nvda-addon/server/server.cmd | 4 ++++ vlibras.nvda-addon/server/server.py | 25 +++++++++++++++++++++++++ 11 files changed, 483 insertions(+), 0 deletions(-) create mode 100644 vlibras.nvda-addon/.gitignore create mode 100644 vlibras.nvda-addon/bin/7z.dll create mode 100644 vlibras.nvda-addon/bin/7z.exe create mode 100644 vlibras.nvda-addon/doc/pt_BR/readme.html create mode 100644 vlibras.nvda-addon/doc/pt_BR/readme.md create mode 100644 vlibras.nvda-addon/doc/style.css create mode 100644 vlibras.nvda-addon/globalPlugins/vlibras.py create mode 100644 vlibras.nvda-addon/make.cmd create mode 100644 vlibras.nvda-addon/manifest.ini create mode 100644 vlibras.nvda-addon/server/server.cmd create mode 100644 vlibras.nvda-addon/server/server.py diff --git a/vlibras.nvda-addon/.gitignore b/vlibras.nvda-addon/.gitignore new file mode 100644 index 0000000..de0ca35 --- /dev/null +++ b/vlibras.nvda-addon/.gitignore @@ -0,0 +1,12 @@ +.* +!*.gitignore +*~ +*.autosave +*.gz +*.log +*.nvda-addon +*.pyc +*.swp +*.txt +*.zip +build/ diff --git a/vlibras.nvda-addon/bin/7z.dll b/vlibras.nvda-addon/bin/7z.dll new file mode 100644 index 0000000..11ce2f1 Binary files /dev/null and b/vlibras.nvda-addon/bin/7z.dll differ diff --git a/vlibras.nvda-addon/bin/7z.exe b/vlibras.nvda-addon/bin/7z.exe new file mode 100644 index 0000000..bc774bb Binary files /dev/null and b/vlibras.nvda-addon/bin/7z.exe differ diff --git a/vlibras.nvda-addon/doc/pt_BR/readme.html b/vlibras.nvda-addon/doc/pt_BR/readme.html new file mode 100644 index 0000000..1ac4573 --- /dev/null +++ b/vlibras.nvda-addon/doc/pt_BR/readme.html @@ -0,0 +1,23 @@ + + + + + + + + + +

VLibras Pugin para NVDA

+ +

+ Este plug-in redireciona o texto de saída do NVDA para a aplicação VLibras Player. +

+

Versão 1.0

+
    +
  1. Primeira versão pública
  2. +
+ + diff --git a/vlibras.nvda-addon/doc/pt_BR/readme.md b/vlibras.nvda-addon/doc/pt_BR/readme.md new file mode 100644 index 0000000..abdf5b7 --- /dev/null +++ b/vlibras.nvda-addon/doc/pt_BR/readme.md @@ -0,0 +1,12 @@ +# VLibras # + +* Autor: Lavid +* Baixe a [versão estável][1] + +Este plug-in redireciona o texto de saída do NVDA para a aplicação VLibras Player. + +## Versão 1.0 ## + +* Primeira versão pública + +[1]: http://www.vlibras.gov.br/ diff --git a/vlibras.nvda-addon/doc/style.css b/vlibras.nvda-addon/doc/style.css new file mode 100644 index 0000000..247ce09 --- /dev/null +++ b/vlibras.nvda-addon/doc/style.css @@ -0,0 +1,46 @@ +@charset "utf-8"; +body { + font-family : Verdana, Arial, Helvetica, Sans-serif; + color : #FFFFFF; + background-color : #000000; + line-height: 1.2em; +} + +h1, h2 { + text-align: center +} + +dt { + font-weight : bold; + float : left; + width: 10%; + clear: left +} + +dd { + margin : 0 0 0.4em 0; + float : left; + width: 90%; + display: block; +} + +p { + clear : both; +} + +a { + text-decoration : underline; +} + +:active { + text-decoration : none; +} + +a:focus, a:hover { + outline: solid +} + +:link { + color: #0000FF; + background-color: #FFFFFF +} diff --git a/vlibras.nvda-addon/globalPlugins/vlibras.py b/vlibras.nvda-addon/globalPlugins/vlibras.py new file mode 100644 index 0000000..c3ed428 --- /dev/null +++ b/vlibras.nvda-addon/globalPlugins/vlibras.py @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- + +# NVDA imports +import api +import globalPluginHandler +import logHandler +import speech +import textInfos +import ui +import controlTypes + +# python imports +import select +import socket +import threading +import time + + +class Cli2Srvnt(threading.Thread): + + def __init__(self, host, port, timeout=1): + threading.Thread.__init__(self) + self.__connected = False + self.__sock = None + self.__host = host + self.__port = port + self.__timeout = timeout + self.__addr = (self.__host, self.__port) + + def __create(self): + self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + def run(self): + exceptional = [] + readable = [] + writable = [] + self.__create() + while True: + try: + if (readable == [] and writable == [] and exceptional == []): + if (self.__sock.connect_ex((self.__host, self.__port)) == 0): + # ui.message("VLibras Plugin CONECTADO") + self.__connected = True + try: + readable, writable, exceptional = select.select( + [self.__sock], [self.__sock], [], self.__timeout + ) + except: + pass + if (readable != []): + self.__connected = False + try: + self.__sock.shutdown(1) + self.__sock.close() + self.__create() + except: + pass + elif (writable != []): + self.__connected = True + except: + pass + time.sleep(1) + + def send(self, msg): + try: + if (self.__connected and self.__sock is not None): + return self.__sock.sendto( + msg.encode("utf-8", "ignore"), + self.__addr + ) + except Exception as e: + logHandler.log.error(u"%s\n%s" % (e.message, e.args)) + return False + + +class GlobalPlugin(globalPluginHandler.GlobalPlugin): + + __captureMouse = False + __silentMode = False + + # keyboard shortcuts + __kbToggleSilentMode = "NVDA+shift+v" + __kbToggleCaptureMouseMode = "NVDA+shift+m" + + # keyboard gestures + __gestures = { + "kb:" + __kbToggleSilentMode: "toggleSilentMode", + "kb:" + __kbToggleCaptureMouseMode: "toggleCaptureMouseMode" + } + + # message to speak on enable or disable + def toggleMessage(self, msg, enabled, kb): + message = "VLibras Plugin: %s %s. Para %s use %s" + if (enabled): + message = message % (msg, "ativado", "desativar", kb) + else: + message = message % (msg, "desativado", "ativar", kb) + return ui.message(message) + + # toggle silent mode by user (default is False) + def script_toggleSilentMode(self, obj): + self.__silentMode = not self.__silentMode + return self.toggleMessage( + "Modo silencioso", + self.__silentMode, + self.__kbToggleSilentMode + ) + + # toggle capture mouse mode by user (default is False) + def script_toggleCaptureMouseMode(self, obj): + self.__captureMouse = not self.__captureMouse + return self.toggleMessage( + "Modo captura de mouse", + self.__captureMouse, + self.__kbToggleCaptureMouseMode + ) + + # constructor + def __init__(self): + super(self.__class__, self).__init__() + self.__lastTextSend = "" + self.__mutex = threading.Lock() + self.__client = Cli2Srvnt("127.0.0.1", 10001) + self.__client.start() + + # destructor + def __exit__(self, exc_type, exc_value, traceback): + self.__client.join() + + # cancel speech if silent mode is true + def handleSpeech(self, obj, nextHandler): + try: + if (self.__silentMode): + return speech.cancelSpeech() + except Exception as e: + logHandler.log.error(u"%s\n%s" % (e.message, e.args)) + return nextHandler() + + # get the current text in focus and send to vlibras + def processFocus(self, obj, nextHandler): + try: + if (obj.role == controlTypes.ROLE_UNKNOWN): + return self.handleSpeech(obj, nextHandler) + info = api.getReviewPosition() + if (info is None): + return self.handleSpeech(obj, nextHandler) + info.expand(textInfos.UNIT_READINGCHUNK) + textToSend = info._get_text() + if textToSend is None: + return self.handleSpeech(obj, nextHandler) + textToSend = textToSend.strip(" \t\r\n") + # mutex to protect self.__lastTextSend + self.__mutex.acquire() + try: + if (textToSend and textToSend != self.__lastTextSend): + self.__lastTextSend = textToSend + if (self.__client.send(textToSend)): + logHandler.log.debugWarning(">> %s\n" % (textToSend)) + finally: + self.__mutex.release() + except Exception as e: + logHandler.log.error(u"%s\n%s" % (e.message, e.args)) + return self.handleSpeech(obj, nextHandler) + + # get the current text in mouse focus and send to vlibras + def processMouse(self, obj, nextHandler, x, y): + try: + if (not self.__captureMouse): + return self.handleSpeech(obj, nextHandler) + if (obj.role == controlTypes.ROLE_UNKNOWN): + return self.handleSpeech(obj, nextHandler) + info = api.getReviewPosition() + if (info is None): + return self.handleSpeech(obj, nextHandler) + info.expand(info.unit_mouseChunk) + textToSend = info._get_text() + if textToSend is None: + return self.handleSpeech(obj, nextHandler) + textToSend = textToSend.strip(" \t\r\n") + # mutex to protect self.__lastTextSend + self.__mutex.acquire() + try: + if (textToSend and textToSend != self.__lastTextSend): + self.__lastTextSend = textToSend + if (self.__client.send(textToSend)): + logHandler.log.debugWarning(">> %s\n" % (textToSend)) + finally: + self.__mutex.release() + except Exception as e: + logHandler.log.error(u"%s\n%s" % (e.message, e.args)) + return self.handleSpeech(obj, nextHandler) + + # Override + def event_typedCharacter(self, obj, nextHandler, ch): + return self.handleSpeech(obj, nextHandler) + + # Override -> processMouse + def event_mouseMove(self, obj, nextHandler, x, y): + return self.processMouse(obj, nextHandler, x, y) + + # Override + def event_stateChange(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_focusEntered(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override -> processFocus + def event_gainFocus(self, obj, nextHandler): + return self.processFocus(obj, nextHandler) + + # Override + def event_foreground(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_becomeNavigatorObject(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_valueChange(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_nameChange(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_descriptionChange(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_caret(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_loseFocus(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) + + # Override + def event_locationChange(self, obj, nextHandler): + return self.handleSpeech(obj, nextHandler) diff --git a/vlibras.nvda-addon/make.cmd b/vlibras.nvda-addon/make.cmd new file mode 100644 index 0000000..773f02f --- /dev/null +++ b/vlibras.nvda-addon/make.cmd @@ -0,0 +1,110 @@ +@ECHO OFF + +CD /D "%~dp0" + +SET "VLIBRAS_ADDON_DIR=%APPDATA%\nvda\addons\vlibras" +SET "VLIBRAS_ADDON_NAME=vlibras.nvda-addon" + +:MAIN + SETLOCAL ENABLEDELAYEDEXPANSION + SET "TARGETS=BUILD HELP INSTALL KILL OPEN RUN UNINSTALL UPDATE" + SET /A "ARGC=0" + FOR %%A IN (%*) DO ( + SET /A "ARGC+=1" + SET "ARGVALID=FALSE" + IF /I "%%A" EQU "--help" (CALL :HELP & GOTO :END) + IF /I "%%A" EQU "-help" (CALL :HELP & GOTO :END) + IF /I "%%A" EQU "/help" (CALL :HELP & GOTO :END) + FOR %%B IN (%TARGETS%) DO ( + IF /I "%%A" == "%%B" ( + SET "ARGVALID=TRUE" + CALL :%%A + ) + ) + IF /I "!ARGVALID!" EQU "FALSE" ( + ECHO.Argument !ARGC! is not valid: %%A + ECHO.For help type: %~nn0 HELP + ECHO.Targets: %TARGETS% + GOTO :END + ) + ) + IF %ARGC% LSS 1 (CALL :BUILD) +:END + ENDLOCAL +EXIT /B + +:HELP + ECHO. + ECHO. Usage: Makefile ^ + ECHO. + ECHO. Options Description + ECHO. build build plugin %VLIBRAS_ADDON_NAME% + ECHO. help show this help + ECHO. install install %VLIBRAS_ADDON_NAME% + ECHO. kill kill all nvda process + ECHO. open open nvda appdata directory + ECHO. run start nvda + ECHO. uninstall remove %VLIBRAS_ADDON_NAME% + ECHO. update reinstall %VLIBRAS_ADDON_NAME% and restart NVDA + ECHO. +GOTO :EOF + +:BUILD + SET "PATH=%CD%\bin;%PATH%" + SET "FILE=%FILE% manifest.ini" + SET "FOLDER=%FOLDER% doc\*" + REM SET "FOLDER=%FOLDER% appModules\*" + SET "FOLDER=%FOLDER% globalPlugins\*" + 2>NUL DEL "%VLIBRAS_ADDON_NAME%" + 7z a -aoa -tzip "%VLIBRAS_ADDON_NAME%" %FILE% %FOLDER% -r -mx9 -mmt +GOTO :EOF + +:INSTALL + XCOPY /V /I /S /Q /Y ".\doc" "%VLIBRAS_ADDON_DIR%\doc" + REM XCOPY /V /I /S /Q /Y ".\appModules" "%VLIBRAS_ADDON_DIR%\appModules" + XCOPY /V /I /S /Q /Y ".\globalPlugins" "%VLIBRAS_ADDON_DIR%\globalPlugins" + XCOPY /V /I /Q /Y ".\manifest.ini" "%VLIBRAS_ADDON_DIR%" +GOTO :EOF + +:KILL + TASKKILL /F /IM nvda.exe + TASKKILL /F /IM nvda_eoaProxy.exe + TASKKILL /F /IM nvda_noUIAccess.exe + TASKKILL /F /IM nvda_service.exe + TASKKILL /F /IM nvda_slave.exe +GOTO :EOF + +:OPEN + IF EXIST "%VLIBRAS_ADDON_DIR%" ( + START "" EXPLORER "%VLIBRAS_ADDON_DIR%" + ) ELSE ( + ECHO.NVDA is not installed! + ) +GOTO :EOF + +:RUN + SET "NVDA_EXE=NVDA\nvda_slave.exe" + SET "NVDA_X86=%PROGRAMFILES%\%NVDA_EXE%" + SET "NVDA_X64=%PROGRAMFILES(x86)%\%NVDA_EXE%" + IF EXIST "%NVDA_X86%" ( + START "" "%NVDA_X86%" launchNVDA -r + ) ELSE IF EXIST "%NVDA_X64%" ( + START "" "%NVDA_X64%" launchNVDA -r + ) ELSE ( + ECHO.NVDA is not installed! + ) +GOTO :EOF + +:UNINSTALL + IF EXIST "%VLIBRAS_ADDON_DIR%" ( + RMDIR /S /Q "%VLIBRAS_ADDON_DIR%" + ) ELSE ( + ECHO.%VLIBRAS_ADDON_NAME% is not installed! + ) +GOTO :EOF + +:UPDATE + CALL :KILL + CALL :INSTALL + CALL :RUN +GOTO :EOF diff --git a/vlibras.nvda-addon/manifest.ini b/vlibras.nvda-addon/manifest.ini new file mode 100644 index 0000000..c0bb1df --- /dev/null +++ b/vlibras.nvda-addon/manifest.ini @@ -0,0 +1,7 @@ +name = "vlibras" +summary = "VLibras Plugin" +version = 1.0 23.01.2017 +description = """Comunicate with vlibras player.""" +author = "Laboratório de Aplicações de Vídeo Digital - Lavid" +url = http://lavid.ufpb.br +docFileName = readme.html diff --git a/vlibras.nvda-addon/server/server.cmd b/vlibras.nvda-addon/server/server.cmd new file mode 100644 index 0000000..469abc3 --- /dev/null +++ b/vlibras.nvda-addon/server/server.cmd @@ -0,0 +1,4 @@ +@ECHO OFF +CD /D "%~dp0" +COLOR 9F +python server.py diff --git a/vlibras.nvda-addon/server/server.py b/vlibras.nvda-addon/server/server.py new file mode 100644 index 0000000..36eb3e0 --- /dev/null +++ b/vlibras.nvda-addon/server/server.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +import socket + +host = "127.0.0.1" +port = 10001 +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.bind((host, port)) +sock.listen(1) + +print("[Esperando Cliente] %s:%d" % (host, port)) +while True: + try: + con, cli = sock.accept() + print("[Cliente Conectado] %s:%s" % (cli)) + while True: + msg = con.recv(1024) + if (msg): + print(msg) + else: + print("[Cliente Desconectado] %s:%s" % (cli)) + break + except: + con.close() -- libgit2 0.21.2