def __init__(self, cursor): self.cursor = cursor self.trigger = SayAllProfileTrigger() self.trigger.enter() # Start at the cursor. if cursor == CURSOR_CARET: try: self.reader = api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError): return else: self.reader = api.getReviewPosition() self.speakTextInfoState = speech.SpeakTextInfoState(self.reader.obj) self.numBufferedLines = 0
def __init__(self, cursor): self.cursor = cursor self.trigger = SayAllProfileTrigger() self.reader = None # Start at the cursor. if cursor == CURSOR_CARET: try: self.reader = api.getCaretObject().makeTextInfo( textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError) as e: raise NotImplementedError("Unable to make TextInfo: " + str(e)) else: self.reader = api.getReviewPosition() # #10899: SayAll profile can't be activated earlier because they may not be anything to read self.trigger.enter() self.speakTextInfoState = speech.SpeakTextInfoState(self.reader.obj) self.numBufferedLines = 0
def readTextHelper_generator(cursor): if cursor == CURSOR_CARET: try: reader = api.getCaretObject().makeTextInfo( textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError): return else: reader = api.getReviewPosition() lastSentIndex = 0 lastReceivedIndex = 0 cursorIndexMap = {} keepReading = True speakTextInfoState = speech.SpeakTextInfoState(reader.obj) start = time.time() with SayAllProfileTrigger(): while True: if not reader.obj: # The object died, so we should too. return # lastReceivedIndex might be None if other speech was interspersed with this say all. # In this case, we want to send more text in case this was the last chunk spoken. if lastReceivedIndex is None or (lastSentIndex - lastReceivedIndex) <= 10: if keepReading: bookmark = reader.bookmark index = lastSentIndex + 1 delta = reader.move(textInfos.UNIT_READINGCHUNK, 1, endPoint="end") if delta <= 0: speech.speakWithoutPauses(None) keepReading = False continue speech.speakTextInfo(reader, unit=textInfos.UNIT_READINGCHUNK, reason=controlTypes.REASON_SAYALL, index=index, useCache=speakTextInfoState) lastSentIndex = index cursorIndexMap[index] = (bookmark, speakTextInfoState.copy()) try: reader.collapse(end=True) except RuntimeError: #MS Word when range covers end of document # Word specific: without this exception to indicate that further collapsing is not posible, say-all could enter an infinite loop. speech.speakWithoutPauses(None) keepReading = False else: # We'll wait for speech to catch up a bit before sending more text. if speech.speakWithoutPauses.lastSentIndex is None or ( lastSentIndex - speech.speakWithoutPauses.lastSentIndex) >= 10: # There is a large chunk of pending speech # Force speakWithoutPauses to send text to the synth so we can move on. speech.speakWithoutPauses(None) receivedIndex = speech.getLastSpeechIndex() if receivedIndex != lastReceivedIndex and ( lastReceivedIndex != 0 or receivedIndex != None): lastReceivedIndex = receivedIndex bookmark, state = cursorIndexMap.get(receivedIndex, (None, None)) if state: state.updateObj() if bookmark is not None: updater = reader.obj.makeTextInfo(bookmark) if cursor == CURSOR_CARET: updater.updateCaret() if cursor != CURSOR_CARET or config.conf["reviewCursor"][ "followCaret"]: api.setReviewPosition(updater, isCaret=cursor == CURSOR_CARET) elif not keepReading and lastReceivedIndex == lastSentIndex: # All text has been sent to the synth. # Turn the page and start again if the object supports it. if isinstance(reader.obj, textInfos.DocumentWithPageTurns): try: reader.obj.turnPage() except RuntimeError: break else: reader = reader.obj.makeTextInfo( textInfos.POSITION_FIRST) keepReading = True else: break while speech.isPaused: yield yield now = time.time() if (now - start) > int(min) * 60 + int(sec): speech.cancelSpeech() break # Wait until the synth has actually finished speaking. # Otherwise, if there is a triggered profile with a different synth, # we will switch too early and truncate speech (even up to several lines). # Send another index and wait for it. index = lastSentIndex + 1 speech.speak([speech.IndexCommand(index)]) while speech.getLastSpeechIndex() < index: yield yield # Some synths say they've handled the index slightly sooner than they actually have, # so wait a bit longer. for i in xrange(30): yield