[orca] Use pyatspi's method for finding descendants rather than our own



commit b1c3c110e407a22c3f054e60e2ff33cbd1191778
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Tue Mar 17 21:27:44 2015 -0400

    Use pyatspi's method for finding descendants rather than our own

 src/orca/script_utilities.py                       |   55 +-------------------
 src/orca/scripts/apps/Instantbird/chat.py          |    4 +-
 src/orca/scripts/apps/Instantbird/script.py        |    6 +--
 src/orca/scripts/apps/ekiga/script.py              |    4 +-
 src/orca/scripts/apps/empathy/script.py            |    6 +--
 src/orca/scripts/apps/gajim/script.py              |    6 +--
 src/orca/scripts/apps/liferea/script.py            |    4 +-
 .../scripts/apps/notification-daemon/script.py     |    5 +-
 src/orca/scripts/apps/pidgin/script.py             |    6 +--
 src/orca/scripts/apps/soffice/script.py            |   23 +++++---
 src/orca/scripts/apps/soffice/script_utilities.py  |   19 +++----
 .../J2SE-access-bridge/script_utilities.py         |   45 ++---------------
 .../J2SE-access-bridge/speech_generator.py         |    4 +-
 13 files changed, 47 insertions(+), 140 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 5170c68..473631f 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -113,42 +113,6 @@ class Utilities:
         return None
 
     @staticmethod
-    def allDescendants(root, onlyShowing=True):
-        """Returns a list of all objects under the given root.  Objects
-        are returned in no particular order - this function does a simple
-        tree traversal, ignoring the children of objects which report the
-        MANAGES_DESCENDANTS state.
-
-        Arguments:
-        - root: the Accessible object to traverse
-        - onlyShowing: examine only those objects that are SHOWING
-
-        Returns: a list of all objects under the specified object
-        """
-
-        if root and root.childCount <= 0:
-            return []
-
-        objlist = []
-        for i, child in enumerate(root):
-            debug.println(debug.LEVEL_FINEST,
-                          "Script.allDescendants looking at child %d" % i)
-            try:
-                state = child.getState()
-            except:
-                debug.println(debug.LEVEL_FINEST, "Error getting state")
-                continue
-
-            if not onlyShowing \
-               or (onlyShowing and state.contains(pyatspi.STATE_SHOWING)):
-                objlist.append(child)
-                if not state.contains(pyatspi.STATE_MANAGES_DESCENDANTS) \
-                   and child.childCount > 0:
-                    objlist.extend(Utilities.allDescendants(child, onlyShowing))
-
-        return objlist
-
-    @staticmethod
     def ancestorWithRole(obj, ancestorRoles, stopRoles):
         """Returns the object of the specified roles which contains the
         given object, or None if the given object is not contained within
@@ -387,22 +351,6 @@ class Utilities:
 
         return defaultButton
 
-    @staticmethod
-    def descendantsWithRole(root, role, onlyShowing=True):
-        """Returns a list of all objects of a specific role beneath the
-        given root.
-
-        Arguments:
-        - root: the Accessible object to traverse
-        - role: the string describing the Accessible role of the object
-        - onlyShowing: examine only those objects that are SHOWING
-
-        Returns a list of descendants of the root that are of the given role.
-        """
-
-        allObjs = Utilities.allDescendants(root, onlyShowing)
-        return [o for o in allObjs if o.getRole() == role]
-
     def displayedLabel(self, obj):
         """If there is an object labelling the given object, return the
         text being displayed for the object labelling this object.
