[orca] Add and use methods to get and set the caret context



commit 261dd97b06919ff8a4e35a713a781d54534cb71c
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Tue Jun 9 19:42:03 2015 -0400

    Add and use methods to get and set the caret context

 src/orca/scripts/apps/epiphany/script.py           |    2 +-
 .../toolkits/Gecko/structural_navigation.py        |   18 ----
 src/orca/scripts/toolkits/WebKitGtk/Makefile.am    |    3 +-
 src/orca/scripts/toolkits/WebKitGtk/script.py      |   96 +++++++++-----------
 .../scripts/toolkits/WebKitGtk/script_utilities.py |   25 +++++
 src/orca/structural_navigation.py                  |   62 ++-----------
 6 files changed, 78 insertions(+), 128 deletions(-)
---
diff --git a/src/orca/scripts/apps/epiphany/script.py b/src/orca/scripts/apps/epiphany/script.py
index fc31f94..9e4a423 100644
--- a/src/orca/scripts/apps/epiphany/script.py
+++ b/src/orca/scripts/apps/epiphany/script.py
@@ -41,7 +41,7 @@ class Script(WebKitGtk.Script):
 
         gtk.Script.onWindowActivated(self, event)
 
-        obj, offset = self._lastCaretContext
+        obj, offset = self.utilities.getCaretContext()
         if obj:
             orca.setLocusOfFocus(None, obj)
 
diff --git a/src/orca/scripts/toolkits/Gecko/structural_navigation.py 
b/src/orca/scripts/toolkits/Gecko/structural_navigation.py
index 4287720..6766ddd 100644
--- a/src/orca/scripts/toolkits/Gecko/structural_navigation.py
+++ b/src/orca/scripts/toolkits/Gecko/structural_navigation.py
@@ -52,14 +52,6 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
     #                                                                   #
     #####################################################################
 
-    def getCurrentObject(self):
-        """Returns the current object -- normally, the locusOfFocus. But
-        in the case of Gecko, that doesn't always work.
-        """
-
-        [obj, offset] = self._script.utilities.getCaretContext()
-        return obj
-
     def _findPreviousObject(self, obj, stopAncestor):
         """Finds the object prior to this one, where the tree we're
         dealing with is a DOM and 'prior' means the previous object
@@ -101,16 +93,6 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
 
         return self._script.utilities.documentFrame()
 
-    def _isInDocument(self, obj):
-        """Returns True of the object is inside of the document."""
-
-        return self._script.utilities.inDocumentContent(obj)
-
-    def _setCaretPosition(self, obj, characterOffset):
-        """Sets the caret at the specified offset within obj."""
-
-        self._script.utilities.setCaretPosition(obj, characterOffset)
-
     #####################################################################
     #                                                                   #
     # Methods for presenting objects                                    #
diff --git a/src/orca/scripts/toolkits/WebKitGtk/Makefile.am b/src/orca/scripts/toolkits/WebKitGtk/Makefile.am
index f769e6c..dee115b 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/Makefile.am
+++ b/src/orca/scripts/toolkits/WebKitGtk/Makefile.am
@@ -3,7 +3,6 @@ orca_python_PYTHON = \
        braille_generator.py \
        script.py \
        speech_generator.py \
-       script_utilities.py \
-       structural_navigation.py
+       script_utilities.py
 
 orca_pythondir=$(pkgpythondir)/scripts/toolkits/WebKitGtk
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script.py b/src/orca/scripts/toolkits/WebKitGtk/script.py
index 89c01c4..795f9cd 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script.py
@@ -42,8 +42,8 @@ import orca.settings_manager as settings_manager
 import orca.speechserver as speechserver
 import orca.orca_state as orca_state
 import orca.speech as speech
+import orca.structural_navigation as structural_navigation
 
-from .structural_navigation import StructuralNavigation
 from .braille_generator import BrailleGenerator
 from .speech_generator import SpeechGenerator
 from .script_utilities import Utilities
@@ -58,8 +58,6 @@ _settingsManager = settings_manager.getManager()
 
 class Script(default.Script):
 
-    CARET_NAVIGATION_KEYS = ['Left', 'Right', 'Up', 'Down', 'Home', 'End']
-
     def __init__(self, app):
         """Creates a new script for WebKitGtk applications.
 
@@ -144,34 +142,34 @@ class Script(default.Script):
         """Returns the 'structural navigation' class for this script."""
 
         types = self.getEnabledStructuralNavigationTypes()
-        return StructuralNavigation(self, types, True)
+        return structural_navigation.StructuralNavigation(self, types, True)
 
     def getEnabledStructuralNavigationTypes(self):
         """Returns a list of the structural navigation object types
         enabled in this script."""
 
-        enabledTypes = [StructuralNavigation.BLOCKQUOTE,
-                        StructuralNavigation.BUTTON,
-                        StructuralNavigation.CHECK_BOX,
-                        StructuralNavigation.CHUNK,
-                        StructuralNavigation.COMBO_BOX,
-                        StructuralNavigation.ENTRY,
-                        StructuralNavigation.FORM_FIELD,
-                        StructuralNavigation.HEADING,
-                        StructuralNavigation.LANDMARK,
-                        StructuralNavigation.LINK,
-                        StructuralNavigation.LIST,
-                        StructuralNavigation.LIST_ITEM,
-                        StructuralNavigation.LIVE_REGION,
-                        StructuralNavigation.PARAGRAPH,
-                        StructuralNavigation.RADIO_BUTTON,
-                        StructuralNavigation.SEPARATOR,
-                        StructuralNavigation.TABLE,
-                        StructuralNavigation.TABLE_CELL,
-                        StructuralNavigation.UNVISITED_LINK,
-                        StructuralNavigation.VISITED_LINK]
-
-        return enabledTypes
+        return [structural_navigation.StructuralNavigation.BLOCKQUOTE,
+                structural_navigation.StructuralNavigation.BUTTON,
+                structural_navigation.StructuralNavigation.CHECK_BOX,
+                structural_navigation.StructuralNavigation.CHUNK,
+                structural_navigation.StructuralNavigation.CLICKABLE,
+                structural_navigation.StructuralNavigation.COMBO_BOX,
+                structural_navigation.StructuralNavigation.ENTRY,
+                structural_navigation.StructuralNavigation.FORM_FIELD,
+                structural_navigation.StructuralNavigation.HEADING,
+                structural_navigation.StructuralNavigation.IMAGE,
+                structural_navigation.StructuralNavigation.LANDMARK,
+                structural_navigation.StructuralNavigation.LINK,
+                structural_navigation.StructuralNavigation.LIST,
+                structural_navigation.StructuralNavigation.LIST_ITEM,
+                structural_navigation.StructuralNavigation.LIVE_REGION,
+                structural_navigation.StructuralNavigation.PARAGRAPH,
+                structural_navigation.StructuralNavigation.RADIO_BUTTON,
+                structural_navigation.StructuralNavigation.SEPARATOR,
+                structural_navigation.StructuralNavigation.TABLE,
+                structural_navigation.StructuralNavigation.TABLE_CELL,
+                structural_navigation.StructuralNavigation.UNVISITED_LINK,
+                structural_navigation.StructuralNavigation.VISITED_LINK]
 
     def getUtilities(self):
         """Returns the utilites for this script."""
@@ -179,16 +177,14 @@ class Script(default.Script):
         return Utilities(self)
 
     def onCaretMoved(self, event):
-        """Called whenever the caret moves.
-
-        Arguments:
-        - event: the Event
-        """
+        """Callback for object:text-caret-moved accessibility events."""
 
         if self._inSayAll:
             return
 
-        self._lastCaretContext = event.source, event.detail1
+        if not self.utilities.isWebKitGtk(event.source):
+            super().onCaretMoved(event)
+            return
 
         lastKey, mods = self.utilities.lastKeyAndModifiers()
         if lastKey in ['Tab', 'ISO_Left_Tab']:
@@ -201,9 +197,8 @@ class Script(default.Script):
             self.updateBraille(event.source)
             return
 
-        orca.setLocusOfFocus(event, event.source, False)
-
-        default.Script.onCaretMoved(self, event)
+        self.utilities.setCaretContext(event.source, event.detail1)
+        super().onCaretMoved(event)
 
     def onDocumentReload(self, event):
         """Callback for document:reload accessibility events."""
@@ -223,7 +218,7 @@ class Script(default.Script):
         # is grabbed rather than set the caret at the start. But for simple
         # content in both Yelp and Epiphany this is alright for now.
         obj, offset = self.utilities.setCaretAtStart(event.source)
-        orca.setLocusOfFocus(event, obj, False)
+        self.utilities.setCaretContext(obj, offset)
 
         self.updateBraille(obj)
         if _settingsManager.getSetting('sayAllOnLoad') \
@@ -239,38 +234,29 @@ class Script(default.Script):
     def onFocusedChanged(self, event):
         """Callback for object:state-changed:focused accessibility events."""
 
-        if self._inSayAll:
+        if self._inSayAll or not event.detail1:
             return
 
-        obj = event.source
-        role = obj.getRole()
-        self._lastCaretContext = obj, -1
-
-        if role == pyatspi.ROLE_LIST_ITEM and obj.childCount:
+        if not self.utilities.isWebKitGtk(event.source):
+            super().onFocusedChanged(event)
             return
 
-        widgetRoles = [pyatspi.ROLE_MENU,
-                       pyatspi.ROLE_MENU_ITEM,
-                       pyatspi.ROLE_LIST_ITEM,
-                       pyatspi.ROLE_RADIO_BUTTON]
-        if role in widgetRoles:
-            default.Script.onFocusedChanged(self, event)
+        contextObj, offset = self.utilities.getCaretContext()
+        if event.source == contextObj:
             return
 
+        obj = event.source
+        role = obj.getRole()
         textRoles = [pyatspi.ROLE_HEADING,
                      pyatspi.ROLE_PANEL,
                      pyatspi.ROLE_PARAGRAPH,
                      pyatspi.ROLE_SECTION,
                      pyatspi.ROLE_TABLE_CELL]
-        if role in textRoles:
+        if role in textRoles \
+           or (role == pyatspi.ROLE_LIST_ITEM and obj.childCount):
             return
 
-        if not (role == pyatspi.ROLE_LINK and obj.childCount):
-            lastKey, mods = self.utilities.lastKeyAndModifiers()
-            if lastKey in self.CARET_NAVIGATION_KEYS:
-                return
-
-        default.Script.onFocusedChanged(self, event)
+        super().onFocusedChanged(event)
 
     def onBusyChanged(self, event):
         """Callback for object:state-changed:busy accessibility events."""
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py 
b/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
index 850b40a..a4aefe3 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
@@ -32,6 +32,8 @@ import re
 
 import orca.script_utilities as script_utilities
 import orca.keybindings as keybindings
+import orca.orca as orca
+import orca.orca_state as orca_state
 
 #############################################################################
 #                                                                           #
@@ -61,6 +63,25 @@ class Utilities(script_utilities.Utilities):
             return False
         return attrs.get('toolkit', '') == 'WebKitGtk'
 
+    def getCaretContext(self):
+        # TODO - JD: This is private, but it's only here temporarily until we
+        # have the shared web content support.
+        obj, offset = self._script._lastCaretContext
+        if not obj and self.isWebKitGtk(orca_state.locusOfFocus):
+            obj, offset = super().getCaretContext()
+
+        return obj, offset
+
+    def setCaretContext(self, obj, offset):
+        # TODO - JD: This is private, but it's only here temporarily until we
+        # have the shared web content support.
+        self._script._lastCaretContext = obj, offset
+        orca.setLocusOfFocus(None, obj, notifyScript=False)
+
+    def setCaretPosition(self, obj, offset):
+        self.setCaretContext(obj, offset)
+        self.setCaretOffset(obj, offset)
+
     def isReadOnlyTextArea(self, obj):
         """Returns True if obj is a text entry area that is read only."""
 
@@ -276,3 +297,7 @@ class Utilities(script_utilities.Utilities):
 
     def treatAsBrowser(self, obj):
         return self.isEmbeddedDocument(obj)
+
+    def inDocumentContent(self, obj=None):
+        obj = obj or orca_state.locusOfFocus
+        return self.isWebKitGtk(obj)
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 06bd3fc..91426c3 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -370,7 +370,7 @@ class StructuralNavigationObject:
             script.presentMessage(title)
             return
 
-        currentObject = self.structuralNavigation.getCurrentObject()
+        currentObject, offset = script.utilities.getCaretContext()
         try:
             index = objects.index(currentObject)
         except:
@@ -432,7 +432,7 @@ class StructuralNavigationObject:
                 script.presentMessage(title)
                 return
 
-            currentObject = self.structuralNavigation.getCurrentObject()
+            currentObject, offset = script.utilities.getCaretContext()
             try:
                 index = objects.index(currentObject)
             except:
@@ -456,8 +456,8 @@ class StructuralNavigationObject:
         """
 
         def goCell(script, inputEvent):
-            thisCell = self.structuralNavigation.getCellForObj(\
-                self.structuralNavigation.getCurrentObject())
+            obj, offset = script.utilities.getCaretContext()
+            thisCell = self.structuralNavigation.getCellForObj(obj)
             currentCoordinates = \
                 self.structuralNavigation.getCellCoordinates(thisCell)
             if direction == "Left":
@@ -845,8 +845,8 @@ class StructuralNavigation:
           is needed and passed in as arg.
         """
 
-        obj = obj or self.getCurrentObject()
-
+        currentObject, offset = self._script.utilities.getCaretContext()
+        obj = obj or currentObject
         try:
             state = obj.getState()
         except:
@@ -924,13 +924,6 @@ class StructuralNavigation:
     #                                                                       #
     #########################################################################
 
-    def getCurrentObject(self):
-        """Returns the current object.  Normally, the locusOfFocus. But
-        in the case of Gecko, that doesn't always work.
-        """
-
-        return orca_state.locusOfFocus
-
     def isAfterDocumentOffset(self, obj, arg=None):
         """Returns True if obj is after the document's caret offset."""
         document = self._getDocument()
@@ -1224,6 +1217,7 @@ class StructuralNavigation:
         interest is contained.
         """
 
+        obj, offset = self._script.utilities.getCaretContext()
         docRoles = [pyatspi.ROLE_DOCUMENT_EMAIL,
                     pyatspi.ROLE_DOCUMENT_FRAME,
                     pyatspi.ROLE_DOCUMENT_PRESENTATION,
@@ -1231,32 +1225,13 @@ class StructuralNavigation:
                     pyatspi.ROLE_DOCUMENT_TEXT,
                     pyatspi.ROLE_DOCUMENT_WEB]
         stopRoles = [pyatspi.ROLE_FRAME, pyatspi.ROLE_SCROLL_PANE]
-        document = self._script.utilities.ancestorWithRole(
-            orca_state.locusOfFocus, docRoles, stopRoles)
-
+        document = self._script.utilities.ancestorWithRole(obj, docRoles, stopRoles)
         if not document and orca_state.locusOfFocus:
             if orca_state.locusOfFocus.getRole() in docRoles:
                 return orca_state.locusOfFocus
 
         return document
 
-    def _isInDocument(self, obj):
-        """Returns True if the accessible object obj is inside of
-        the document.
-
-        Arguments:
-        -obj: the accessible object of interest.
-        """
-
-        document = self._getDocument()
-        while obj and obj.parent:
-            if self._script.utilities.isSameObject(obj.parent, document):
-                return True
-            else:
-                obj = obj.parent
-
-        return False
-
     #########################################################################
     #                                                                       #
     # Methods for Presenting Objects                                        #
@@ -1610,26 +1585,9 @@ class StructuralNavigation:
         return [obj, 0]
 
     def _setCaretPosition(self, obj, characterOffset):
-        """Sets the caret at the specified offset within obj.
-
-        Arguments:
-        - obj: the accessible object in which the caret should be
-          positioned.
-        - characterOffset: the offset at which to position the caret.
-        """
-
-        try:
-            text = obj.queryText()
-            text.setCaretOffset(characterOffset)
-        except NotImplementedError:
-            try:
-                obj.queryComponent().grabFocus()
-            except:
-                debug.printException(debug.LEVEL_SEVERE)
-        except:
-            debug.printException(debug.LEVEL_SEVERE)
+        """Sets the caret at the specified offset within obj."""
 
-        orca.setLocusOfFocus(None, obj, notifyScript=False)
+        self._script.utilities.setCaretPosition(obj, characterOffset)
 
     def _presentLine(self, obj, offset):
         """Presents the first line of the object to the user.


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