46
46
def readObjects(obj):
47
47
_startGenerator(readObjectsHelper_generator(obj))
49
def generateObjectSubtreeSpeech(obj,indexGen):
51
speech.speakObject(obj,reason=speech.REASON_SAYALL,index=index)
53
child=obj.simpleFirstChild
55
childSpeech=generateObjectSubtreeSpeech(child,indexGen)
58
child=child.simpleNext
49
60
def readObjectsHelper_generator(obj):
63
speechGen=generateObjectSubtreeSpeech(obj,itertools.count())
57
67
while keepUpdating:
68
# lastReceivedIndex might be None if other speech was interspersed with this say all.
69
# In this case, we want to send more text in case this was the last chunk spoken.
70
if lastReceivedIndex is None or (lastSentIndex-lastReceivedIndex)<=1:
73
o,lastSentIndex=speechGen.next()
77
objIndexMap[lastSentIndex]=o
78
receivedIndex=speech.getLastSpeechIndex()
79
if receivedIndex!=lastReceivedIndex and (lastReceivedIndex!=0 or receivedIndex!=None):
80
lastReceivedIndex=receivedIndex
81
lastReceivedObj=objIndexMap.get(lastReceivedIndex)
82
if lastReceivedObj is not None:
83
api.setNavigatorObject(lastReceivedObj)
84
#Clear old objects from the map
85
for i in objIndexMap.keys():
86
if i<=lastReceivedIndex:
58
88
while speech.isPaused:
62
speech.speakObject(obj,index=indexCount,reason=speech.REASON_SAYALL)
65
obj=obj.getNextInFlow(up=up,down=down)
70
levelsIndexMap[indexCount]=(len(up),len(down))
71
spokenIndex=speech.getLastSpeechIndex()
72
if spokenIndex is None:
74
for count in range(spokenIndex-lastSpokenIndex):
75
upLen,downLen=levelsIndexMap.get(lastSpokenIndex+count+1,(0,0))
76
if upLen==0 and downLen==0:
79
for count in range(upLen+1):
80
tones.beep(880*(1.25**count),50)
83
for count in range(downLen+1):
84
tones.beep(880/(1.25**count),50)
86
updateObj=updateObj.nextInFlow
87
api.setNavigatorObject(updateObj)
88
if not keepReading and spokenIndex>=endIndex:
90
lastSpokenIndex=spokenIndex
93
92
def readText(info,cursor):
94
93
_startGenerator(readTextHelper_generator(info,cursor))
96
95
def readTextHelper_generator(info,cursor):
100
# The object died, so we should too.
100
102
reader=info.copy()
101
103
if not reader.isCollapsed:
102
104
reader.collapse()
104
106
keepUpdating=True
106
107
while keepUpdating:
107
# receiveCount might be None if other speech was interspersed with this say all.
109
# The object died, so we should too.
111
# lastReceivedIndex might be None if other speech was interspersed with this say all.
108
112
# In this case, we want to send more text in case this was the last chunk spoken.
109
if receiveCount is None or (sendCount-receiveCount)<=10:
113
if lastReceivedIndex is None or (lastSentIndex-lastReceivedIndex)<=10:
111
115
bookmark=reader.bookmark
116
index=lastSentIndex+1
113
117
delta=reader.move(textInfos.UNIT_READINGCHUNK,1,endPoint="end")
119
speech.speakWithoutPauses(None)
115
120
keepReading=False
117
speech.speakTextInfo(reader,reason=speech.REASON_SAYALL,index=index)
122
speech.speakTextInfo(reader,unit=textInfos.UNIT_READINGCHUNK,reason=speech.REASON_SAYALL,index=index)
119
124
cursorIndexMap[index]=bookmark
120
reader.collapse(end=True)
121
spokenIndex=speech.getLastSpeechIndex()
122
if spokenIndex!=oldSpokenIndex:
123
oldSpokenIndex=spokenIndex
124
receiveCount=spokenIndex
125
bookmark=cursorIndexMap.get(spokenIndex,None)
126
reader.collapse(end=True)
127
except RuntimeError: #MS Word when range covers end of document
128
speech.speakWithoutPauses(None)
131
# We'll wait for speech to catch up a bit before sending more text.
132
if speech.speakWithoutPauses.lastSentIndex is None or (lastSentIndex-speech.speakWithoutPauses.lastSentIndex)>=10: # There is a
133
# There is a large chunk of pending speech
134
# Force speakWithoutPauses to send text to the synth so we can move on.
135
speech.speakWithoutPauses(None)
136
receivedIndex=speech.getLastSpeechIndex()
137
if receivedIndex!=lastReceivedIndex and (lastReceivedIndex!=0 or receivedIndex!=None):
138
lastReceivedIndex=receivedIndex
139
bookmark=cursorIndexMap.get(receivedIndex,None)
126
140
if bookmark is not None:
127
141
updater=reader.obj.makeTextInfo(bookmark)
128
142
if cursor==CURSOR_CARET: