-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpythonwin_dict.py
More file actions
executable file
·312 lines (278 loc) · 11.1 KB
/
Copy pathpythonwin_dict.py
File metadata and controls
executable file
·312 lines (278 loc) · 11.1 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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
__version__ = "$Revision: 512 $, $Date: 2013-09-04 14:45:28 +0200 (wo, 04 sep 2013) $, $Author: quintijn $"
# Python Macro Language for Dragon NaturallySpeaking
# (c) Copyright 1999 by Joel Gould
# Portions (c) Copyright 1999 by Dragon Systems, Inc.
#
# Pythonwin, trying things with dication grammar, only seems to work when
# exclusively activated.
#
# Use testDialogForDicationGrammar.py (run from pythonwin), to start the window
# which accepts dictation from this grammar
#
# dictated text is inserted in front of text that is already there
#
# written by: Quintijn Hoogenboom (QH software, training & advies), june 2006
#
#
"""
try with title "Title" (from testDialogForDicationGrammar.py) or
"Script" having a new (non saved python script)
"""
import natlink
natut = __import__('natlinkutils')
import win32ui
import nsformat
dictObj = None
debugMode = 1
##wantedTitle = "PythonWin - [Script1]"
wantedTitle = "Title" # belonging to testDialogForDicationGrammar
class VoiceDictation:
dictObj = None
ctrl = None
# Initialization. Create a DictObj instance and activate it for the
# dialog box window. All callbacks from the DictObj instance will go
# directly to the dialog box.
def initialize(self, hndle=None):
if self.dictObj != None:
D("dictObj already initialized")
return
self.__class__.dictObj = natlink.DictObj()
Cwnd = win32ui.GetForegroundWindow()
for i in range(15000, 16000):
try:
ctrl = Cwnd.GetDlgItem(i) # edit box
except:
pass
else:
D("got ctrl: %s: %s"% (i, ctrl))
self.__class__.ctrl = ctrl
break
else:
D("could not find a ctrl")
self.__class__.ctrl = None
self.dictObj.setBeginCallback(self.onTextBegin)
self.dictObj.setChangeCallback(self.onTextChange)
self.dictObj.activate(hndle)
## self.dictObj.activate(dlg.GetSafeHwnd())
def onTextBegin(self,moduleInfo):
D('win dict, text begin')
self.updateState()
# We get this callback when something in the dictation object changes
# like text is added or something is selected by voice. We then update
# the edit control to match the dictation object.
def onTextChange(self,delStart,delEnd,newText,selStart,selEnd):
D('win dict, text change:%s, %s, %s, %s, %s'% ( delStart, delEnd, newText, selStart, selEnd))
self.dictObj.setLock(1)
if self.ctrl:
self.ctrl.SetSel(delStart,delEnd)
self.ctrl.ReplaceSel(newText)
self.ctrl.SetSel(selStart,selEnd)
else:
natut.playString(newText)
self.dictObj.setLock(0)
def updateState(self):
if self.ctrl:
D("ctrl")
text = self.ctrl.GetWindowText()
selStart,selEnd = self.ctrl.GetSel()
else:
D("fake text")
text = "aa bb cc dd"
selStart, selEnd = len(text), len(text)
visStart,visEnd = self.getVisibleRegion()
if (visStart, visEnd) == (None, None):
visStart, visEnd = selStart, selEnd
self.dictObj.setLock(1)
self.dictObj.setText(text,0,0x7FFFFFFF)
self.dictObj.setTextSel(selStart,selEnd)
self.dictObj.setVisibleText(visStart,visEnd)
self.dictObj.setLock(0)
D("dictObj set with text: %s"% text)
def getWindowText(self):
if self.ctrl:
return self.ctrl.GetWindowText()
else:
return "aa bb cc"
def getSel(self):
if self.ctrl:
return self.ctrl.GetSel()
else:
return 4, 5
def getVisibleRegion(self):
"""Utility subroutine which calculates the visible region of the edit
control and returns the start and end of the current visible region.
"""
if self.ctrl:
top,bottom,left,right = self.ctrl.GetClientRect()
firstLine = self.ctrl.GetFirstVisibleLine()
visStart = self.ctrl.LineIndex(firstLine)
lineCount = self.ctrl.GetLineCount()
lastLine = lineCount
for line in range(firstLine+1,lineCount):
charInLine = self.ctrl.LineIndex(line)
left,top = self.ctrl.GetCharPos(charInLine)
if top >= bottom:
break
lastLine = line
visEnd = self.ctrl.LineIndex(lastLine+1)
if visEnd == -1:
visEnd = len(self.ctrl.GetWindowText())
return visStart,visEnd
else:
return None, None
# Call this function to cleanup. We have to reset the callback
# functions or the object will not be freed.
def terminate(self):
if self.dictObj:
self.dictObj.deactivate()
self.dictObj.setBeginCallback(None)
self.dictObj.setChangeCallback(None)
self.__class__.dictObj = None
self.__class__.ctrl = None
class CommandGrammar(natut.GrammarBase):
gramSpec = """
<OK> exported = OK | okay;
<scratch> exported = scratch [that];
<clear> exported = clear | start again;
"""
def initialize(self):
print 'initializing/loading CommandGrammar belonging to Python dictatebox'
self.load(self.gramSpec)
self.state = None
self.isActive = 0
self.prevHandle = -1
self.txt = None # becomes the text dialog
# keep same as pythonwin_dict grammar:
self.exclusive = 0 # test with 1 or 0!
self.dictObj = VoiceDictation()
def gotBegin(self,moduleInfo):
winHandle = moduleInfo[2]
if self.prevHandle == winHandle:
return
# terminate dictObj:
self.dictObj.terminate()
self.prevHandle = winHandle
if natut.matchWindow(moduleInfo, 'pythonwin', wantedTitle):
if not self.isActive:
self.dictObj.initialize(hndle=winHandle)
print 'activate (exclusive: %s) Pythonwin command grammar with dictate box, handle: %s'% \
(self.exclusive, winHandle)
self.activateAll(winHandle, exclusive=self.exclusive)
self.isActive = 1
elif self.isActive:
print 'deactivate Pythonwin command grammar with dictate box'
self.dictObj.terminate()
self.deactivateAll()
self.txt = None
self.isActive = 0
def onTextBegin(self, param):
print "ontextbegin: %s"% param
def gotResultsInit(self,words,fullResults):
if not self.txt:
Cwnd = win32ui.GetForegroundWindow()
self.txt=Cwnd.GetDlgItem(15008) # edit box
def gotResults_OK(self, words, fullResults):
print 'heard command: %s '% words
natut.playString("{tab}{enter}")
def gotResults_scratch(self, words, fullResults):
print 'heard command: %s '% words
i,j = self.txt.GetSel()
if i < j:
natut.playString("{backspace}")
def gotResults_clear(self, words, fullResults):
print 'heard command: %s '% words
self.txt.Clear()
##class DictGrammar(natut.DictGramBase):
## def __init__(self):
## natut.DictGramBase.__init__(self)
##
## def initialize(self):
## print 'initializing/loading DictGrammar!!'
## self.load()
## self.state = None
## self.isActive = 0
## self.prevHandle = -1
## self.txt = None # becomes the text dialog
## self.exclusive = 1 # test with 1 or 0!
## self.totalText = ''
## self.dictObj = VoiceDictation()
##
##
## def gotBegin(self,moduleInfo):
## winHandle = moduleInfo[2]
## if self.prevHandle == winHandle:
## if self.dictObj:
## self.onTextBegin()
##
## return
## self.dictObj.terminate()
## self.prevHandle = winHandle
## if natut.matchWindow(moduleInfo, 'pythonwin', wantedTitle):
## if not self.isActive:
## if not self.dictObj:
## self.dictObj.initialize(ctrl=None, hndle=winHandle)
##
## print 'activate (exclusive: %s) Pythonwin dictation grammar, handle: %s'% \
## (self.exclusive, winHandle)
## self.activate(winHandle, exclusive=self.exclusive)
## self.isActive = 1
## elif self.isActive:
## print 'deactivate Pythonwin dictation grammar'
## if self.dictObj:
## self.dictObj.terminate()
## self.deactivate()
## self.txt = None
## self.isActive = 0
##
##
## def gotResults(self, words):
## self.numberOfLinesBelow = 3 # for s&s or printing
## print 'heard dictation: %s '% words
## self.dictObj.setBeginCallback()
#### dir txt: ['Clear', 'Copy', 'CreateWindow', 'Cut', 'FmtLines',
#### 'GetFirstVisibleLine', 'GetLine', 'GetLineCount',
#### 'GetSel', 'LimitText', 'LineFromChar', 'LineIndex',
#### 'LineScroll', 'Paste', 'ReplaceSel', 'SetReadOnly', 'SetSel']
##
#### for funcName in ['GetFirstVisibleLine', 'GetLine', 'GetLineCount',
#### 'LineIndex', 'LineFromChar']:
#### func = getattr(txt, funcName)
#### result = func()
#### print '%s: %s'% (funcName, result)
## self.dictObj.onTextBegin()
##
## actualLine = txt.GetLine()
## actualLineNumber = txt.LineFromChar()
## ## with no selection on, the current line is txt.GetLine(), others are txt.GetLine(index)
## ## the current line number = txt.LineFromChar()
## ## in this example the visible region is shown, until maximum 3 lines below the current line
## print 'current line: %s'% txt.GetLine()
## print 'line index: %s'% txt.LineIndex()
## print 'line fromchar: %s'% txt.LineFromChar()
## print 'GetSel: %s, %s'% txt.GetSel()
## maxLineNum = min(txt.GetLineCount(), actualLineNumber+self.numberOfLinesBelow)
## for line in range(txt.GetFirstVisibleLine(), maxLineNum):
## text = txt.GetLine(line)
## print 'line %s: %s'% (line, text)
##
## actual,self.state = nsformat.formatWords(words,self.state)
## txt.ReplaceSel(actual)
## self.totalText += actual
def D(t):
"""debug text if debugMode is on"""
if debugMode:
print t
# standard stuff Joel (adapted for possible empty gramSpec, QH, unimacro)
dictGrammar = None
##dictGrammar = DictGrammar()
##dictGrammar.initialize()
cmdGrammar = CommandGrammar()
cmdGrammar.initialize()
print 'cmdGrammar initialized'
##print 'dictGrammar initialized'
def unload():
global dictGrammar, thisGrammar
if dictGrammar:
dictGrammar.unload()
if cmdGrammar:
cmdGrammar.unload()