[orca] More work on removal of direct calls to speech.speak()



commit db2a0845c76f24db659faea2f929fee3de5bdb88
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Wed Jan 12 16:31:38 2022 +0100

    More work on removal of direct calls to speech.speak()
    
    The default script already has methods which make it possible for
    messages to be spoken. Using these methods will facilitate on-the-fly
    language switching.

 src/orca/mouse_review.py                           |  1 -
 src/orca/scripts/apps/Instantbird/script.py        |  4 ++--
 src/orca/scripts/apps/Thunderbird/script.py        |  8 +++----
 .../apps/gnome-screensaver-dialog/script.py        | 22 +++++++++--------
 .../scripts/apps/notification-daemon/script.py     |  5 ++--
 src/orca/scripts/apps/notify-osd/script.py         | 18 +++++++-------
 src/orca/scripts/apps/pidgin/script.py             |  7 +++---
 src/orca/scripts/apps/soffice/script.py            | 21 +++++-----------
 src/orca/scripts/default.py                        | 22 ++++++++++-------
 src/orca/scripts/terminal/script.py                |  7 ++----
 src/orca/scripts/toolkits/gtk/script.py            |  4 +---
 src/orca/scripts/web/script.py                     | 28 ++++++++++------------
 src/orca/structural_navigation.py                  |  9 +++----
 13 files changed, 70 insertions(+), 86 deletions(-)
---
diff --git a/src/orca/mouse_review.py b/src/orca/mouse_review.py
index 1a8687229..77d463b99 100644
--- a/src/orca/mouse_review.py
+++ b/src/orca/mouse_review.py
@@ -47,7 +47,6 @@ from . import orca
 from . import orca_state
 from . import script_manager
 from . import settings_manager
-from . import speech
 
 _eventManager = event_manager.getManager()
 _scriptManager = script_manager.getManager()
diff --git a/src/orca/scripts/apps/Instantbird/script.py b/src/orca/scripts/apps/Instantbird/script.py
index 60216f68e..27e6105cb 100644
--- a/src/orca/scripts/apps/Instantbird/script.py
+++ b/src/orca/scripts/apps/Instantbird/script.py
@@ -33,7 +33,6 @@ import orca.orca as orca
 import orca.settings_manager as settings_manager
 import orca.orca_state as orca_state
 import orca.scripts.toolkits.Gecko as Gecko
-import orca.speech as speech
 
 from .chat import Chat
 from .script_utilities import Utilities
@@ -184,7 +183,8 @@ class Script(Gecko.Script):
             room1 = self.chat.getChatRoomName(orca_state.locusOfFocus)
             room2 = self.chat.getChatRoomName(event.source)
             if room1 != room2:
-                speech.speak(room2)
+                voice = self.speechGenerator.voice(obj=event.source, string=room2)
+                self.speakMessage(room2, voice=voice)
                 flashTime = _settingsManager.getSetting('brailleFlashTime')
                 self.displayBrailleMessage(room2, flashTime)
                 orca.setLocusOfFocus(event, event.source)
diff --git a/src/orca/scripts/apps/Thunderbird/script.py b/src/orca/scripts/apps/Thunderbird/script.py
index 74f5b019a..a19e15c74 100644
--- a/src/orca/scripts/apps/Thunderbird/script.py
+++ b/src/orca/scripts/apps/Thunderbird/script.py
@@ -34,7 +34,6 @@ import orca.input_event as input_event
 import orca.scripts.default as default
 import orca.settings_manager as settings_manager
 import orca.orca_state as orca_state
-import orca.speech as speech
 import orca.scripts.toolkits.Gecko as Gecko
 
 from .spellcheck import SpellCheck
@@ -321,7 +320,8 @@ class Script(Gecko.Script):
             else:
                 hasSelection = text.getNSelections() > 0
             if hasSelection or isSystemEvent:
