vlibras.py
8.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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)