[orca] Fix for bug #520595 - Orca is far too "chatty" for persons with learning disabilities



commit a85356554713d5e5cfbb8cea223372d161bddf4a
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date:   Mon Aug 16 21:09:09 2010 -0400

    Fix for bug #520595 - Orca is far too "chatty" for persons with learning disabilities

 src/orca/default.py                                |   38 ++-
 src/orca/orca-setup.ui                             |  299 +++++++++++---------
 src/orca/orca.py                                   |    6 +-
 src/orca/orca_gui_prefs.py                         |   20 ++
 .../scripts/apps/evolution/speech_generator.py     |    4 +
 src/orca/scripts/apps/soffice/speech_generator.py  |    6 +
 .../scripts/toolkits/Gecko/speech_generator.py     |   17 +-
 .../J2SE-access-bridge/speech_generator.py         |    6 +
 src/orca/settings.py                               |    6 +
 src/orca/speech_generator.py                       |   87 ++++++
 10 files changed, 327 insertions(+), 162 deletions(-)
---
diff --git a/src/orca/default.py b/src/orca/default.py
index 655b128..bf369f6 100644
--- a/src/orca/default.py
+++ b/src/orca/default.py
@@ -3263,6 +3263,7 @@ class Script(script.Script):
                 return
 
         if event.type.startswith("object:state-changed:selected") \
+           and not settings.onlySpeakDisplayedText \
            and orca_state.locusOfFocus:
             # If this selection state change is for the object which
             # currently has the locus of focus, and the last keyboard
@@ -5104,6 +5105,9 @@ class Script(script.Script):
         - endOffset: text end offset.
         """
 
+        if settings.onlySpeakDisplayedText:
+            return
+
         try:
             text = obj.queryText()
         except:
@@ -5280,18 +5284,19 @@ class Script(script.Script):
         except:
             debug.printException(debug.LEVEL_FINEST)
 
-        voice = self.voices.get(settings.SYSTEM_VOICE)
-        if self.utilities.isTextSelected(obj, startOffset, endOffset):
-            # Translators: when the user selects (highlights) text in
-            # a document, Orca lets them know this.
-            #
-            speech.speak(C_("text", "selected"), voice, False)
-        elif len(text.getText(startOffset, endOffset)):
-            # Translators: when the user unselects
-            # (unhighlights) text in a document, Orca lets
-            # them know this.
-            #
-            speech.speak(C_("text", "unselected"), voice, False)
+        if not settings.onlySpeakDisplayedText:
+            voice = self.voices.get(settings.SYSTEM_VOICE)
+            if self.utilities.isTextSelected(obj, startOffset, endOffset):
+                # Translators: when the user selects (highlights) text in
+                # a document, Orca lets them know this.
+                #
+                speech.speak(C_("text", "selected"), voice, False)
+            elif len(text.getText(startOffset, endOffset)):
+                # Translators: when the user unselects
+                # (unhighlights) text in a document, Orca lets
+                # them know this.
+                #
+                speech.speak(C_("text", "unselected"), voice, False)
 
         self._saveLastTextSelections(text)
 
@@ -5381,7 +5386,8 @@ class Script(script.Script):
         if briefMessage is None:
             briefMessage = fullMessage
 
-        if settings.enableSpeech:
+        if settings.enableSpeech \
+           and (voice != None or not settings.onlySpeakDisplayedText):
             if settings.messageVerbosityLevel == settings.VERBOSITY_LEVEL_BRIEF:
                 message = briefMessage
             else:
@@ -5742,8 +5748,10 @@ class Script(script.Script):
           prior to speaking the new text.
         """
 
-        voice = voice or self.voices.get(settings.SYSTEM_VOICE)
-        speech.speak(string, voice, interrupt)
+        if settings.enableSpeech \
+           and (voice != None or not settings.onlySpeakDisplayedText):
+            voice = voice or self.voices.get(settings.SYSTEM_VOICE)
+            speech.speak(string, voice, interrupt) 
 
     @staticmethod
     def presentItemsInSpeech(items):
