[orca] Fix for bgo#538050 - Orca should announce the slide title, number, and count when Page Up/Page Down



commit 3a9f38250590b514d92ccf3479cfda31a98f300d
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date:   Mon May 17 16:44:43 2010 -0400

    Fix for bgo#538050 - Orca should announce the slide title, number, and count when Page Up/Page Down is pressed in Impress
    
    Note: You'll need a pretty recent version of OOo Impress to use this feature.
    Also note that Impress support is really just beginning in Orca. Compelling
    access is on it's way, but it's not quite here yet. Stay tuned!

 src/orca/scripts/apps/soffice/script.py           |   18 ++++
 src/orca/scripts/apps/soffice/script_utilities.py |  107 +++++++++++++++++++++
 2 files changed, 125 insertions(+), 0 deletions(-)
---
diff --git a/src/orca/scripts/apps/soffice/script.py b/src/orca/scripts/apps/soffice/script.py
index 4fd1729..aaf87a3 100644
--- a/src/orca/scripts/apps/soffice/script.py
+++ b/src/orca/scripts/apps/soffice/script.py
@@ -1675,6 +1675,24 @@ class Script(default.Script):
                 event.source.parent, orca_state.activeWindow):
             self.readMisspeltWord(event, event.source)
 
+        # Impress slide navigation.
+        #
+        if self.utilities.isInImpress(event.source) \
+           and self.utilities.isDrawingView(event.source):
+            title, position, count = \
+                self.utilities.slideTitleAndPosition(event.source)
+            if title:
+                title += "."
+
+            # Translators: this is an indication of the position of the
+            # focused Impress slide and the total number of slides in the
+            # presentation.
+            #
+            msg = _("slide %(position)d of %(count)d") % \
+                    {"position" : position, "count" : count}
+            msg = self.utilities.appendString(title, msg)
+            self.presentMessage(msg)
+
         default.Script.onNameChanged(self, event)
 
     def onFocus(self, event):
diff --git a/src/orca/scripts/apps/soffice/script_utilities.py b/src/orca/scripts/apps/soffice/script_utilities.py
index 6781f35..1d2da02 100644
--- a/src/orca/scripts/apps/soffice/script_utilities.py
+++ b/src/orca/scripts/apps/soffice/script_utilities.py
@@ -31,6 +31,7 @@ __license__   = "LGPL"
 import pyatspi
 
 import orca.debug as debug
+import orca.orca_state as orca_state
 import orca.script_utilities as script_utilities
 
 #############################################################################
@@ -188,6 +189,112 @@ class Utilities(script_utilities.Utilities):
 
     #########################################################################
     #                                                                       #
+    # Impress-Specific Utilities                                            #
+    #                                                                       #
+    #########################################################################
+
+    def drawingView(self, obj=orca_state.locusOfFocus):
+        """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 = filter(lambda o: ":" in o.name and "/" in o.name, docFrames)
+        if docFrame:
+            return docFrame[0]
+
+        return None
+
+    def isDrawingView(self, obj):
+        """Returns True if obj is the Impress Drawing View."""
+
+        if obj and obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
+            return (":" in obj.name and "/" in obj.name)
+
+        return False
+
+    def isInImpress(self, obj=orca_state.locusOfFocus):
+        """Returns True if obj is in OOo Impress."""
+
+        # Having checked English, Spanish, and Arabic, it would seem
+        # that the Frame name will end with "Impress", unlocalized.
+        #
+        if obj:
+            topLevel = self.topLevelObject(obj)
+            if topLevel and topLevel.name.endswith("Impress"):
+                return True
+
+        return False
+
+    def slideAndTaskPanes(self, obj=orca_state.locusOfFocus):
+        """Attempts to locate the Impress slide pane and task pane."""
+
+        drawingView = self.drawingView(obj)
+        if not drawingView:
+            return None, None
+
+        parent = drawingView.parent
+        if parent:
+            parent = parent.parent
+        if not parent:
+            return None, None
+
+        panes = self.descendantsWithRole(parent, pyatspi.ROLE_SPLIT_PANE)
+        if not panes:
+            return None, None
+
+        slidePane = taskPane = None
+        if self.descendantsWithRole(panes[0], pyatspi.ROLE_DOCUMENT_FRAME):
+            slidePane = panes[0]
+            if len(panes) == 2:
+                taskPane = panes[1]
+        else:
+            taskPane = panes[0]
+            if len(panes) == 2:
+                slidePane = panes[1]
+
+        return slidePane, taskPane
+
+    def slideTitleAndPosition(self, obj):
+        """Attempts to obtain the title, position of the slide which contains
+        or is represented by obj.
+
+        Returns a (title, position, count) tuple.
+        """
+
+        if obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
+            dv = obj
+        else:
+            dv = self.ancestorWithRole(obj, [pyatspi.ROLE_DOCUMENT_FRAME], [])
+
+        if not dv or not self.isDrawingView(dv):
+            return "", 0, 0
+
+        positionAndCount = dv.name.split(":")[1]
+        position, count = positionAndCount.split("/")
+        title = ""
+        for child in dv:
+            if not child.childCount:
+                continue
+            # We want an actual Title.
+            #
+            if child.name.startswith("ImpressTitle"):
+                title = self.displayedText(child[0])
+                break
+            # But we'll live with a Subtitle if we can't find a title.
+            # Unlike Titles, a single subtitle can be made up of multiple
+            # accessibles.
+            #
+            elif child.name.startswith("ImpressSubtitle"):
+                for line in child:
+                    title = self.appendString(title, self.displayedText(line))
+
+        return title, int(position), int(count)
+
+    #########################################################################
+    #                                                                       #
     # Utilities for working with the accessible text interface              #
     #                                                                       #
     #########################################################################



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