[orca] Fix for bgo#616618 - Node level and number of children not presented for Java trees



commit 2b8a2d22bd98f5bd9d7bd9db7efc0187f1be4470
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date:   Fri Apr 23 05:01:00 2010 -0400

    Fix for bgo#616618 - Node level and number of children not presented for Java trees

 .../toolkits/J2SE-access-bridge/formatting.py      |    9 ++-
 .../scripts/toolkits/J2SE-access-bridge/script.py  |   29 +++++---
 .../J2SE-access-bridge/speech_generator.py         |   26 +++++++-
 test/keystrokes/java/role_tree.py                  |   76 +++++++++-----------
 4 files changed, 86 insertions(+), 54 deletions(-)
---
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py b/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py
index 419cc51..16171af 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py
@@ -1,6 +1,7 @@
 # Orca
 #
 # Copyright 2006-2009 Sun Microsystems Inc.
+# Copyright 2010 Joanmarie Diggs
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,7 +23,8 @@
 __id__ = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc., "  \
+                "Copyright (c) 2010 Joanmarie Diggs"
 __license__   = "LGPL"
 
 import copy
@@ -39,8 +41,9 @@ formatting = {
         # states in order to tell whether they are expanded or collapsed.
         #
         pyatspi.ROLE_LABEL: {
-            'unfocused': '(displayedText or roleName) + expandableState',
-            'focused': 'expandableState'
+            'unfocused': '(displayedText or roleName) + expandableState + numberOfChildren',
+            'focused': 'expandableState + numberOfChildren',
+            'basicWhereAmI': '(displayedText or roleName) + expandableState + numberOfChildren + nodeLevel',
             },
     },
     'braille': {
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/script.py b/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
index bc2efd8..ba676c9 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
@@ -1,6 +1,7 @@
 # Orca
 #
 # Copyright 2006-2009 Sun Microsystems Inc.
+# Copyright 2010 Joanmarie Diggs
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -20,7 +21,8 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc., "  \
+                "Copyright (c) 2010 Joanmarie Diggs"
 __license__   = "LGPL"
 
 import pyatspi
@@ -120,16 +122,25 @@ class Script(default.Script):
         if not obj:
             return -1
 
-        treeLikeThing = self.getAncestor(obj,
-                                         [pyatspi.ROLE_TREE,
-                                          pyatspi.ROLE_TABLE,
-                                          pyatspi.ROLE_TREE_TABLE],
-                                         None)
-        if not treeLikeThing:
-            return -1
+        if not self._lastDescendantChangedSource:
+            return default.Script.getNodeLevel(self, obj)
+
+        # It would seem that Java is making multiple copies of accessibles
+        # and/or killing them frequently. This is messing up our ability to
+        # ascend the hierarchy. We need to see if we can find our clone and
+        # set obj to it before trying to get the node level.
+        #
+        items = self.findByRole(
+            self._lastDescendantChangedSource, obj.getRole())
+        for item in items:
+            if item.name == obj.name and self.isSameObject(item, obj):
+                obj = item
+                break
+        else:
+            return default.Script.getNodeLevel(self, obj)
 
         count = 0
-        while True:
+        while obj:
             state = obj.getState()
             if state.contains(pyatspi.STATE_EXPANDABLE) \
                or state.contains(pyatspi.STATE_COLLAPSED):
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 53cf162..79ca79f 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
@@ -1,6 +1,7 @@
 # Orca
 #
 # Copyright 2005-2009 Sun Microsystems Inc.
+# Copyright 2010 Joanmarie Diggs
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -20,7 +21,8 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc., " \
+                "Copyright (c) 2010 Joanmarie Diggs"
 __license__   = "LGPL"
 
 import pyatspi
@@ -28,6 +30,8 @@ import pyatspi
 import orca.settings as settings
 import orca.speech_generator as speech_generator
 
+from orca.orca_i18n import ngettext
+
 ########################################################################
 #                                                                      #
 # Speech Generator                                                     #
@@ -53,6 +57,26 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         del args['requireText']
         return result
 
+    def _generateNumberOfChildren(self, obj, **args):
+        """Returns an array of strings (and possibly voice and audio
+        specifications) that represents the number of children the
+        object has."""
+
+        result = []
+        if obj and obj.getState().contains(pyatspi.STATE_EXPANDED) \
+           and obj.getRole() == pyatspi.ROLE_LABEL and obj.childCount:
+            children = obj.childCount
+            # Translators: this is the number of items in a layered
+            # pane or table.
+            #
+            items = ngettext("%d item", "%d items", children) % children
+            result.append(items)
+        else:
+            result.extend(speech_generator.SpeechGenerator.\
+                          _generateNumberOfChildren(self, obj, **args))
+
+        return result
+
     def _generatePositionInList(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the relative position of an
diff --git a/test/keystrokes/java/role_tree.py b/test/keystrokes/java/role_tree.py
index a4e9aae..5dbc177 100644
--- a/test/keystrokes/java/role_tree.py
+++ b/test/keystrokes/java/role_tree.py
@@ -69,7 +69,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. Down Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application SwingSet2 Frame RootPane LayeredPane Tree Demo TabList Tree Demo Page ScrollPane Viewport Tree Music expanded TREE LEVEL 1'",
      "     VISIBLE:  'Music expanded TREE LEVEL 1', cursor=1",
-     "SPEECH OUTPUT: 'Music expanded tree level 1'"]))
+     "SPEECH OUTPUT: 'Music expanded 3 items tree level 1'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -80,9 +80,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "2. Down Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Classical collapsed'",
-     "     VISIBLE:  'Classical collapsed', cursor=1",
-     "SPEECH OUTPUT: 'Classical collapsed'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Classical collapsed TREE LEVEL 2'",
+     "     VISIBLE:  'Classical collapsed TREE LEVEL 2', cursor=1",
+     "SPEECH OUTPUT: 'Classical collapsed tree level 2'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -108,7 +108,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Right Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application Jazz expanded'",
      "     VISIBLE:  'Jazz expanded', cursor=1",
-     "SPEECH OUTPUT: 'expanded'"]))
+     "SPEECH OUTPUT: 'expanded 4 items'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -119,9 +119,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "5. Down Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Albert Ayler collapsed'",
-     "     VISIBLE:  'Albert Ayler collapsed', cursor=1",
-     "SPEECH OUTPUT: 'Albert Ayler collapsed'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Albert Ayler collapsed TREE LEVEL 3'",
+     "     VISIBLE:  'Albert Ayler collapsed TREE LEVE', cursor=1",
+     "SPEECH OUTPUT: 'Albert Ayler collapsed tree level 3'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -147,26 +147,20 @@ sequence.append(utils.AssertPresentationAction(
     "7. Right Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application Chet Baker expanded'",
      "     VISIBLE:  'Chet Baker expanded', cursor=1",
-     "SPEECH OUTPUT: 'expanded'"]))
+     "SPEECH OUTPUT: 'expanded 4 items'"]))
     
 ##########################################################################
-# [[[BUG 483219: JTree nodes don't show expanded or collapsed in braille]]]
-# [[[BUG 483221: When traversing jtree nodes the entire context is announced again and again]]]
-# Expected output when node is selected:
-# 
-# BRAILLE LINE:  'SwingSet2 Application SwingSet2 Frame RootPane LayeredPane Tree Demo TabList Tree Demo ScrollPane Viewport Tree Music Label Jazz Label Chet Baker Label Sings and Plays Label'
-#      VISIBLE:  'Sings and Plays Label', cursor=1
-# SPEECH OUTPUT: 'SwingSet2 application SwingSet2 frame Tree Demo tab list Tree Demo page Music label Jazz label Chet Baker label'
-# SPEECH OUTPUT: 'Sings and Plays label collapsed'
+# Expected output when node is expanded:
+#
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "8. Down Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Sings and Plays collapsed'",
-     "     VISIBLE:  'Sings and Plays collapsed', cursor=1",
-     "SPEECH OUTPUT: 'Sings and Plays collapsed'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Sings and Plays collapsed TREE LEVEL 4'",
+     "     VISIBLE:  'Sings and Plays collapsed TREE L', cursor=1",
+     "SPEECH OUTPUT: 'Sings and Plays collapsed tree level 4'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -218,7 +212,7 @@ sequence.append(utils.AssertPresentationAction(
     "12. Right Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application Grey December expanded'",
      "     VISIBLE:  'Grey December expanded', cursor=1",
-     "SPEECH OUTPUT: 'expanded'"]))
+     "SPEECH OUTPUT: 'expanded 9 items'"]))
     
 ########################################################################
 # Do a basic "Where Am I" via KP_Enter.
@@ -231,7 +225,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BUG? - Little detail - see bug 483222.",
      "BRAILLE LINE:  'SwingSet2 Application Grey December expanded'",
      "     VISIBLE:  'Grey December expanded', cursor=1",
-     "SPEECH OUTPUT: 'Grey December expanded'"]))
+     "SPEECH OUTPUT: 'Grey December expanded 9 items'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -242,9 +236,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "14. Down Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Grey December'",
-     "     VISIBLE:  'Grey December', cursor=1",
-     "SPEECH OUTPUT: 'Grey December'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Grey December TREE LEVEL 5'",
+     "     VISIBLE:  'Grey December TREE LEVEL 5', cursor=1",
+     "SPEECH OUTPUT: 'Grey December tree level 5'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -307,9 +301,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "19. Up Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Grey December'",
-     "     VISIBLE:  'Grey December', cursor=1",
-     "SPEECH OUTPUT: 'Grey December'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Grey December TREE LEVEL 5'",
+     "     VISIBLE:  'Grey December TREE LEVEL 5', cursor=1",
+     "SPEECH OUTPUT: 'Grey December tree level 5'"]))
 
 ##########################################################################
 # Expected output when node is selected:
@@ -322,7 +316,7 @@ sequence.append(utils.AssertPresentationAction(
     "20. Up Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application Grey December expanded'",
      "     VISIBLE:  'Grey December expanded', cursor=1",
-     "SPEECH OUTPUT: 'Grey December expanded'"]))
+     "SPEECH OUTPUT: 'Grey December expanded 9 items'"]))
     
 ##########################################################################
 # Expected output when node is collaped:
@@ -359,9 +353,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "23. Up Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Sings and Plays collapsed'",
-     "     VISIBLE:  'Sings and Plays collapsed', cursor=1",
-     "SPEECH OUTPUT: 'Sings and Plays collapsed'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Sings and Plays collapsed TREE LEVEL 4'",
+     "     VISIBLE:  'Sings and Plays collapsed TREE L', cursor=1",
+     "SPEECH OUTPUT: 'Sings and Plays collapsed tree level 4'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -374,7 +368,7 @@ sequence.append(utils.AssertPresentationAction(
     "24. Up Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application Chet Baker expanded'",
      "     VISIBLE:  'Chet Baker expanded', cursor=1",
-     "SPEECH OUTPUT: 'Chet Baker expanded'"]))
+     "SPEECH OUTPUT: 'Chet Baker expanded 4 items'"]))
     
 ##########################################################################
 # Expected output when node is collaped:
@@ -398,9 +392,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "26. Up Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Albert Ayler collapsed'",
-     "     VISIBLE:  'Albert Ayler collapsed', cursor=1",
-     "SPEECH OUTPUT: 'Albert Ayler collapsed'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Albert Ayler collapsed TREE LEVEL 3'",
+     "     VISIBLE:  'Albert Ayler collapsed TREE LEVE', cursor=1",
+     "SPEECH OUTPUT: 'Albert Ayler collapsed tree level 3'"]))
 
 ##########################################################################
 # Expected output when node is selected:
@@ -413,7 +407,7 @@ sequence.append(utils.AssertPresentationAction(
     "27. Up Arrow in the tree",
     ["BRAILLE LINE:  'SwingSet2 Application Jazz expanded'",
      "     VISIBLE:  'Jazz expanded', cursor=1",
-     "SPEECH OUTPUT: 'Jazz expanded'"]))
+     "SPEECH OUTPUT: 'Jazz expanded 4 items'"]))
 
 ##########################################################################
 # Expected output when node is collaped:
@@ -437,9 +431,9 @@ sequence.append(WaitAction("object:active-descendant-changed", None, None,
                            pyatspi.ROLE_TREE, 5000))
 sequence.append(utils.AssertPresentationAction(
     "29. Up Arrow in the tree",
-    ["BRAILLE LINE:  'SwingSet2 Application Classical collapsed'",
-     "     VISIBLE:  'Classical collapsed', cursor=1",
-     "SPEECH OUTPUT: 'Classical collapsed'"]))
+    ["BRAILLE LINE:  'SwingSet2 Application Classical collapsed TREE LEVEL 2'",
+     "     VISIBLE:  'Classical collapsed TREE LEVEL 2', cursor=1",
+     "SPEECH OUTPUT: 'Classical collapsed tree level 2'"]))
     
 ##########################################################################
 # Expected output when node is selected:
@@ -453,7 +447,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BUG? - Seems a bit chatty",
      "BRAILLE LINE:  'SwingSet2 Application SwingSet2 Frame RootPane LayeredPane Tree Demo TabList Tree Demo Page ScrollPane Viewport Tree Music expanded TREE LEVEL 1'",
      "     VISIBLE:  'Music expanded TREE LEVEL 1', cursor=1",
-     "SPEECH OUTPUT: 'SwingSet2 frame Tree Demo tab list Tree Demo page Music expanded tree level 1'"]))
+     "SPEECH OUTPUT: 'SwingSet2 frame Tree Demo tab list Tree Demo page Music expanded 3 items tree level 1'"]))
     
 ##########################################################################
 # Leave tree



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