diff --git a/src/orca/orca-setup.ui b/src/orca/orca-setup.ui
index c5b8429..41c8ff0 100644
--- a/src/orca/orca-setup.ui
+++ b/src/orca/orca-setup.ui
@@ -1272,175 +1272,196 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkTable" id="checkBoxTable">
+                          <object class="GtkHBox" id="checkboxHBox">
                             <property name="visible">True</property>
-                            <property name="n_rows">4</property>
-                            <property name="n_columns">2</property>
+                            <property name="homogeneous">True</property>
                             <child>
-                              <object class="GtkCheckButton" id="speakBlankLinesCheckButton">
-                                <property name="label" translatable="yes">Speak blank lines</property>
+                              <object class="GtkVBox" id="vbox1">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="enableSpeechIndentationCheckButton">
-                                <property name="label" translatable="yes">Speak _indentation and justification</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
-                              </object>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="enableMnemonicSpeakingCheckButton">
-                                <property name="label" translatable="yes">Spea_k object mnemonics</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
-                              </object>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="enableTutorialMessagesCheckButton">
-                                <property name="label" translatable="yes">Speak tutorial messages</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
-                              </object>
-                              <packing>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="enablePositionSpeakingCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: This checkbox toggles whether or not Orca says the child position (e.g., 'item 6 of 7').">Speak child p_osition</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
-                              </object>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="speakMultiCaseStringsAsWordsCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis.">Speak multicase strings as wor_ds</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
-                              </object>
-                              <packing>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkCheckButton" id="enablePauseBreaksCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries).  This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is enountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated.">Break speech into ch_unks between pauses</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="use_underline">True</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                                <signal name="toggled" handler="checkButtonToggled"/>
+                                <child>
+                                  <object class="GtkCheckButton" id="onlySpeakDisplayedTextCheckButton">
+                                    <property name="label" translatable="yes" comments="Translators: If this setting is enabled, Orca will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. 'checkbox') or its state (e.g. 'not checked') or say 'mispelled' to indicate the presence of red squiggly spelling error lines -- things which Orca normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability.">Only speak displayed text</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="onlySpeakDisplayedTextToggled"/>
+                                  </object>
+                                  <packing>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="speakMultiCaseStringsAsWordsCheckButton">
+                                    <property name="label" translatable="yes" comments="Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis.">Speak multicase strings as wor_ds</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
+                                  </object>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="enablePauseBreaksCheckButton">
+                                    <property name="label" translatable="yes" comments="Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries).  This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is enountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated.">Break speech into ch_unks between pauses</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
+                                  </object>
+                                  <packing>
+                                    <property name="position">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkHBox" id="hbox39">
+                                    <property name="visible">True</property>
+                                    <property name="spacing">3</property>
+                                    <child>
+                                      <object class="GtkLabel" id="sayAllLabel">
+                                        <property name="visible">True</property>
+                                        <property name="label" translatable="yes" comments="Translators: Say all by refers to the way that Orca will say (speak) an amount of text -- in particular, where Orca where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and  say all by line.  If Orca were speaking a work of fiction, it's probably best to do say all by sentence so it sound more natural. If Orca were speaking something like a page of computer commands, doing a say all by line would work better.">Say All B_y:</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="mnemonic_widget">sayAllStyle</property>
+                                        <accessibility>
+                                          <relation type="label-for" target="sayAllStyle"/>
+                                        </accessibility>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkComboBox" id="sayAllStyle">
+                                        <property name="visible">True</property>
+                                        <property name="model">model2</property>
+                                        <accessibility>
+                                          <relation type="labelled-by" target="sayAllLabel"/>
+                                        </accessibility>
+                                        <signal name="changed" handler="sayAllStyleChanged"/>
+                                        <child>
+                                          <object class="GtkCellRendererText" id="renderer2"/>
+                                          <attributes>
+                                            <attribute name="text">0</attribute>
+                                          </attributes>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="padding">3</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="position">3</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
                               </object>
                               <packing>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
+                                <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkHBox" id="hbox39">
+                              <object class="GtkVBox" id="speechContextVBox">
                                 <property name="visible">True</property>
-                                <property name="spacing">3</property>
                                 <child>
