During sayAll, only cache controlField and formatField speech when the text at that point is actually spoken, rather than when the speech is first queued. This stops inappropratiate announcement of entering/exiting fields when speaking text after a sayAll, although the synth never actually got around to speaking that particular text.
Specifically:
* Added a new SpeakTextInfoState class to speech.py which can hold controlField stack, formatField and indentation info for caching. It is instanciated with an NVDAObject or treeInterceptor in which it collects a previous SpeakTextInfoState to get the initial values. There is also an updateObj method which can apply the curent state back to the NVDAObject/treeInterceptor.
* speech.speakTextInfo: all controlField/formatField/indentation info is sotred on a SpeakTextInfoState object now, rather than directly on the TextInfo's obj. If speakTextInfo's useCache argument is True, then speakTextInfo creates its own state object, and also ensure that the info is written back to the NVDAObject/treeInterceptor at the end, ensuring older behaviour. However, if useCache is a pre-existing SpeakTextInfoState object, then speakTextInfo uses this, but does not write back the info to the NVDAObject/treeInterceptor itself, rather it assume that the caller of speakTextInfo will do so at a later time.
* sayallHandler.readTextHelper_generator: create a SpeakTextInfoState object at the start of the function, and keep passing this to speakTextInfo via its useCache argument. After each call to speakTextInfo, save a copy of the SpeakTextInfoState as it is ight now along with the text position bookmark under this index in the index map. When this indes received from they synth (i.e. the text is actually speaking), fetch the speakTextInfoState for this index, and write back the info to the underlying NVDAObject/treeInterceptor.
# Please enter the commit message for your changes. Lines starting