Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions source/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,6 @@ def main():
import speech
log.debug("Initializing speech")
speech.initialize()
from speech import sayAll
log.debug("Initializing sayAllHandler")
sayAll.initialize()
if not globalVars.appArgs.minimal and (time.time()-globalVars.startTime)>5:
log.debugWarning("Slow starting core (%.2f sec)" % (time.time()-globalVars.startTime))
# Translators: This is spoken when NVDA is starting.
Expand Down
16 changes: 10 additions & 6 deletions source/documentBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
#See the file COPYING for more details.

from baseObject import AutoPropertyObject, ScriptableObject
from scriptHandler import isScriptWaiting
import config
import textInfos
import speech
import ui
import controlTypes


class TextContainerObject(AutoPropertyObject):
"""
An object that contains text which can be accessed via a call to a makeTextInfo method.
Expand Down Expand Up @@ -141,6 +139,12 @@ def _getNearestTableCell(self, tableID, startPos, origRow, origCol, origRowSpan,
raise LookupError

def _tableMovementScriptHelper(self, movement="next", axis=None):
# documentBase is a core module and should not depend on these UI modules and so they are imported
# at run-time. (#12404)
from scriptHandler import isScriptWaiting
from speech import speakTextInfo
import ui

if isScriptWaiting():
return
formatConfig=config.conf["documentFormatting"].copy()
Expand All @@ -162,7 +166,7 @@ def _tableMovementScriptHelper(self, movement="next", axis=None):
# Retrieve the cell on which we started.
info = self._getTableCellAt(tableID, self.selection,origRow, origCol)

speech.speakTextInfo(info, formatConfig=formatConfig, reason=controlTypes.OutputReason.CARET)
speakTextInfo(info, formatConfig=formatConfig, reason=controlTypes.OutputReason.CARET)
info.collapse()
self.selection = info

Expand All @@ -187,6 +191,8 @@ def script_previousColumn(self, gesture):
script_previousColumn.__doc__ = _("moves to the previous table column")

def script_toggleIncludeLayoutTables(self,gesture):
# documentBase is a core module and should not depend on UI, so it is imported at run-time. (#12404)
import ui
if config.conf["documentFormatting"]["includeLayoutTables"]:
# Translators: The message announced when toggling the include layout tables browse mode setting.
state = _("layout tables off")
Expand All @@ -205,5 +211,3 @@ def script_toggleIncludeLayoutTables(self,gesture):
"kb:control+alt+rightArrow": "nextColumn",
"kb:control+alt+leftArrow": "previousColumn",
}


4 changes: 0 additions & 4 deletions source/scriptHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@
from typing import List, Optional
import time
import weakref
import inspect
import types
import config
import speech
from speech import sayAll
import appModuleHandler
import api
import queueHandler
from logHandler import log
import inputCore
import globalPluginHandler
import braille
import vision
import keyLabels
import baseObject

_numScriptsQueued=0 #Number of scripts that are queued to be executed
Expand Down
13 changes: 12 additions & 1 deletion source/speech/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
speakSpelling,
speakText,
speakTextInfo,
SpeakTextInfoState,
speakTextSelected,
speakTypedCharacters,
SpeechMode,
Expand Down Expand Up @@ -132,6 +133,7 @@
"speakSpelling",
"speakText",
"speakTextInfo",
"SpeakTextInfoState",
"speakTextSelected",
"speakTypedCharacters",
"SpeechMode",
Expand All @@ -142,13 +144,22 @@
import synthDriverHandler
import config
from .speech import initialize as speechInitialize
from .sayAll import initialize as sayAllInitialize
Comment thread
feerrenrut marked this conversation as resolved.


def initialize():
"""Loads and sets the synth driver configured in nvda.ini."""
""" Loads and sets the synth driver configured in nvda.ini.
Initializes the state of speech and initializes the sayAllHandler
"""
synthDriverHandler.initialize()
synthDriverHandler.setSynth(config.conf["speech"]["synth"])
speechInitialize()
sayAllInitialize(
speak,
speakObject,
getTextInfoSpeech,
SpeakTextInfoState,
)


def terminate():
Expand Down
50 changes: 37 additions & 13 deletions source/speech/sayAll.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@
# Julien Cochuyt

from enum import IntEnum
from typing import TYPE_CHECKING
from typing import Callable, TYPE_CHECKING
import weakref
import garbageHandler
from .speech import (
speak,
getTextInfoSpeech,
SpeakTextInfoState,
speakObject,
)
from logHandler import log
import config
import controlTypes
Expand All @@ -26,11 +20,17 @@
from .speechWithoutPauses import SpeechWithoutPauses

from .types import (
SpeechSequence,
_flattenNestedSequences,
)

if TYPE_CHECKING:
import NVDAObjects
from .speech import (
getTextInfoSpeech,
SpeakTextInfoState,
speakObject,
)


class CURSOR(IntEnum):
Expand All @@ -41,18 +41,38 @@ class CURSOR(IntEnum):
SayAllHandler = None


def initialize():
def initialize(
speakFunc: Callable[[SpeechSequence], None],
speakObject: 'speakObject',
getTextInfoSpeech: 'getTextInfoSpeech',
SpeakTextInfoState: 'SpeakTextInfoState',
):
log.debug("Initializing sayAllHandler")
global SayAllHandler
SayAllHandler = _SayAllHandler(SpeechWithoutPauses(speakFunc=speak))
SayAllHandler = _SayAllHandler(
SpeechWithoutPauses(speakFunc=speakFunc),
speakObject,
getTextInfoSpeech,
SpeakTextInfoState,
)


class _SayAllHandler:
def __init__(self, speechWithoutPausesInstance: SpeechWithoutPauses):
def __init__(
self,
speechWithoutPausesInstance: SpeechWithoutPauses,
speakObject: 'speakObject',
getTextInfoSpeech: 'getTextInfoSpeech',
SpeakTextInfoState: 'SpeakTextInfoState',
):
self.lastSayAllMode = None
self.speechWithoutPausesInstance = speechWithoutPausesInstance
#: The active say all manager.
#: This is a weakref because the manager should be allowed to die once say all is complete.
self._getActiveSayAll = lambda: None # noqa: Return None when called like a dead weakref.
self._speakObject = speakObject
self._getTextInfoSpeech = getTextInfoSpeech
self._makeSpeakTextInfoState = SpeakTextInfoState

def stop(self):
'''
Expand Down Expand Up @@ -115,7 +135,11 @@ def next(self):
return
# Call this method again when we start speaking this object.
callbackCommand = CallbackCommand(self.next, name="say-all:next")
speakObject(obj, reason=controlTypes.OutputReason.SAYALL, _prefixSpeechCommand=callbackCommand)
SayAllHandler._speakObject(
obj,
reason=controlTypes.OutputReason.SAYALL,
_prefixSpeechCommand=callbackCommand
)

def stop(self):
self.walker = None
Expand Down Expand Up @@ -158,7 +182,7 @@ def __init__(self, handler: _SayAllHandler, cursor: CURSOR):
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 = SpeakTextInfoState(self.reader.obj)
self.speakTextInfoState = SayAllHandler._makeSpeakTextInfoState(self.reader.obj)
self.numBufferedLines = 0

def nextLine(self):
Expand Down Expand Up @@ -207,7 +231,7 @@ def _onLineReached(obj=self.reader.obj, state=state):
# and insert the lineReached callback at the very beginning of the sequence.
# _linePrefix on speakTextInfo cannot be used here
# As it would be inserted in the sequence after all initial control starts which is too late.
speechGen = getTextInfoSpeech(
speechGen = SayAllHandler._getTextInfoSpeech(
self.reader,
unit=textInfos.UNIT_READINGCHUNK,
reason=controlTypes.OutputReason.SAYALL,
Expand Down