-                speech.speak(event.any_data)
+                voice = self.speechGenerator.voice(obj=event.source, string=event.any_data)
+                self.speakMessage(event.any_data, voice=voice)
                 self._lastAutoComplete = event.any_data
                 return
 
@@ -354,9 +354,7 @@ class Script(Gecko.Script):
            or not self.utilities.isDocument(event.source):
             return
 
-        speech.speak(obj.name)
-        [obj, offset] = self.utilities.findFirstCaretContext(obj, 0)
-        self.utilities.setCaretPosition(obj, offset)
+        super().onNameChanged(event)
 
     def _presentMessage(self, documentFrame):
         """Presents the first line of the message, or the entire message,
diff --git a/src/orca/scripts/apps/gnome-screensaver-dialog/script.py 
b/src/orca/scripts/apps/gnome-screensaver-dialog/script.py
index f7ba5068a..ac61a9a5a 100644
--- a/src/orca/scripts/apps/gnome-screensaver-dialog/script.py
+++ b/src/orca/scripts/apps/gnome-screensaver-dialog/script.py
@@ -28,25 +28,27 @@ __license__   = "LGPL"
 import pyatspi
 
 import orca.scripts.toolkits.gtk as gtk
-import orca.speech as speech
 
 class Script(gtk.Script):
 
     def onFocusedChanged(self, event):
         """Callback for object:state-changed:focused accessibility events."""
 
-        obj = event.source
+        if event.source.getRole() != pyatspi.ROLE_PASSWORD_TEXT:
+            gtk.Script.onFocusedChanged(self, event)
+            return
 
         # If we are focused in a password text area, we need to check if
         # there are any useful messages displayed in a couple of labels that
         # are visually below that password area. If there are, then speak
         # them for the user. See bug #529655 for more details.
         #
-        if obj.getRole() == pyatspi.ROLE_PASSWORD_TEXT:
-            obj = obj.parent.parent.parent
-            for child in obj:
-                if child.getRole() == pyatspi.ROLE_LABEL and child.name:
-                    speech.speak(child.name)
-                return
-
-        gtk.Script.onFocusedChanged(self, event)
+        strings = []
+        for child in event.source.parent.parent.parent:
+            if child.getRole() == pyatspi.ROLE_LABEL and child.name:
+                strings.append(child.name)
+
+        string = " ".join(strings)
+        voice = self.speechGenerator.voice(obj=event.source, string=string)
+        self.speakMessage(string, voice=voice)
+        self.updateBraille(event.source)
diff --git a/src/orca/scripts/apps/notification-daemon/script.py 
b/src/orca/scripts/apps/notification-daemon/script.py
index aba9f83fb..8f5bff876 100644
--- a/src/orca/scripts/apps/notification-daemon/script.py
+++ b/src/orca/scripts/apps/notification-daemon/script.py
@@ -30,7 +30,6 @@ import pyatspi
 import orca.messages as messages
 import orca.scripts.default as default
 import orca.settings as settings
-import orca.speech as speech
 import orca.notification_messages as notification_messages
 
 ########################################################################
@@ -48,6 +47,8 @@ class Script(default.Script):
         allLabels = pyatspi.findAllDescendants(event.source, hasRole)
         texts = [self.utilities.displayedText(acc) for acc in allLabels]
         text = '%s %s' % (messages.NOTIFICATION, ' '.join(texts))
-        speech.speak(text, None, True)
+
+        voice = self.speechGenerator.voice(obj=event.source, string=text)
+        self.speakMessage(text, voice=voice)
         self.displayBrailleMessage(text, flashTime=settings.brailleFlashTime)
         notification_messages.saveMessage(text)
diff --git a/src/orca/scripts/apps/notify-osd/script.py b/src/orca/scripts/apps/notify-osd/script.py
index 813781348..c4a00a575 100644
--- a/src/orca/scripts/apps/notify-osd/script.py
+++ b/src/orca/scripts/apps/notify-osd/script.py
@@ -29,7 +29,6 @@ import orca.messages as messages
 import orca.scripts.default as default
 import orca.settings as settings
 import orca.settings_manager as settings_manager
-import orca.speech as speech
 import orca.notification_messages as notification_messages
 
 _settingsManager = settings_manager.getManager()
@@ -49,8 +48,10 @@ class Script(default.Script):
             value = -1
 
         if value >= 0:
-            speech.speak(str(value), None, True)
-            self.displayBrailleMessage("%s" % value,
+            string = str(value)
+            voice = self.speechGenerator.voice(obj=event.source, string=string)
+            self.speakMessage(string, voice=voice)
+            self.displayBrailleMessage(string,
                                        flashTime=settings.brailleFlashTime)
 
     def onNameChanged(self, event):
@@ -66,19 +67,16 @@ class Script(default.Script):
         message = ""
         voices = _settingsManager.getSetting('voices')
         if value < 0:
-            utterances.append(messages.NOTIFICATION)
-            utterances.append(voices.get(settings.SYSTEM_VOICE))
+            self.speakMessage(messages.NOTIFICATION)
             message = '%s %s' % (event.source.name, event.source.description)
-            utterances.append(message)
-            utterances.append(voices.get(settings.DEFAULT_VOICE))
         else:
             # A gauge notification, e.g. the Ubuntu volume notification that
             # appears when you press the multimedia keys.
             #
             message = '%s %d' % (event.source.name, value)
-            utterances.append(message)
-            utterances.append(voices.get(settings.SYSTEM_VOICE))
+            self.speakMessage(message)
 
-        speech.speak(utterances, None, True)
+        voice = self.speechGenerator.voice(obj=event.source, string=message)
+        self.speakMessage(message, voice=voice)
         self.displayBrailleMessage(message, flashTime=settings.brailleFlashTime)
         notification_messages.saveMessage(message)
diff --git a/src/orca/scripts/apps/pidgin/script.py b/src/orca/scripts/apps/pidgin/script.py
index 87498870a..861e5531c 100644
--- a/src/orca/scripts/apps/pidgin/script.py
+++ b/src/orca/scripts/apps/pidgin/script.py
@@ -32,7 +32,6 @@ import orca.debug as debug
 import orca.messages as messages
 import orca.scripts.toolkits.GAIL as GAIL
 import orca.settings as settings
-import orca.speech as speech
 
 from .chat import Chat
 from .script_utilities import Utilities
@@ -133,7 +132,8 @@ class Script(GAIL.Script):
                     child = event.source[-1]
                     if child.name:
                         line = messages.CHAT_NEW_TAB % child.name
-                        speech.speak(line)
+                        voice = self.speechGenerator.voice(obj=child, string=line)
+                        self.speakMessage(line, voice=voice)
 
     def onNameChanged(self, event):
         """Called whenever a property on an object changes.
