orca r4242 - in branches/phase2/src/orca: . plugins



Author: wwalker
Date: Thu Sep 18 14:39:05 2008
New Revision: 4242
URL: http://svn.gnome.org/viewvc/orca?rev=4242&view=rev

Log:
Begin work on Listener and Handler introspection.


Modified:
   branches/phase2/src/orca/default.py
   branches/phase2/src/orca/plugins/Makefile.am
   branches/phase2/src/orca/script.py

Modified: branches/phase2/src/orca/default.py
==============================================================================
--- branches/phase2/src/orca/default.py	(original)
+++ branches/phase2/src/orca/default.py	Thu Sep 18 14:39:05 2008
@@ -56,6 +56,11 @@
         #
         pluginClasses = []
         try:
+            import plugins.automatic
+            pluginClasses.append(plugins.automatic.Plugin)
+        except:
+            log.exception("handled exception while importing module:")
+        try:
             import plugins.debug_actions
             pluginClasses.append(plugins.debug_actions.Plugin)
         except:
@@ -97,36 +102,6 @@
 
         return script.Script._getPluginClasses(self) + pluginClasses
 
-    def _createObjectEventListeners(self):
-        """Sets up the AT-SPI event listeners for this script.
-        """
-        listeners = script.Script._createObjectEventListeners(self)
-        listeners.update({
-            "focus:":                           self._onFocus,
-            "object:active-descendant-changed": self._onActiveDescendantChanged,
-            #"keyboard:modifiers":               self._noOp,
-            "mouse:button":                     self._onMouseButton,
-            "object:property-change:accessible-name": self._onNameChanged,
-            "object:text-caret-moved":          self._onCaretMoved,
-            "object:text-changed:delete":       self._onTextDeleted,
-            "object:text-changed:insert":       self._onTextInserted,
-            "object:text-selection-changed":    self._onTextSelectionChanged,
-            "object:selection-changed":         self._onSelectionChanged,
-            "object:link-selected":             self._onLinkSelected,
-            "object:state-changed:active":      self._onStateChanged,
-            "object:state-changed:focused":     self._onStateChanged,
-            "object:state-changed:showing":     self._onStateChanged,
-            "object:state-changed:checked":     self._onStateChanged,
-            "object:state-changed:indeterminate": self._onStateChanged,
-            "object:state-changed:expanded":    self._onStateChanged,
-            "object:state-changed:selected":    self._onStateChanged,
-            "object:property-change:accessible-value": self._onValueChanged,
-            "object:value-changed":             self._onValueChanged,
-            "window:activate":                  self._onWindowActivated,
-            "window:deactivate":                self._onWindowDeactivated,
-        })
-        return listeners
-    
     def _createInputEventHandlers(self):
         """Defines InputEventHandler fields for this script that can be
         called by the key and braille bindings.
@@ -344,79 +319,108 @@
     #                                                                  #
     ####################################################################
 
-    def _onFocus(self, event):
+    def _focusListener(self, event):
         """Called on AT-SPI focus events.
+
+        event: focus:
         """
-        log.debug("_onFocus: %s" % str(event).replace("\n", " "))
+        log.debug("_focusListener: %s" % str(event).replace("\n", " "))
 
-    def _onActiveDescendantChanged(self, event):
+    def _activeDescendantChangedListener(self, event):
         """Called on AT-SPI object:active-descendant-changed events.
+
+        event: object:active-descendant-changed
         """
-        log.debug("_onActiveDescendantChanged: %s" \
+        log.debug("_activeDescendantChangedListener: %s" \
                   % str(event).replace("\n", " "))
 
-    def _onMouseButton(self, event):
+    def _mouseButtonListener(self, event):
         """Called on AT-SPI mouse:button events.
+
+        event: mouse:button
         """
-        log.debug("_onMouseButton: %s" % str(event).replace("\n", " "))
+        log.debug("_mouseButtonListener: %s" % str(event).replace("\n", " "))
 
-    def _onNameChanged(self, event):
+    def _nameChangedListener(self, event):
         """Called on AT-SPI object:property-change:accessible-name events.
+
+        event: object:property-change:accessible-name
         """
-        log.debug("_onNameChanged: %s" % str(event).replace("\n", " "))
+        log.debug("_nameChangedListener: %s" % str(event).replace("\n", " "))
 
-    def _onCaretMoved(self, event):
+    def _caretMovedListener(self, event):
         """Called on AT-SPI object:text-caret-moved events.