-                                  <object class="GtkLabel" id="sayAllLabel">
+                                  <object class="GtkCheckButton" id="speakBlankLinesCheckButton">
+                                    <property name="label" translatable="yes">Speak blank lines</property>
                                     <property name="visible">True</property>
-                                    <property name="label" translatable="yes" comments="Translators: Say all by refers to the way that Orca will say (speak) an amount of text -- in particular, where Orca where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and  say all by line.  If Orca were speaking a work of fiction, it's probably best to do say all by sentence so it sound more natural. If Orca were speaking something like a page of computer commands, doing a say all by line would work better.">Say All B_y:</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
                                     <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">sayAllStyle</property>
-                                    <accessibility>
-                                      <relation type="label-for" target="sayAllStyle"/>
-                                    </accessibility>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
                                   </object>
                                   <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
                                     <property name="position">0</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkComboBox" id="sayAllStyle">
+                                  <object class="GtkCheckButton" id="enableSpeechIndentationCheckButton">
+                                    <property name="label" translatable="yes">Speak _indentation and justification</property>
                                     <property name="visible">True</property>
-                                    <property name="model">model2</property>
-                                    <accessibility>
-                                      <relation type="labelled-by" target="sayAllLabel"/>
-                                    </accessibility>
-                                    <signal name="changed" handler="sayAllStyleChanged"/>
-                                    <child>
-                                      <object class="GtkCellRendererText" id="renderer2"/>
-                                      <attributes>
-                                        <attribute name="text">0</attribute>
-                                      </attributes>
-                                    </child>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
                                   </object>
                                   <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">False</property>
-                                    <property name="padding">3</property>
                                     <property name="position">1</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="enableMnemonicSpeakingCheckButton">
+                                    <property name="label" translatable="yes">Spea_k object mnemonics</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
+                                  </object>
+                                  <packing>
+                                    <property name="position">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="enablePositionSpeakingCheckButton">
+                                    <property name="label" translatable="yes" comments="Translators: This checkbox toggles whether or not Orca says the child position (e.g., 'item 6 of 7').">Speak child p_osition</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
+                                  </object>
+                                  <packing>
+                                    <property name="position">3</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="enableTutorialMessagesCheckButton">
+                                    <property name="label" translatable="yes">Speak tutorial messages</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <signal name="toggled" handler="checkButtonToggled"/>
+                                  </object>
+                                  <packing>
+                                    <property name="position">4</property>
+                                  </packing>
+                                </child>
                               </object>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
+                                <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
                           <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
diff --git a/src/orca/orca.py b/src/orca/orca.py
index 8a44ce3..c1cf17c 100644
--- a/src/orca/orca.py
+++ b/src/orca/orca.py
@@ -306,7 +306,8 @@ def _onChildrenChanged(e):
         #
         try:
             if desktop.childCount == 0:
-                speech.speak(_("Goodbye."))
+                if not settings.onlySpeakDisplayedText:
+                    speech.speak(_("Goodbye."))
                 shutdown()
                 return
         except: # could be a CORBA.COMM_FAILURE
@@ -2121,7 +2122,8 @@ def main():
 
     try:
         message = _("Welcome to Orca.")
-        speech.speak(message, settings.voices.get(settings.SYSTEM_VOICE))
+        if not settings.onlySpeakDisplayedText:
+            speech.speak(message, settings.voices.get(settings.SYSTEM_VOICE))
         braille.displayMessage(message)
     except:
         debug.printException(debug.LEVEL_SEVERE)
diff --git a/src/orca/orca_gui_prefs.py b/src/orca/orca_gui_prefs.py
index 1132b35..4295417 100644
--- a/src/orca/orca_gui_prefs.py
+++ b/src/orca/orca_gui_prefs.py
@@ -1536,6 +1536,10 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         self.get_widget("speechSupportCheckButton").set_active(enable)
         self.get_widget("speechVbox").set_sensitive(enable)
 
+        enable = prefs["onlySpeakDisplayedText"]
+        self.get_widget("onlySpeakDisplayedTextCheckButton").set_active(enable)
+        self.get_widget("speechContextVBox").set_sensitive(not enable)
+
         if prefs["verbalizePunctuationStyle"] == \
                                settings.PUNCTUATION_STYLE_NONE:
             self.get_widget("noneButton").set_active(True)