@@ -208,8 +208,7 @@ class Script(GAIL.Script):
         obj = event.source
         if self.chat.isInBuddyList(obj):
             obj = obj.parent[obj.getIndexInParent() + 1]
-            self.updateBraille(obj)
-            speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
+            self.presentObject(obj, alreadyFocused=True)
             return
             
         GAIL.Script.onExpandedChanged(self, event)
diff --git a/src/orca/scripts/apps/soffice/script.py b/src/orca/scripts/apps/soffice/script.py
index 14ac34790..2912c4717 100644
--- a/src/orca/scripts/apps/soffice/script.py
+++ b/src/orca/scripts/apps/soffice/script.py
@@ -39,7 +39,6 @@ import orca.input_event as input_event
 import orca.messages as messages
 import orca.orca as orca
 import orca.orca_state as orca_state
-import orca.speech as speech
 import orca.settings as settings
 import orca.settings_manager as settings_manager
 import orca.structural_navigation as structural_navigation
@@ -304,14 +303,6 @@ class Script(default.Script):
         prefs.update(self.spellcheck.getPreferencesFromGUI())
         return prefs
 
-    def presentObject(self, obj, **args):
-        if not self._lastCommandWasStructNav:
-            super().presentObject(obj, **args)
-            return
-
-        utterances = self.speechGenerator.generateSpeech(obj, **args)
-        speech.speak(utterances)
-
     def panBrailleLeft(self, inputEvent=None, panAmount=0):
         """In document content, we want to use the panning keys to browse the
         entire document.
@@ -531,9 +522,7 @@ class Script(default.Script):
                     for tab in child:
                         eventState = tab.getState()
                         if eventState.contains(pyatspi.STATE_SELECTED):
-                            utterances = \
-                                self.speechGenerator.generateSpeech(tab)
-                            speech.speak(utterances)
+                            self.presentObject(tab)
 
         # TODO - JD: This is a hack that needs to be done better. For now it
         # fixes the broken echo previous word on Return.
@@ -553,8 +542,10 @@ class Script(default.Script):
             isControlKey = mods & keybindings.CTRL_MODIFIER_MASK
             isShiftKey = mods & keybindings.SHIFT_MODIFIER_MASK
             if event_string in ["Up", "Down"] and isControlKey and not isShiftKey:
-                if self.utilities.displayedText(newLocusOfFocus):
-                    speech.speak(self.utilities.displayedText(newLocusOfFocus))
+                string = self.utilities.displayedText(newLocusOfFocus)
+                if string:
+                    voice = self.speechGenerator.voice(obj=newLocusOfFocus, string=string)
+                    self.speakMessage(string, voice=voice)
                     self.updateBraille(newLocusOfFocus)
                     try:
                         text = newLocusOfFocus.queryText()
@@ -860,7 +851,7 @@ class Script(default.Script):
             wasCommand = mods & keybindings.COMMAND_MODIFIER_MASK
             weToggledIt = wasCommand and keyString not in navKeys
         if weToggledIt:
-            speech.speak(self.speechGenerator.generateSpeech(obj))
+            self.presentObject(obj, alreadyFocused=True)
 
     def onSelectedChanged(self, event):
         """Callback for object:state-changed:selected accessibility events."""
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 4478e84e7..1a555967f 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -2322,8 +2322,7 @@ class Script(script.Script):
         if hash(oldObj) == hash(obj) and oldState == event.detail1:
             return
  
-        self.updateBraille(obj)
-        speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
+        self.presentObject(obj, alreadyFocused=True)
         self.pointOfReference['checkedChange'] = hash(obj), event.detail1
 
     def onChildrenAdded(self, event):
@@ -4011,15 +4010,9 @@ class Script(script.Script):
                 self.phoneticSpellCurrentItem(event.event_string)
                 return True
 
-        string = None
-        if event.isPrintableKey():
-            string = event.event_string
-
         msg = "DEFAULT: Presenting keyboard event"
         debug.println(debug.LEVEL_INFO, msg, True)
-
-        voice = self.speechGenerator.voice(string=string)
-        speech.speakKeyEvent(event, voice)
+        self.speakKeyEvent(event)
         return True
 
     def presentMessage(self, fullMessage, briefMessage=None, voice=None, resetStyles=True, force=False):
@@ -4438,6 +4431,17 @@ class Script(script.Script):
     #                                                                      #
     ########################################################################
 
+    def speakKeyEvent(self, event):
+        """Method to speak a keyboard event. Scripts should use this method
+        rather than calling speech.speakKeyEvent directly."""
+
+        string = None
+        if event.isPrintableKey():
+            string = event.event_string
+
+        voice = self.speechGenerator.voice(string=string)
+        speech.speakKeyEvent(event, voice)
+
     def speakCharacter(self, character):
         """Method to speak a single character. Scripts should use this
         method rather than calling speech.speakCharacter directly."""
diff --git a/src/orca/scripts/terminal/script.py b/src/orca/scripts/terminal/script.py
index 102cf4a86..b74140998 100644
--- a/src/orca/scripts/terminal/script.py
+++ b/src/orca/scripts/terminal/script.py
@@ -27,7 +27,6 @@ __license__   = "LGPL"
 from orca import debug
 from orca import orca
 from orca import orca_state
-from orca import speech
 from orca.scripts import default
 
 from .braille_generator import BrailleGenerator
@@ -97,7 +96,7 @@ class Script(default.Script):
             self.speakCharacter(newString)
         else:
             voice = self.speechGenerator.voice(obj=event.source, string=newString)
-            speech.speak(newString, voice)
+            self.speakMessage(newString, voice=voice)
 
         if self.flatReviewContext:
             return
@@ -138,9 +137,7 @@ class Script(default.Script):
 
         msg = "TERMINAL: Presenting keyboard event %s" % string
         debug.println(debug.LEVEL_INFO, msg, True)
-
-        voice = self.speechGenerator.voice(string=string)
-        speech.speakKeyEvent(event, voice)
+        self.speakKeyEvent(event)
         return True
 
     def skipObjectEvent(self, event):
diff --git a/src/orca/scripts/toolkits/gtk/script.py b/src/orca/scripts/toolkits/gtk/script.py
index 22921f4fa..2cfeaa70a 100644
--- a/src/orca/scripts/toolkits/gtk/script.py
+++ b/src/orca/scripts/toolkits/gtk/script.py
@@ -33,7 +33,6 @@ import orca.mouse_review as mouse_review
 import orca.orca as orca
 import orca.orca_state as orca_state
 import orca.scripts.default as default
-import orca.speech as speech
 
 from .script_utilities import Utilities
 
@@ -91,8 +90,7 @@ class Script(default.Script):
         if not pyatspi.findAncestor(obj, isListBox):
             return
 
-        self.updateBraille(obj)
-        speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
+        self.presentObject(obj, alreadyFocused=True)
 
     def onFocus(self, event):
         """Callback for focus: accessibility events."""
diff --git a/src/orca/scripts/web/script.py b/src/orca/scripts/web/script.py
index cebd30764..c8e2e2d59 100644
--- a/src/orca/scripts/web/script.py
+++ b/src/orca/scripts/web/script.py
@@ -993,9 +993,7 @@ class Script(default.Script):
             args["priorObj"] = priorObj
 
         if obj.getRole() == pyatspi.ROLE_ENTRY:
-            utterances = self.speechGenerator.generateSpeech(obj, **args)
-            speech.speak(utterances)
-            self.updateBraille(obj)
+            super().presentObject(obj, **args)
             return
 
         # We shouldn't use cache in this method, because if the last thing we presented
@@ -1324,61 +1322,60 @@ class Script(default.Script):
         self.updateBraille(newFocus, documentFrame=document)
         orca.emitRegionChanged(newFocus, caretOffset)
 
+        contents = None
+        args = {}
         if self._lastCommandWasMouseButton and event \
              and event.type.startswith("object:text-caret-moved"):
             msg = "WEB: Last input event was mouse button. Generating line contents."
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset)
-            utterances = self.speechGenerator.generateContents(contents, priorObj=oldFocus)
+            args['priorObj'] = oldFocus
         elif self.utilities.isContentEditableWithEmbeddedObjects(newFocus) \
            and (self._lastCommandWasCaretNav or self._lastCommandWasStructNav) \
            and not (newFocus.getRole() == pyatspi.ROLE_TABLE_CELL and newFocus.name):
             msg = "WEB: New focus %s content editable. Generating line contents." % newFocus
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset)
-            utterances = self.speechGenerator.generateContents(contents)
         elif self.utilities.isAnchor(newFocus):
             msg = "WEB: New focus %s is anchor. Generating line contents." % newFocus
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, 0)
-            utterances = self.speechGenerator.generateContents(contents)
         elif self.utilities.lastInputEventWasPageNav() and not self.utilities.getTable(newFocus):
             msg = "WEB: New focus %s was scrolled to. Generating line contents." % newFocus
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset)
-            utterances = self.speechGenerator.generateContents(contents)
         elif self.utilities.isFocusedWithMathChild(newFocus):
             msg = "WEB: New focus %s has math child. Generating line contents." % newFocus
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset)
-            utterances = self.speechGenerator.generateContents(contents)
         elif newFocus.getRole() == pyatspi.ROLE_HEADING:
             msg = "WEB: New focus %s is heading. Generating object contents." % newFocus
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getObjectContentsAtOffset(newFocus, 0)
-            utterances = self.speechGenerator.generateContents(contents)
         elif self.utilities.caretMovedToSamePageFragment(event, oldFocus):
             msg = "WEB: Event source %s is same page fragment. Generating line contents." % event.source
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, 0)
-            utterances = self.speechGenerator.generateContents(contents)
         elif self.utilities.lastInputEventWasLineNav() and self.utilities.isZombie(oldFocus):
             msg = "WEB: Last input event was line nav; oldFocus is zombie. Generating line contents."
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset)
-            utterances = self.speechGenerator.generateContents(contents)
         elif self.utilities.lastInputEventWasLineNav() and event \
              and event.type.startswith("object:children-changed"):
             msg = "WEB: Last input event was line nav and children changed. Generating line contents."
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset)
-            utterances = self.speechGenerator.generateContents(contents)
         else:
             msg = "WEB: New focus %s is not a special case. Generating speech." % newFocus
             debug.println(debug.LEVEL_INFO, msg, True)
-            utterances = self.speechGenerator.generateSpeech(newFocus, priorObj=oldFocus)
+            args['priorObj'] = oldFocus
+
+        if contents:
+            self.speakContents(contents, **args)
+        else:
+            utterances = self.speechGenerator.generateSpeech(newFocus, **args)
+            speech.speak(utterances)
 
-        speech.speak(utterances)
         self._saveFocusedObjectInfo(newFocus)
 
         if self.utilities.inTopLevelWebApp(newFocus) and not self._browseModeIsSticky:
@@ -1758,8 +1755,7 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg, True)
             return False
 
-        self.updateBraille(obj)
-        speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
+        self.presentObject(obj, alreadyFocused=True)
         self.pointOfReference['checkedChange'] = hash(obj), event.detail1
         return True
 
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 11b16cad3..4c93521ca 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -42,7 +42,6 @@ from . import orca_gui_navlist
 from . import orca_state
 from . import settings
 from . import settings_manager
-from . import speech
 
 _settingsManager = settings_manager.getManager()
 #############################################################################
@@ -1162,14 +1161,16 @@ class StructuralNavigation:
             for header in rowHeaders:
                 if not header in oldRowHeaders:
                     text = self._getCellText(header)
-                    speech.speak(text)
+                    voice = self._script.speechGenerator.voice(string=text)
+                    self._script.speakMessage(text, voice=voice, force=True)
 
         if colDiff:
             colHeaders = self._script.utilities.columnHeadersForCell(cell)
             for header in colHeaders:
                 if not header in oldColHeaders:
                     text = self._getCellText(header)
-                    speech.speak(text)
+                    voice = self._script.speechGenerator.voice(string=text)
+                    self._script.speakMessage(text, voice=voice, force=True)
 
     def getCellCoordinates(self, obj, preferAttribute=True):
         """Returns the [row, col] of a ROLE_TABLE_CELL or [-1, -1]
@@ -2983,7 +2984,7 @@ class StructuralNavigation:
         if not blank:
             self._presentObject(cell, 0)
         else:
-            speech.speak(messages.BLANK)
+            self._script.speakMessage(messages.BLANK)
 
         if settings.speakCellCoordinates:
             [row, col] = self.getCellCoordinates(cell)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]