+
+        event: object:text-caret-moved
         """
-        log.debug("_onCaretMoved: %s" % str(event).replace("\n", " "))
+        log.debug("_caretMovedListener: %s" % str(event).replace("\n", " "))
 
-    def _onTextDeleted(self, event):
+    def _textDeletedListener(self, event):
         """Called on AT-SPI object:text-changed:delete events.
+
+        event: object:text-changed:delete
         """
-        log.debug("_onTextDeleted: %s" % str(event).replace("\n", " "))
+        log.debug("_textDeletedListener: %s" % str(event).replace("\n", " "))
 
-    def _onTextInserted(self, event):
+    def _textInsertedListener(self, event):
         """Called on AT-SPI object:text-changed:insert events.
+       
+        event: object:text-changed:insert
         """
-        log.debug("_onTextInserted: %s" % str(event).replace("\n", " "))
+        log.debug("_textInsertedListener: %s" % str(event).replace("\n", " "))
 
-    def _onTextSelectionChanged(self, event):
+    def _textSelectionChangedListener(self, event):
         """Called on AT-SPI object:text-selection-changed events.
+
+        event: object:text-selection-changed
         """
-        log.debug("_onTextSelectionChanged: %s" % str(event).replace("\n", " "))
+        log.debug("_textSelectionChangedListener: %s" 
+                  % str(event).replace("\n", " "))
 
-    def _onSelectionChanged(self, event):
+    def _selectionChangedListener(self, event):
         """Called on AT-SPI object:selection-changed events.
+
+        event: object:selection-changed
         """
-        log.debug("_onSelectionChanged: %s" % str(event).replace("\n", " "))
+        log.debug("_selectionChangedListener: %s" % str(event).replace("\n", " "))
 
-    def _onLinkSelected(self, event):
+    def _linkSelectedListener(self, event):
         """Called on AT-SPI object:link-selected events.
+
+        event: object:link-selected
         """
-        log.debug("_onLinkSelected: %s" % str(event).replace("\n", " "))
+        log.debug("_linkSelectedListener: %s" % str(event).replace("\n", " "))
 
-    def _onStateChanged(self, event):
+    def _stateChangedListener(self, event):
         """Called on AT-SPI object:state-changed events.
+
+        event: object:state-changed
         """
-        log.debug("_onStateChanged: %s" % str(event).replace("\n", " "))
+        log.debug("_stateChangedListener: %s" % str(event).replace("\n", " "))
 
-    def _onValueChanged(self, event):
+    def _valueChangedListener(self, event):
         """Called on AT-SPI object:value-changed and
            object:property-change:accessible-value events.
+
+        event: object:value-changed, object:property-change:accessible-value
         """
-        log.debug("_onValueChanged: %s" % str(event).replace("\n", " "))
+        log.debug("_valueChangedListener: %s" % str(event).replace("\n", " "))
 
-    def _onWindowActivated(self, event):
+    def _windowActivateListener(self, event):
         """Called on AT-SPI window:activate events.
+
+        event: window:activate
         """
-        log.debug("_onWindowActivated: %s" % str(event).replace("\n", " "))
+        log.debug("_windowActivateListener: %s" % str(event).replace("\n", " "))
 
-    def _onWindowDeactivated(self, event):
+    def _eindowDeactivatedListener(self, event):
         """Called on AT-SPI window:deactivate events.
+
+        event: window:deactivate
         """
-        log.debug("_onWindowDeactivated: %s" % str(event).replace("\n", " "))
+        log.debug("_windowDeactivateListener: %s" % str(event).replace("\n", " "))
 
-    def _noOp(self, event):
+    def _noOpListener(self, event):
         """Just here to capture events.
         """
         log.debug("_noOp: %s" % str(event).replace("\n", " "))

Modified: branches/phase2/src/orca/plugins/Makefile.am
==============================================================================
--- branches/phase2/src/orca/plugins/Makefile.am	(original)
+++ branches/phase2/src/orca/plugins/Makefile.am	Thu Sep 18 14:39:05 2008
@@ -1,6 +1,8 @@
 orca_pathdir=$(pyexecdir)
 
-orca_python_PYTHON = __init__.py
+orca_python_PYTHON = \
+	__init__.py \
+	automatic.py
 
 orca_pythondir=$(pyexecdir)/orca/plugins
 

Modified: branches/phase2/src/orca/script.py
==============================================================================
--- branches/phase2/src/orca/script.py	(original)
+++ branches/phase2/src/orca/script.py	Thu Sep 18 14:39:05 2008
@@ -78,7 +78,7 @@
         self._isActive = False
         self.presentIfInactive = False
 
-        self._objectEventListeners = self._createObjectEventListeners()
+        self._objectEventListeners = self._introspectObjectEventListeners()
         self._inputEventHandlers = self._createInputEventHandlers()
         self._keyboardBindings = \
             self._createKeyboardBindings(self._inputEventHandlers)
@@ -163,6 +163,121 @@
         """
         log.info("NEW SCRIPT: %s" % self)
 