@@ -1397,7 +1345,8 @@ class Utilities:
         Returns a list of unrelated labels under the given root.
         """
 
-        allLabels = self.descendantsWithRole(root, pyatspi.ROLE_LABEL, onlyShowing)
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_LABEL
+        allLabels = pyatspi.findAllDescendants(root, hasRole)
         try:
             labels = [x for x in allLabels if not x.getRelationSet()]
             labels = [x for x in labels if x.parent and x.name != x.parent.name]
diff --git a/src/orca/scripts/apps/Instantbird/chat.py b/src/orca/scripts/apps/Instantbird/chat.py
index ef27458..dbb262a 100644
--- a/src/orca/scripts/apps/Instantbird/chat.py
+++ b/src/orca/scripts/apps/Instantbird/chat.py
@@ -72,8 +72,8 @@ class Chat(chat.Chat):
         #
         if event.source.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
             bubble = event.source[event.detail1]
-            paragraphs = self._script.utilities.descendantsWithRole(
-                bubble, pyatspi.ROLE_PARAGRAPH)
+            hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_PARAGRAPH
+            paragraphs = pyatspi.findAllDescendants(bubble, hasRole)
 
             # If the user opted the non-default, "simple" appearance, then this
             # might not be a bubble at all, but a paragraph.
diff --git a/src/orca/scripts/apps/Instantbird/script.py b/src/orca/scripts/apps/Instantbird/script.py
index b0db7fa..a80265d 100644
--- a/src/orca/scripts/apps/Instantbird/script.py
+++ b/src/orca/scripts/apps/Instantbird/script.py
@@ -204,8 +204,6 @@ class Script(Gecko.Script):
         # Hack to "tickle" the accessible hierarchy. Otherwise, the
         # events we need to present text added to the chatroom are
         # missing.
-        #
-        allPageTabs = self.utilities.descendantsWithRole(
-            event.source, pyatspi.ROLE_PAGE_TAB)
-
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_PAGE_TAB
+        allPageTabs = pyatspi.findAllDescendants(event.source, hasRole)
         default.Script.onWindowActivated(self, event)
diff --git a/src/orca/scripts/apps/ekiga/script.py b/src/orca/scripts/apps/ekiga/script.py
index 59a07d3..05da811 100644
--- a/src/orca/scripts/apps/ekiga/script.py
+++ b/src/orca/scripts/apps/ekiga/script.py
@@ -89,8 +89,8 @@ class Script(default.Script):
         """
 
         if event.source.getRole() == pyatspi.ROLE_SPLIT_PANE:
-            textObjects = self.utilities.descendantsWithRole(
-                event.source, pyatspi.ROLE_TEXT)
+            hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_TEXT
+            textObjects = pyatspi.findAllDescendants(event.source, hasRole)
             return
 
         default.Script.onValueChanged(self, event)
diff --git a/src/orca/scripts/apps/empathy/script.py b/src/orca/scripts/apps/empathy/script.py
index c001424..592bd75 100644
--- a/src/orca/scripts/apps/empathy/script.py
+++ b/src/orca/scripts/apps/empathy/script.py
@@ -122,10 +122,8 @@ class Script(gtk.Script):
         # Hack to "tickle" the accessible hierarchy. Otherwise, the
         # events we need to present text added to the chatroom are
         # missing.
-        #
-        allPageTabs = self.utilities.descendantsWithRole(
-            event.source, pyatspi.ROLE_PAGE_TAB)
-
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_PAGE_TAB
+        allPageTabs = pyatspi.findAllDescendants(event.source, hasRole)
         gtk.Script.onWindowActivated(self, event)
 
     def onValueChanged(self, event):
diff --git a/src/orca/scripts/apps/gajim/script.py b/src/orca/scripts/apps/gajim/script.py
index f36dff9..6b87d60 100644
--- a/src/orca/scripts/apps/gajim/script.py
+++ b/src/orca/scripts/apps/gajim/script.py
@@ -97,8 +97,6 @@ class Script(default.Script):
         # Hack to "tickle" the accessible hierarchy. Otherwise, the
         # events we need to present text added to the chatroom are
         # missing.
-        #
-        allPageTabs = self.utilities.descendantsWithRole(
-            event.source, pyatspi.ROLE_PAGE_TAB)
-
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_PAGE_TAB
+        allPageTabs = pyatspi.findAllDescendants(event.source, hasRole)
         default.Script.onWindowActivated(self, event)