@@ -1558,6 +1562,9 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         else:
             self.get_widget("cellSpeechButton").set_active(True)
 
+        self.get_widget("onlySpeakDisplayedTextCheckButton").set_active(
+            prefs["onlySpeakDisplayedText"])
+
         self.get_widget("enableSpeechIndentationCheckButton").set_active(\
             prefs["enableSpeechIndentation"])
 
@@ -2588,6 +2595,19 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
         self.prefsDict["enableSpeech"] = enable
         self.get_widget("speechVbox").set_sensitive(enable)
 
+    def onlySpeakDisplayedTextToggled(self, widget):
+        """Signal handler for the "toggled" signal for the GtkCheckButton
+        onlySpeakDisplayedText. In addition to updating the preferences,
+        set the sensitivity of the speechContextVBox.
+
+        Arguments:
+        - widget: the component that generated the signal.
+        """
+
+        enable = widget.get_active()
+        self.prefsDict["onlySpeakDisplayedText"] = enable
+        self.get_widget("speechContextVBox").set_sensitive(not enable)
+
     def speechSystemsChanged(self, widget):
         """Signal handler for the "changed" signal for the speechSystems
            GtkComboBox widget. The user has selected a different speech
diff --git a/src/orca/scripts/apps/evolution/speech_generator.py b/src/orca/scripts/apps/evolution/speech_generator.py
index ebdbebd..8fb50f9 100644
--- a/src/orca/scripts/apps/evolution/speech_generator.py
+++ b/src/orca/scripts/apps/evolution/speech_generator.py
@@ -27,6 +27,7 @@ __license__   = "LGPL"
 
 import pyatspi
 
+import orca.settings as settings
 import orca.speech_generator as speech_generator
 
 from orca.orca_i18n import _ # for gettext support
@@ -84,6 +85,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         # formatting string to address the headers associated with
         # toggle columns. That's really the difference here.]]]
         #
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(speech_generator.SYSTEM)
         try:
diff --git a/src/orca/scripts/apps/soffice/speech_generator.py b/src/orca/scripts/apps/soffice/speech_generator.py
index a641445..60565b9 100644
--- a/src/orca/scripts/apps/soffice/speech_generator.py
+++ b/src/orca/scripts/apps/soffice/speech_generator.py
@@ -178,6 +178,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         if that description is different from that of the name and
         label.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(speech_generator.SYSTEM)
         if obj.description:
@@ -375,6 +378,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         Returns an indication of how many characters are greater than the size
         of the spread sheet cell, or None if the message fits.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(speech_generator.SYSTEM)
         try:
diff --git a/src/orca/scripts/toolkits/Gecko/speech_generator.py b/src/orca/scripts/toolkits/Gecko/speech_generator.py
index bff614d..c9699b3 100644
--- a/src/orca/scripts/toolkits/Gecko/speech_generator.py
+++ b/src/orca/scripts/toolkits/Gecko/speech_generator.py
@@ -32,6 +32,7 @@ __license__   = "LGPL"
 import pyatspi
 
 import orca.rolenames as rolenames
+import orca.settings as settings
 import orca.speech_generator as speech_generator
 
 from orca.orca_i18n import _
@@ -285,6 +286,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         return result
 
     def _generateNumberOfChildren(self, obj, **args):
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(speech_generator.SYSTEM)
         role = args.get('role', obj.getRole())
@@ -416,12 +420,13 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
             # Finally add the role if it's not among the roles we don't
             # wish to speak.
             #
-            acss = self.voice(speech_generator.SYSTEM)
-            if not (role in dontSpeakRoles) and len(newResult):
-                roleInfo = rolenames.getSpeechForRoleName(parent)
-                if roleInfo:
-                    result.extend(acss)
-                    result.append(roleInfo)
+            if not settings.onlySpeakDisplayedText:
+                acss = self.voice(speech_generator.SYSTEM)
+                if not (role in dontSpeakRoles) and len(newResult):
+                    roleInfo = rolenames.getSpeechForRoleName(parent)
+                    if roleInfo:
+                        result.extend(acss)
+                        result.append(roleInfo)
 
             # If this object is an ARIA widget with STATE_REQUIRED, add
             # that. (Note that for the most part, the ARIA widget itself
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py b/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
index 453691e..7d1cd8a 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
@@ -84,6 +84,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         specifications) that represents the number of children the
         object has."""
 
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(speech_generator.SYSTEM)
         if obj and obj.getState().contains(pyatspi.STATE_EXPANDED) \