+    def _parseObjectEventListenerDocString(self, docstring):
+        """Looks for an 'event:' line in the given docstring and
+        returns it if it exists."""
+        import re
+        EVENT = re.compile(r'(\sevent:\s*)(.*)\n')
+        match = EVENT.search(docstring)
+        try:
+            event = match.group(2).strip()
+        except:
+            event = None
+        return event
+
+    def _introspectObjectEventListeners(self):
+        """Find the AT-SPI listeners based upon their method name.
+        """
+        # Find all the Listener methods and save them based upon their name
+        # and their bound form.
+        #
+        listeners = {}
+        for symbol in dir(self):
+            if symbol.endswith("Listener"):
+                method = getattr(self, symbol).__get__(self, self.__class__)
+                if callable(method):
+                    eventString = \
+                        self._parseObjectEventListenerDocString(method.__doc__)
+                    try:
+                        events = eventString.split()
+                    except:
+                        events = []
+                    for event in events:
+                        listeners[event.strip(', ')] = method
+        return listeners
+
+    def _parseHandlerDocString(self, docstring):
+        """Looks for 'keyboard:', 'braille:', and 'description:' lines in
+        the given docstring and returns them if they exist."""
+        import re
+        KEYBOARD = re.compile(r'(\skeyboard:\s*)(.*)\n')
+        BRAILLE = re.compile(r'(\sbraille:\s*)(.*)\n')
+        DESCRIPTION = re.compile(r'(\sdescription:\s*)(.*)\n')
+        match = KEYBOARD.search(docstring)
+        try:
+            keyboard = match.group(2).strip()
+        except:
+            keyboard = None
+
+        match = BRAILLE.search(docstring)
+        try:
+            braille = match.group(2).strip()
+        except:
+            braille = None
+
+        match = DESCRIPTION.search(docstring)
+        try:
+            description = match.group(2).strip()
+        except:
+            description = None
+
+        # TODO: need to allow for multiple bindings.
+        # TODO: need allow things to cross lines.
+        # TODO: possibly eval things here?
+        #
+        return (keyboard, braille, description)
+
+    def _introspectHandlers(self):
+        """TODO: EXPERIMENTAL method to find the input event handlers for this
+        object based upon their method name.  The biggest issue is getting
+        the description to be marked for translation so intltool will pick
+        it up.
+        """
+        import input_event
+        from orca_i18n import _
+        try:
+            import brlapi
+        except:
+            log.exception("Not using braille bindings because of this exception:")
+
+        # Find all the Handler methods and save them based upon their name
+        # and their unbound (i.e., requires the plugin to be passed as the
+        # first argument) form.
+        #
+        methodList = []
+        for symbol in dir(self):
+            if symbol.endswith("Handler"):
+                method = self.__class__.__dict__[symbol]
+                if callable(method):
+                    methodList.append([symbol, method])
+
+        # Create the handlers and bindings.
+        #
+        # TODO: add gratuitous try/except clauses.
+        #
+        for symbol, method in methodList:
+            (keyboard, braille, description) = \
+                self._parseHandlerDocString(method.__doc__)
+            self._inputEventHandlers[symbol] = input_bindings.Handler(
+                method, description)
+            if keyboard:
+                [keysym, mask, modifiers, repeat] = keyboard.split()
+                binding = input_bindings.KeyboardBinding(
+                    eval(keysym.strip(', ')), 
+                    eval(mask.strip(', ')),
+                    eval(modifiers.strip(', ')),
+                    symbol,
+                    eval(repeat))
+                self._keyboardBindings.append(binding)
+            if braille:
+                [cmd, mask, modifiers, repeat] = keyboard.split()
+                self._brailleBindings.append(input_bindings.BrailleBinding(
+                        eval(keysym.strip(',')), 
+                        eval(mask.strip(',')),
+                        eval(modifiers.strip(',')),
+                        symbol,
+                        eval(repeat)))
+
     def __str__(self):
         """Returns a human readable representation of the script.
         """
@@ -180,14 +295,6 @@
         """
         return []
 
-    def _createObjectEventListeners(self):
-        """Sets up the AT-SPI event listeners for this script.
-
-        Returns a dictionary where the keys are AT-SPI event names
-        and the values are script methods.
-        """
-        return {}
-
     def _createInputEventHandlers(self):
         """Defines InputEventHandler fields for this script that can be
         called by the key and braille bindings.



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