diff --git a/src/orca/scripts/apps/liferea/script.py b/src/orca/scripts/apps/liferea/script.py
index d1b2642..0ff22f0 100644
--- a/src/orca/scripts/apps/liferea/script.py
+++ b/src/orca/scripts/apps/liferea/script.py
@@ -143,8 +143,8 @@ class Script(default.Script):
         if orca_state.locusOfFocus.getRole() == \
                                         pyatspi.ROLE_TABLE_COLUMN_HEADER:
             table = event.source.parent
-            cells = self.utilities.descendantsWithRole(
-                table, pyatspi.ROLE_TABLE_CELL)
+            hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_CELL
+            cells = pyatspi.findAllDescendants(event.source, hasRole)
             eventsynthesizer.clickObject(cells[1], 1)
 
         default.Script.locusOfFocusChanged(self, event, 
diff --git a/src/orca/scripts/apps/notification-daemon/script.py 
b/src/orca/scripts/apps/notification-daemon/script.py
index 5c229e0..ebe4a06 100644
--- a/src/orca/scripts/apps/notification-daemon/script.py
+++ b/src/orca/scripts/apps/notification-daemon/script.py
@@ -43,7 +43,8 @@ class Script(default.Script):
     def onWindowCreated(self, event):
         """Callback for window:create accessibility events."""
 
-        a = self.utilities.descendantsWithRole(event.source, pyatspi.ROLE_LABEL)
-        texts = [self.utilities.displayedText(acc) for acc in a]
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_LABEL
+        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)
diff --git a/src/orca/scripts/apps/pidgin/script.py b/src/orca/scripts/apps/pidgin/script.py
index 0578ccb..e89901d 100644
--- a/src/orca/scripts/apps/pidgin/script.py
+++ b/src/orca/scripts/apps/pidgin/script.py
@@ -188,10 +188,8 @@ class Script(GAIL.Script):
         # Hack to "tickle" the accessible hierarchy. Otherwise, the
         # events we need to present text added to the chatroom are
         # missing.
-        #
-        allPageTabs = self.utilities.descendantsWithRole(
-            event.source, pyatspi.ROLE_PAGE_TAB)
-
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_PAGE_TAB
+        allPageTabs = pyatspi.findAllDescendants(event.source, hasRole)
         GAIL.Script.onWindowActivated(self, event)
 
     def onExpandedChanged(self, event):
diff --git a/src/orca/scripts/apps/soffice/script.py b/src/orca/scripts/apps/soffice/script.py
index 4f994c3..8f9fe03 100644
--- a/src/orca/scripts/apps/soffice/script.py
+++ b/src/orca/scripts/apps/soffice/script.py
@@ -522,8 +522,21 @@ class Script(default.Script):
         wind up reading the word or not).
         """
 
-        paragraph = self.utilities.descendantsWithRole(
-            pane, pyatspi.ROLE_PARAGRAPH)
+        def isMatch(obj):
+            if not (obj and obj.getRole() == pyatspi.ROLE_PARAGRAPH):
+                return False
+
+            if not obj.getState().contains(pyatspi.STATE_EDITABLE):
+                return False
+
+            try:
+                text = obj.queryText()
+            except:
+                return False
+
+            return text.characterCount > 0
+
+        paragraph = pyatspi.findAllDescendants(pane, isMatch)
 
         # If there is not exactly one paragraph, this isn't the spellcheck
         # dialog.
@@ -543,12 +556,6 @@ class Script(default.Script):
             if not textLength:
                 return False
 
-        # If the text here is not editable, this isn't the spellcheck
-        # dialog.
-        #
-        if not paragraph[0].getState().contains(pyatspi.STATE_EDITABLE):
-            return False
-
         # Determine which word is the misspelt word. This word will have
         # non-default text attributes associated with it.
         #
diff --git a/src/orca/scripts/apps/soffice/script_utilities.py 
b/src/orca/scripts/apps/soffice/script_utilities.py
index 0e3508f..1f1bc09 100644
--- a/src/orca/scripts/apps/soffice/script_utilities.py
+++ b/src/orca/scripts/apps/soffice/script_utilities.py
@@ -519,15 +519,7 @@ class Utilities(script_utilities.Utilities):
         """Attempts to locate the Impress drawing view, which is the
         area in which slide editing occurs."""
 
-        # TODO - JD: We should probably add this to the generatorCache.
-        #
-        docFrames = self.descendantsWithRole(
-            self.topLevelObject(obj), pyatspi.ROLE_DOCUMENT_FRAME)
-        docFrame = [o for o in docFrames if ":" in o.name and "/" in o.name]
-        if docFrame:
-            return docFrame[0]
-
-        return None
+        return pyatspi.findDescendant(self.topLevelObject(obj), self.isDrawingView)
 
     def isDrawingView(self, obj):
         """Returns True if obj is the Impress Drawing View."""
@@ -545,7 +537,8 @@ class Utilities(script_utilities.Utilities):
         #
         if obj:
             topLevel = self.topLevelObject(obj)
-            if topLevel and topLevel.name.endswith("Impress"):
+            if topLevel and not self.isZombie(topLevel) \
+               and topLevel.name.endswith("Impress"):
                 return True
 
         return False
@@ -563,12 +556,14 @@ class Utilities(script_utilities.Utilities):
         if not parent:
             return None, None
 
-        panes = self.descendantsWithRole(parent, pyatspi.ROLE_SPLIT_PANE)
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_SPLIT_PANE
+        panes = pyatspi.findAllDescendants(parent, hasRole)
         if not panes:
             return None, None
 
         slidePane = taskPane = None
-        if self.descendantsWithRole(panes[0], pyatspi.ROLE_DOCUMENT_FRAME):
+        hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_DOCUMENT_FRAME
+        if pyatspi.findAllDescendants(panes[0], hasRole):
             slidePane = panes[0]
             if len(panes) == 2:
                 taskPane = panes[1]
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/script_utilities.py 
b/src/orca/scripts/toolkits/J2SE-access-bridge/script_utilities.py
index 9538da0..8a9ebff 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/script_utilities.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/script_utilities.py
@@ -111,7 +111,10 @@ class Utilities(script_utilities.Utilities):
         -obj: the Accessible object
         """
 
-        newObj = self.validObj(self._script.lastDescendantChangedSource, obj)
+        newObj = obj
+        if newObj and self.isZombie(newObj):
+            newObj = self.findReplicant(self._script.lastDescendantChangedSource, obj)
+
         if not newObj:
             return script_utilities.Utilities.nodeLevel(self, obj)
 
@@ -127,43 +130,3 @@ class Utilities(script_utilities.Utilities):
                 break
 
         return count - 1
-
-    def validObj(self, rootObj, obj, onlyShowing=True):
-        """Attempts to convert an older copy of an accessible into the
-        current, active version. We need to do this in order to ascend
-        the hierarchy.
-
-        Arguments:
-        - rootObj: the top-most ancestor of interest
-        - obj: the old object we're attempting to replace
-        - onlyShowing: whether or not we should limit matches to those
-          which have STATE_SHOWING
-
-         Returns an accessible replacement for obj if one can be found;
-         otherwise, None.
-         """
-
-        if not (obj and rootObj):
-            return None
-
-        items = self.descendantsWithRole(rootObj, obj.getRole(), onlyShowing)
-        for item in items:
-            if item.name == obj.name \
-               and self.isSameObject(item, obj):
-                return item
-
-        return None
-
-    #########################################################################
-    #                                                                       #
-    # Utilities for working with the accessible text interface              #
-    #                                                                       #
-    #########################################################################
-
-
-
-    #########################################################################
-    #                                                                       #
-    # Miscellaneous Utilities                                               #
-    #                                                                       #
-    #########################################################################
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 baab387..108e6dc 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
@@ -111,8 +111,8 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
 
         listObj = None
         if obj and obj.getRole() == pyatspi.ROLE_COMBO_BOX:
-            allLists = self._script.utilities.descendantsWithRole(
-                obj, pyatspi.ROLE_LIST, False)
+            hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_LIST
+            allLists = pyatspi.findAllDescendants(obj, hasRole)
             if len(allLists) == 1:
                 listObj = allLists[0]
 


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