@@ -107,6 +110,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         object in a list.
         """
 
+        if settings.onlySpeakDisplayedText:
+            return []
+
         listObj = None
         if obj and obj.getRole() == pyatspi.ROLE_COMBO_BOX:
             allLists = self._script.utilities.descendantsWithRole(
diff --git a/src/orca/settings.py b/src/orca/settings.py
index 6147c14..5c8afb4 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -89,6 +89,7 @@ from orca_i18n import C_          # to provide qualified translatable strings
 userCustomizableSettings = [
     "orcaModifierKeys",
     "enableSpeech",
+    "onlySpeakDisplayedText",
     "speechServerFactory",
     "speechServerInfo",
     "voices",
@@ -364,6 +365,11 @@ enableSpeechCallbacks   = True
 #
 silenceSpeech           = False
 
+# If True, only text which is displayed on screen will be spoken
+# (roles, states, etc. will not be).
+#
+onlySpeakDisplayedText = False
+
 # Settings that apply to the particular speech engine to
 # use as well details on the default voices to use.
 #
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index bfb4268..937c0c0 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -172,6 +172,9 @@ class SpeechGenerator(generator.Generator):
         represent the description of the object, if that description
         is different from that of the name and label.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(SYSTEM)
         result = generator.Generator._generateDescription(self, obj, **args)
         if result:
@@ -201,6 +204,9 @@ class SpeechGenerator(generator.Generator):
         of a speech generator that we can update and the user can
         override.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         role = args.get('role', obj.getRole())
         if role != pyatspi.ROLE_PARAGRAPH:
@@ -214,6 +220,9 @@ class SpeechGenerator(generator.Generator):
         Note that a 'role' attribute in args will override the
         accessible role of the obj.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         role = args.get('role', obj.getRole())
@@ -277,6 +286,9 @@ class SpeechGenerator(generator.Generator):
         for check boxes. [[[WDW - should we return an empty array if
         we can guarantee we know this thing is not checkable?]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(STATE)
         result = generator.Generator._generateCheckedState(self, obj, **args)
         if result:
@@ -289,6 +301,9 @@ class SpeechGenerator(generator.Generator):
         tree node. If the object is not expandable, an empty array
         will be returned.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(STATE)
         result = generator.Generator._generateExpandableState(self, obj, **args)
         if result:
@@ -300,6 +315,9 @@ class SpeechGenerator(generator.Generator):
         represent the checked state of the menu item, only if it is
         checked. Otherwise, and empty array will be returned.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(STATE)
         result = generator.Generator.\
             _generateMenuItemCheckedState(self, obj, **args)
@@ -313,6 +331,9 @@ class SpeechGenerator(generator.Generator):
         the object.  This is typically for check boxes. If the object
         is not multiselectable, an empty array will be returned.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(STATE)
         if obj.getState().contains(pyatspi.STATE_MULTISELECTABLE):
@@ -331,6 +352,9 @@ class SpeechGenerator(generator.Generator):
         for check boxes. [[[WDW - should we return an empty array if
         we can guarantee we know this thing is not checkable?]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(STATE)
         result = generator.Generator._generateRadioState(self, obj, **args)
         if result:
@@ -343,6 +367,9 @@ class SpeechGenerator(generator.Generator):
         for check boxes. [[[WDW - should we return an empty array if
         we can guarantee we know this thing is not checkable?]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(STATE)
         result = generator.Generator._generateToggleState(self, obj, **args)
         if result:
@@ -655,6 +682,9 @@ class SpeechGenerator(generator.Generator):
         returned.  [[[WDW - I wonder if this string should be moved to
         settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(STATE)
         # If this is an icon within an layered pane or a table cell
@@ -700,6 +730,9 @@ class SpeechGenerator(generator.Generator):
         """Returns an array of strings (and possibly voice and audio
         specifications) reflecting the column number of a cell.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         col = -1
@@ -726,6 +759,9 @@ class SpeechGenerator(generator.Generator):
         """Returns an array of strings (and possibly voice and audio
         specifications) reflecting the row number of a cell.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         row = -1
@@ -754,6 +790,9 @@ class SpeechGenerator(generator.Generator):
         of its column number, the total number of columns, its row,
         and the total number of rows.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         if obj.parent.getRole() == pyatspi.ROLE_TABLE_CELL:
@@ -786,6 +825,9 @@ class SpeechGenerator(generator.Generator):
         specifications) indicating that this cell is the last cell
         in the table.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
@@ -1061,6 +1103,9 @@ class SpeechGenerator(generator.Generator):
         object is selected. [[[WDW - I wonder if this string should be
         moved to settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
 
@@ -1082,6 +1127,9 @@ class SpeechGenerator(generator.Generator):
         object is selected. [[[WDW - I wonder if this string should be
         moved to settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         try:
@@ -1112,6 +1160,9 @@ class SpeechGenerator(generator.Generator):
         - obj: the text object.
         - line: the string to check for spaces and tabs.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         acss = self.voice(SYSTEM)
         if not settings.enableSpeechIndentation:
             return []
@@ -1177,6 +1228,9 @@ class SpeechGenerator(generator.Generator):
         is typically set by Orca to be the previous object with
         focus.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         oldLevel = self._script.utilities.nodeLevel(args.get('priorObj', None))
@@ -1198,6 +1252,9 @@ class SpeechGenerator(generator.Generator):
         object.  This is typically for progress bars. [[[WDW - we
         should consider returning an empty array if there is no value.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         try:
@@ -1271,6 +1328,9 @@ class SpeechGenerator(generator.Generator):
         this doesn't apply?]]] [[[WDW - I wonder if this string should
         be moved to settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         childNodes = self._script.utilities.childNodes(obj)
@@ -1292,6 +1352,9 @@ class SpeechGenerator(generator.Generator):
         apply?]]] [[[WDW - I wonder if this string should be moved to
         settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         hasItems = False
@@ -1316,6 +1379,9 @@ class SpeechGenerator(generator.Generator):
         apply?]]] [[[WDW - I wonder if this string should be moved to
         settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         if not obj.childCount:
@@ -1332,6 +1398,9 @@ class SpeechGenerator(generator.Generator):
         and the position of the current item. This object will be an icon
         panel or a layered pane.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         # TODO - JD: Is there a better way to do this other than
@@ -1392,6 +1461,9 @@ class SpeechGenerator(generator.Generator):
         [[[WDW - I wonder if this string should be moved to
         settings.py.]]]
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         # If this application has more than one unfocused alert or
@@ -1509,6 +1581,9 @@ class SpeechGenerator(generator.Generator):
         specifications) that represent the relative position of an
         object in a group.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         position = -1
@@ -1542,6 +1617,9 @@ class SpeechGenerator(generator.Generator):
         specifications) that represent the relative position of an
         object in a list.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         position = -1
@@ -1705,6 +1783,9 @@ class SpeechGenerator(generator.Generator):
         specifications) that represent the accelerator for the object,
         or an empty array if no accelerator can be found.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         [mnemonic, shortcut, accelerator] = \
@@ -1720,6 +1801,9 @@ class SpeechGenerator(generator.Generator):
         specifications) that represent the mnemonic for the object, or
         an empty array if no mnemonic can be found.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         if settings.enableMnemonicSpeaking or args.get('forceMnemonic', False):
@@ -1749,6 +1833,9 @@ class SpeechGenerator(generator.Generator):
         tutorial generator.  A tutorial can be forced by setting the
         'forceTutorial' attribute of the args dictionary to True.
         """
+        if settings.onlySpeakDisplayedText:
+            return []
+
         result = []
         acss = self.voice(SYSTEM)
         alreadyFocused = args.get('alreadyFocused', False)



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