~stomato463/+junk/nvdajp

« back to all changes in this revision

Viewing changes to source/sayAllHandler.py

  • Committer: Masataka Shinke
  • Date: 2011-10-25 12:35:26 UTC
  • mfrom: (4185 jpmain)
  • mto: This revision was merged to the branch mainline in revision 4211.
  • Revision ID: mshinke@users.sourceforge.jp-20111025123526-ze527a2rl3z0g2ky
lp:~nishimotz/nvdajp/main : 4185 をマージ

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
#This file is covered by the GNU General Public License.
5
5
#See the file COPYING for more details.
6
6
 
 
7
import itertools
7
8
import queueHandler
8
9
import config
9
10
import speech
10
11
import textInfos
11
 
import characterSymbols
12
12
import globalVars
13
13
import api
14
14
import tones
46
46
def readObjects(obj):
47
47
        _startGenerator(readObjectsHelper_generator(obj))
48
48
 
 
49
def generateObjectSubtreeSpeech(obj,indexGen):
 
50
        index=indexGen.next()
 
51
        speech.speakObject(obj,reason=speech.REASON_SAYALL,index=index)
 
52
        yield obj,index
 
53
        child=obj.simpleFirstChild
 
54
        while child:
 
55
                childSpeech=generateObjectSubtreeSpeech(child,indexGen)
 
56
                for r in childSpeech:
 
57
                        yield r
 
58
                child=child.simpleNext
 
59
 
49
60
def readObjectsHelper_generator(obj):
50
 
        levelsIndexMap={}
51
 
        updateObj=obj
 
61
        lastSentIndex=0
 
62
        lastReceivedIndex=0
 
63
        speechGen=generateObjectSubtreeSpeech(obj,itertools.count())
 
64
        objIndexMap={}
52
65
        keepReading=True
53
66
        keepUpdating=True
54
 
        indexCount=0
55
 
        lastSpokenIndex=0
56
 
        endIndex=0
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:
 
71
                        if keepReading:
 
72
                                try:
 
73
                                        o,lastSentIndex=speechGen.next()
 
74
                                except StopIteration:
 
75
                                        keepReading=False
 
76
                                        continue
 
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:
 
87
                                        del objIndexMap[i]
58
88
                while speech.isPaused:
59
89
                        yield
60
 
                        continue
61
 
                if keepReading:
62
 
                        speech.speakObject(obj,index=indexCount,reason=speech.REASON_SAYALL)
63
 
                        up=[]
64
 
                        down=[]
65
 
                        obj=obj.getNextInFlow(up=up,down=down)
66
 
                        if not obj:
67
 
                                endIndex=indexCount
68
 
                                keepReading=False
69
 
                        indexCount+=1
70
 
                        levelsIndexMap[indexCount]=(len(up),len(down))
71
 
                spokenIndex=speech.getLastSpeechIndex()
72
 
                if spokenIndex is None:
73
 
                        spokenIndex=0
74
 
                for count in range(spokenIndex-lastSpokenIndex):
75
 
                        upLen,downLen=levelsIndexMap.get(lastSpokenIndex+count+1,(0,0))
76
 
                        if upLen==0 and downLen==0:
77
 
                                tones.beep(880,50)
78
 
                        if upLen>0:
79
 
                                for count in range(upLen+1):
80
 
                                        tones.beep(880*(1.25**count),50)
81
 
                                        time.sleep(0.025)
82
 
                        if downLen>0:
83
 
                                for count in range(downLen+1):
84
 
                                        tones.beep(880/(1.25**count),50)
85
 
                                        time.sleep(0.025)
86
 
                        updateObj=updateObj.nextInFlow
87
 
                        api.setNavigatorObject(updateObj)
88
 
                if not keepReading and spokenIndex>=endIndex:
89
 
                        keepUpdating=False
90
 
                lastSpokenIndex=spokenIndex
91
90
                yield
92
91
 
93
92
def readText(info,cursor):
94
93
        _startGenerator(readTextHelper_generator(info,cursor))
95
94
 
96
95
def readTextHelper_generator(info,cursor):
97
 
        sendCount=0
98
 
        receiveCount=0
 
96
        lastSentIndex=0
 
97
        lastReceivedIndex=0
99
98
        cursorIndexMap={}
 
99
        if not info.obj:
 
100
                # The object died, so we should too.
 
101
                return
100
102
        reader=info.copy()
101
103
        if not reader.isCollapsed:
102
104
                reader.collapse()
103
105
        keepReading=True
104
106
        keepUpdating=True
105
 
        oldSpokenIndex=None
106
107
        while keepUpdating:
107
 
                # receiveCount might be None if other speech was interspersed with this say all.
 
108
                if not reader.obj:
 
109
                        # The object died, so we should too.
 
110
                        return
 
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:
110
114
                        if keepReading:
111
115
                                bookmark=reader.bookmark
112
 
                                index=sendCount
 
116
                                index=lastSentIndex+1
113
117
                                delta=reader.move(textInfos.UNIT_READINGCHUNK,1,endPoint="end")
114
118
                                if delta<=0:
 
119
                                        speech.speakWithoutPauses(None)
115
120
                                        keepReading=False
116
121
                                        continue
117
 
                                speech.speakTextInfo(reader,reason=speech.REASON_SAYALL,index=index)
118
 
                                sendCount+=1
 
122
                                speech.speakTextInfo(reader,unit=textInfos.UNIT_READINGCHUNK,reason=speech.REASON_SAYALL,index=index)
 
123
                                lastSentIndex=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)
 
125
                                try:
 
126
                                        reader.collapse(end=True)
 
127
                                except RuntimeError: #MS Word when range covers end of document
 
128
                                        speech.speakWithoutPauses(None)
 
129
                                        keepReading=False
 
130
                else:
 
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: