orca r4261 - in branches/phase2: . src/orca src/orca/plugins src/orca/plugins/bookmarks src/orca/plugins/debug_actions src/orca/plugins/flat_review src/orca/plugins/speech_parameters src/orca/plugins/where_am_i



Author: wwalker
Date: Fri Sep 26 19:16:35 2008
New Revision: 4261
URL: http://svn.gnome.org/viewvc/orca?rev=4261&view=rev

Log:
Major handler refactor before we get too far.  Much more "Pythonic".


Added:
   branches/phase2/src/orca/input_binding.py   (contents, props changed)
Removed:
   branches/phase2/src/orca/default_bindings.py
   branches/phase2/src/orca/input_bindings.py
   branches/phase2/src/orca/plugins/bookmarks/braille_bindings.py
   branches/phase2/src/orca/plugins/bookmarks/keyboard_bindings.py
   branches/phase2/src/orca/plugins/debug_actions/braille_bindings.py
   branches/phase2/src/orca/plugins/debug_actions/keyboard_bindings.py
   branches/phase2/src/orca/plugins/flat_review/braille_bindings.py
   branches/phase2/src/orca/plugins/flat_review/keyboard_bindings.py
   branches/phase2/src/orca/plugins/speech_parameters/braille_bindings.py
   branches/phase2/src/orca/plugins/speech_parameters/keyboard_bindings.py
   branches/phase2/src/orca/plugins/where_am_i/braille_bindings.py
   branches/phase2/src/orca/plugins/where_am_i/keyboard_bindings.py
Modified:
   branches/phase2/logging.conf
   branches/phase2/src/orca/Makefile.am
   branches/phase2/src/orca/braille.py
   branches/phase2/src/orca/default.py
   branches/phase2/src/orca/input_event.py
   branches/phase2/src/orca/orca.py
   branches/phase2/src/orca/plugin.py
   branches/phase2/src/orca/plugins/automatic.py
   branches/phase2/src/orca/plugins/bookmarks/Makefile.am
   branches/phase2/src/orca/plugins/bookmarks/plugin.py
   branches/phase2/src/orca/plugins/debug_actions/Makefile.am
   branches/phase2/src/orca/plugins/debug_actions/plugin.py
   branches/phase2/src/orca/plugins/flat_review/Makefile.am
   branches/phase2/src/orca/plugins/flat_review/plugin.py
   branches/phase2/src/orca/plugins/speech_parameters/Makefile.am
   branches/phase2/src/orca/plugins/speech_parameters/plugin.py
   branches/phase2/src/orca/plugins/where_am_i/Makefile.am
   branches/phase2/src/orca/plugins/where_am_i/plugin.py
   branches/phase2/src/orca/script.py
   branches/phase2/src/orca/script_manager.py
   branches/phase2/src/orca/settings.py

Modified: branches/phase2/logging.conf
==============================================================================
--- branches/phase2/logging.conf	(original)
+++ branches/phase2/logging.conf	Fri Sep 26 19:16:35 2008
@@ -14,35 +14,35 @@
 handlers: file
 
 [logger_utils]
-level: INFO
+level: DEBUG
 handlers: file
 qualname: orca.utils
 propagate: 0
 parent: root
 
 [logger_orca]
-level: INFO
+level: DEBUG
 handlers: file
 qualname: orca.orca
 propagate: 0
 parent: root
 
 [logger_script_manager]
-level: INFO
+level: DEBUG
 handlers: file
 qualname: orca.script_manager
 propagate: 0
 parent: root
 
 [logger_script]
-level: INFO
+level: DEBUG
 handlers: file
 qualname: orca.script
 propagate: 0
 parent: root
 
 [logger_plugin]
-level: INFO
+level: DEBUG
 handlers: file
 qualname: orca.plugin
 propagate: 0

Modified: branches/phase2/src/orca/Makefile.am
==============================================================================
--- branches/phase2/src/orca/Makefile.am	(original)
+++ branches/phase2/src/orca/Makefile.am	Fri Sep 26 19:16:35 2008
@@ -12,8 +12,7 @@
 	braille.py \
 	character_names.py \
 	default.py \
-	default_bindings.py \
-	input_bindings.py \
+	input_binding.py \
 	input_event.py \
 	key_names.py \
 	orca_i18n.py \

Modified: branches/phase2/src/orca/braille.py
==============================================================================
--- branches/phase2/src/orca/braille.py	(original)
+++ branches/phase2/src/orca/braille.py	Fri Sep 26 19:16:35 2008
@@ -191,9 +191,9 @@
         _processBrailleEvent(_brlAPI.expandKeyCode(key))
     return _brlAPIRunning
 
-def setupKeyRanges(keys):
-    """Hacky method to tell BrlTTY what to send and not send us via
-    the readKey method.  This only works with BrlTTY v3.8 and better.
+def setKeys(keys):
+    """Tell BrlTTY what to send and not send us via the readKey
+    method.  This only works with BrlTTY v3.8 and better.
 
     Arguments:
     -keys: a list of BrlAPI commands.
@@ -212,9 +212,9 @@
         for key in keys:
             keySet.append(brlapi.KEY_TYPE_CMD | key)
         _brlAPI.acceptKeys(brlapi.rangeType_command, keySet)
-        log.debug("set braille key ranges to %s", keySet)
+        log.debug("set braille keys to %s", keySet)
     except:
-        log.exception("handled exception while setting up braille key ranges:")
+        log.exception("handled exception while setting up braille keys:")
 
 def init(callback=None):
     """Initializes the braille module, connecting to the BrlTTY driver.
@@ -315,8 +315,8 @@
 
     import gtk
     init(_myCallback)
-    setupKeyRanges([brlapi.KEY_CMD_ROUTE,
-                    brlapi.KEY_CMD_FWINLT, 
-                    brlapi.KEY_CMD_FWINRT])
+    setKeys([brlapi.KEY_CMD_ROUTE,
+             brlapi.KEY_CMD_FWINLT, 
+             brlapi.KEY_CMD_FWINRT])
     print "Press keys on the braille display.  Press Ctrl+C to quit."
     gtk.main()

Modified: branches/phase2/src/orca/default.py
==============================================================================
--- branches/phase2/src/orca/default.py	(original)
+++ branches/phase2/src/orca/default.py	Fri Sep 26 19:16:35 2008
@@ -27,8 +27,11 @@
 import logging
 log = logging.getLogger('orca.default')
 
-import default_bindings
-import input_bindings
+import brlapi
+
+import input_binding
+import input_event
+import settings
 import script
 
 from orca_i18n import _ # for gettext support
@@ -102,220 +105,9 @@
 
         return script.Script._getPluginClasses(self) + pluginClasses
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-        """
-        handlers = script.Script._createInputEventHandlers(self)
-        handlers.update({
-            "sayAllHandler" : input_bindings.Handler(
-                Script._sayAll,
-                # Translators: the Orca "SayAll" command allows the
-                # user to press a key and have the entire document in
-                # a window be automatically spoken to the user.  If
-                # the user presses any key during a SayAll operation,
-                # the speech will be interrupted and the cursor will
-                # be positioned at the point where the speech was
-                # interrupted.
-                #
-                _("Speaks entire document.")),
-
-            "toggleTableCellReadModeHandler" : input_bindings.Handler(
-                Script._toggleTableCellReadMode,
-                # Translators: when users are navigating a table, they
-                # sometimes want the entire row of a table read, or
-                # they just want the current cell to be presented to them.
-                #
-                _("Toggles whether to read just the current table cell " \
-                  "or the whole row.")),
-
-            "readCharAttributesHandler" : input_bindings.Handler(
-                Script._readCharAttributes,
-                # Translators: the attributes being presented are the
-                # text attributes, such as bold, italic, font name,
-                # font size, etc.
-                #
-                _("Reads the attributes associated with the current text " \
-                  "character.")),
-
-            "brailleCursorKeyHandler" : input_bindings.Handler(
-                Script._processBrailleCursorKey,
-                # Translators: a refreshable braille display is an
-                # external hardware device that presents braille
-                # character to the user.  There are a limited number
-                # of cells on the display (typically 40 cells).  
-                # There is typically a small button called a 'cursor
-                # routing key' over each cell.  The typical use is
-                # to move the text caret to the given spot when one
-                # presses the button.
-                #
-                _("Handles presses of braille cursor routing keys."),
-                False), # Do not enable learn mode for this action
-
-            "panBrailleLeftHandler" : input_bindings.Handler(
-                Script._panBrailleLeft,
-                # Translators: a refreshable braille display is an
-                # external hardware device that presents braille
-                # character to the user.  There are a limited number
-                # of cells on the display (typically 40 cells).  Orca
-                # provides the feature to build up a longer logical
-                # line and allow the user to press buttons on the
-                # braille display so they can pan left and right over
-                # this line.
-                #
-                _("Pans the braille display to the left."),
-                False), # Do not enable learn mode for this action
-
-            "panBrailleRightHandler" : input_bindings.Handler(
-                Script._panBrailleRight,
-                # Translators: a refreshable braille display is an
-                # external hardware device that presents braille
-                # character to the user.  There are a limited number
-                # of cells on the display (typically 40 cells).  Orca
-                # provides the feature to build up a longer logical
-                # line and allow the user to press buttons on the
-                # braille display so they can pan left and right over
-                # this line.
-                #
-                _("Pans the braille display to the right."),
-                False), # Do not enable learn mode for this action
-
-            "enterLearnModeHandler" : input_bindings.Handler(
-                Script._enterLearnMode,
-                # Translators: Orca has a "Learn Mode" that will allow
-                # the user to type any key on the keyboard and hear what
-                # the effects of that key would be.  The effects might
-                # be what Orca would do if it had a handler for the
-                # particular key combination, or they might just be to
-                # echo the name of the key if Orca doesn't have a handler.
-                #
-                _("Enters learn mode.  Press escape to exit learn mode.")),
-
-            "quitOrcaHandler" : input_bindings.Handler(
-                Script._quitOrca,
-                _("Quits Orca")),
-
-            "preferencesSettingsHandler" : input_bindings.Handler(
-                Script._showPreferencesGUI,
-                # Translators: the preferences configuration dialog is
-                # the dialog that allows users to set their preferences
-                # for Orca.
-                #
-                _("Displays the preferences configuration dialog.")),
-
-            "appPreferencesSettingsHandler" : input_bindings.Handler(
-                Script._showAppPreferencesGUI,
-                # Translators: the application preferences configuration
-                # dialog is the dialog that allows users to set their
-                # preferences for a specific application within Orca.
-                #
-                _("Displays the application preferences configuration " \
-                  "dialog.")),
-
-            "toggleSilenceSpeechHandler" : input_bindings.Handler(
-                Script._toggleSilenceSpeech,
-                # Translators: Orca allows the user to turn speech synthesis
-                # on or off.  We call it 'silencing'.
-                #
-                _("Toggles the silencing of speech.")),
-
-            "toggleColorEnhancementsHandler" : input_bindings.Handler(
-                Script._toggleColorEnhancements,
-                # Translators: "color enhancements" are changes users can
-                # make to the appearance of the screen to make things easier
-                # to see, such as inverting the colors or applying a tint.
-                # This command toggles these enhancements on/off.
-                #
-                _("Toggles color enhancements.")),
-
-            "toggleMouseEnhancementsHandler" : input_bindings.Handler(
-                Script._toggleMouseEnhancements,
-                # Translators: "mouse enhancements" are changes users can
-                # make to the appearance of the mouse pointer to make it
-                # easier to see, such as increasing its size, changing its
-                # color, and surrounding it with crosshairs.  This command
-                # toggles these enhancements on/off.
-                #
-                _("Toggles mouse enhancements.")),
-
-            "increaseMagnificationHandler" : input_bindings.Handler(
-                Script._increaseMagnification,
-                # Translators: this command increases the magnification
-                # level.
-                #
-                _("Increases the magnification level.")),
-
-            "decreaseMagnificationHandler" : input_bindings.Handler(
-                Script._decreaseMagnification,
-                # Translators: this command decreases the magnification
-                # level.
-                #
-                _("Decreases the magnification level.")),
-
-            "toggleMagnifierHandler" : input_bindings.Handler(
-                Script._toggleMagnifier,
-                # Translators: Orca allows the user to turn the magnifier
-                # on or off. This command not only toggles magnification,
-                # but also all of the color and pointer customizations
-                # made through the magnifier.
-                #
-                _("Toggles the magnifier.")),
-
-            "cycleZoomerTypeHandler" : input_bindings.Handler(
-                Script._cycleZoomerType,
-                # Translators: the user can choose between several different
-                # types of magnification, including full screen and split
-                # screen.  The "position" here refers to location of the
-                # magnifier.
-                #
-                _("Cycles to the next magnifier position.")),
-
-            # TODO: Add mouse review back in.
-            #"toggleMouseReviewHandler" : input_bindings.Handler(
-            #    mouse_review.toggle,
-            #    # Translators: Orca allows the item under the pointer to
-            #    # be spoken. This toggles the feature.
-            #    #
-            #    _("Toggle mouse review mode.")),
-
-            "bypassNextCommandHandler" : input_bindings.Handler(
-                Script._bypassNextCommand,
-                # Translators: Orca normally intercepts all keyboard
-                # commands and only passes them along to the current
-                # application when they are not Orca commands.  This
-                # command causes the next command issued to be passed
-                # along to the current application, bypassing Orca's
-                # interception of it.
-                #
-                _("Passes the next command on to the current application.")),
-        })
-        return handlers
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        bindings = script.Script._createKeyboardBindings(self, handlers)
-        # TODO: make this a decision between desktop and laptop layout
-        if True:
-            bindings.extend(default_bindings.desktopKeys)
-        else:
-            bindings.extend(default_bindings.laptopKeys)
-        return bindings
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings.
-        """
-        bindings = script.Script._createBrailleBindings(self, handlers)
-        bindings.extend(default_bindings.brailleKeys)
-        return bindings
-
     ####################################################################
     #                                                                  #
-    # AT-SPI Event Handlers                                            #
+    # AT-SPI OBJECT EVENT HANDLERS                                     #
     #                                                                  #
     ####################################################################
 
@@ -419,95 +211,314 @@
     #                                                                  #
     ####################################################################
 
-    def _sayAll(self, inputEvent=None, modifiers=None):
+    def _sayAllHandler(self, inputEvent=None):
         """The sayAll handler.
         """
-        log.debug("_sayAll: %s" % inputEvent)
+        log.debug("_sayAllHandler: %s" % inputEvent)
+    # Translators: the Orca "SayAll" command allows the
+    # user to press a key and have the entire document in
+    # a window be automatically spoken to the user.  If
+    # the user presses any key during a SayAll operation,
+    # the speech will be interrupted and the cursor will
+    # be positioned at the point where the speech was
+    # interrupted.
+    #                
+    _sayAllHandler.description = _("Speaks entire document.")
+    _sayAllHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Add",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "semicolon",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
 
-    def _toggleTableCellReadMode(self, inputEvent=None, modifiers=None):
+    def _toggleTableCellReadModeHandler(self, inputEvent=None):
         """The toggleTableCellReadMode handler.
         """
-        log.debug("_toggleTableCellReadMode: %s" % inputEvent)
+        log.debug("_toggleTableCellReadModeHandler: %s" % inputEvent)
+    # Translators: when users are navigating a table, they
+    # sometimes want the entire row of a table read, or
+    # they just want the current cell to be presented to them.
+    #
+    _toggleTableCellReadModeHandler.description = \
+        _("Toggles whether to read just the current table cell " \
+          "or the whole row.")
+    _toggleTableCellReadModeHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "F11",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK),
+        input_binding.KeyboardBinding(
+            "SunF36",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK)        
+    ]
 
-    def _readCharAttributes(self, inputEvent=None, modifiers=None):
+    def _readCharAttributesHandler(self, inputEvent=None):
         """The readCharAttributes handler.
         """
-        log.debug("_readCharAttributes: %s" % inputEvent)
+        log.debug("_readCharAttributesHandler: %s" % inputEvent)
+    # Translators: the attributes being presented are the
+    # text attributes, such as bold, italic, font name,
+    # font size, etc.
+    #
+    _readCharAttributesHandler.description = \
+        _("Reads the attributes associated with the current text character.")
+    _readCharAttributesHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "f",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK)
+    ]
 
-    def _processBrailleCursorKey(self, inputEvent=None, modifiers=None):
+    def _brailleCursorKeyHandler(self, inputEvent=None):
         """The brailleCursorKeyHandler handler.
         """
-        log.debug("_processBrailleCursorKey: %s" % inputEvent)
+        log.debug("_brailleCursorKeyHandler: %s" % inputEvent)
+    # Translators: a refreshable braille display is an
+    # external hardware device that presents braille
+    # character to the user.  There are a limited number
+    # of cells on the display (typically 40 cells).  
+    # There is typically a small button called a 'cursor
+    # routing key' over each cell.  The typical use is
+    # to move the text caret to the given spot when one
+    # presses the button.
+    #
+    _brailleCursorKeyHandler.description = \
+        _("Handles presses of braille cursor routing keys.")
+    _brailleCursorKeyHandler.bindings = [\
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_ROUTE,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK,
+            learnMode = False)
+    ]
 
-    def _panBrailleLeft(self, inputEvent=None, modifiers=None):
+    def _panBrailleLeftHandler(self, inputEvent=None):
         """The panBrailleLeft handler.
         """
-        log.debug("_panBrailleLeft: %s" % inputEvent)
+        log.debug("_panBrailleLeftHandler: %s" % inputEvent)
+    # Translators: a refreshable braille display is an
+    # external hardware device that presents braille
+    # character to the user.  There are a limited number
+    # of cells on the display (typically 40 cells).  Orca
+    # provides the feature to build up a longer logical
+    # line and allow the user to press buttons on the
+    # braille display so they can pan left and right over
+    # this line.
+    #
+    _panBrailleLeftHandler.description = \
+        _("Pans the braille display to the left.")
+    _panBrailleLeftHandler.bindings = [
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_FWINLT,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK,
+            learnMode = False)
+    ]
 
-    def _panBrailleRight(self, inputEvent=None, modifiers=None):
+    def _panBrailleRightHandler(self, inputEvent=None):
         """The panBrailleRight handler.
         """
-        log.debug("_panBrailleRight: %s" % inputEvent)
+        log.debug("_panBrailleRightHandler: %s" % inputEvent)
+    # Translators: a refreshable braille display is an
+    # external hardware device that presents braille
+    # character to the user.  There are a limited number
+    # of cells on the display (typically 40 cells).  Orca
+    # provides the feature to build up a longer logical
+    # line and allow the user to press buttons on the
+    # braille display so they can pan left and right over
+    # this line.
+    #
+    _panBrailleRightHandler.description = \
+        _("Pans the braille display to the right.")
+    _panBrailleRightHandler.bindings = [
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_FWINRT,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK,
+            learnMode = False)
+    ]
 
-    def _enterLearnMode(self, inputEvent=None, modifiers=None):
+    def _enterLearnModeHandler(self, inputEvent=None):
         """The enterLearnMode handler.
         """
-        log.debug("_enterLearnMode: %s" % inputEvent)
+        log.debug("_enterLearnModeHandler: %s" % inputEvent)
+    # Translators: Orca has a "Learn Mode" that will allow
+    # the user to type any key on the keyboard and hear what
+    # the effects of that key would be.  The effects might
+    # be what Orca would do if it had a handler for the
+    # particular key combination, or they might just be to
+    # echo the name of the key if Orca doesn't have a handler.
+    #
+    _enterLearnModeHandler.description = \
+        _("Enters learn mode.  Press escape to exit learn mode.")
+    _enterLearnModeHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "h",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK)
+    ]
 
-    def _quitOrca(self, inputEvent=None, modifiers=None):
+    def _quitOrcaHandler(self, inputEvent=None):
         """The quitOrca handler.
         """
-        log.debug("_quitOrca: %s" % inputEvent)
+        log.debug("_quitOrcaHandler: %s" % inputEvent)
+    _quitOrcaHandler.description = _("Quits Orca")
+    _quitOrcaHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "q",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK)
+    ]
 
-    def _showPreferencesGUI(self, inputEvent=None, modifiers=None):
+    def _showPreferencesGUIHandler(self, inputEvent=None):
         """The showPreferencesGUI handler.
         """
-        log.debug("_showPreferencesGUI: %s" % inputEvent)
+        log.debug("_showPreferencesGUIHandler: %s" % inputEvent)
+    # Translators: the preferences configuration dialog is
+    # the dialog that allows users to set their preferences
+    # for Orca.
+    #
+    _showPreferencesGUIHandler.description = \
+        _("Displays the preferences configuration dialog.")
+    _showPreferencesGUIHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "space",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK)
+    ]
 
-    def _showAppPreferencesGUI(self, inputEvent=None, modifiers=None):
+    def _showAppPreferencesGUIHandler(self, inputEvent=None):
         """The showAppPreferencesGUI handler.
         """
-        log.debug("_showAppPreferencesGUI: %s" % inputEvent)
+        log.debug("_showAppPreferencesGUIHandler: %s" % inputEvent)
+    # Translators: the application preferences configuration
+    # dialog is the dialog that allows users to set their
+    # preferences for a specific application within Orca.
+    #
+    _showAppPreferencesGUIHandler.description = \
+        _("Displays the application preferences configuration dialog.")
+    _showAppPreferencesGUIHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "space",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK)
+    ]
 
-    def _toggleSilenceSpeech(self, inputEvent=None, modifiers=None):
+    def _toggleSilenceSpeechHandler(self, inputEvent=None):
         """The toggleSilenceSpeech handler.
         """
-        log.debug("_toggleSilenceSpeech: %s" % inputEvent)
+        log.debug("_toggleSilenceSpeechHandler: %s" % inputEvent)
+    # Translators: Orca allows the user to turn speech synthesis
+    # on or off.  We call it 'silencing'.
+    #
+    _toggleSilenceSpeechHandler.description = \
+        _("Toggles the silencing of speech.")
+    _toggleSilenceSpeechHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "s",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK)
+    ]
 
-    def _toggleColorEnhancements(self, inputEvent=None, modifiers=None):
+    def _toggleColorEnhancementsHandler(self, inputEvent=None):
         """The toggleColorEnhancements handler.
         """
-        log.debug("_toggleColorEnhancements: %s" % inputEvent)
+        log.debug("_toggleColorEnhancementsHandler: %s" % inputEvent)
+    # Translators: "color enhancements" are changes users can
+    # make to the appearance of the screen to make things easier
+    # to see, such as inverting the colors or applying a tint.
+    # This command toggles these enhancements on/off.
+    #
+    _toggleColorEnhancementsHandler.description = \
+        _("Toggles color enhancements.")
 
-    def _toggleMouseEnhancements(self, inputEvent=None, modifiers=None):
+    def _toggleMouseEnhancementsHandler(self, inputEvent=None):
         """The toggleMouseEnhancements handler.
         """
-        log.debug("_toggleMouseEnhancements: %s" % inputEvent)
+        log.debug("_toggleMouseEnhancementsHandler: %s" % inputEvent)
+    # Translators: "mouse enhancements" are changes users can
+    # make to the appearance of the mouse pointer to make it
+    # easier to see, such as increasing its size, changing its
+    # color, and surrounding it with crosshairs.  This command
+    # toggles these enhancements on/off.
+    #
+    _toggleMouseEnhancementsHandler.description = \
+        _("Toggles mouse enhancements.")
 
-    def _increaseMagnification(self, inputEvent=None, modifiers=None):
+    def _increaseMagnificationHandler(self, inputEvent=None):
         """The increaseMagnification handler.
         """
-        log.debug("_increaseMagnification: %s" % inputEvent)
+        log.debug("_increaseMagnificationHandler: %s" % inputEvent)
+    # Translators: this command increases the magnification
+    # level.
+    #
+    _increaseMagnificationHandler.description = \
+        _("Increases the magnification level.")
 
-    def _decreaseMagnification(self, inputEvent=None, modifiers=None):
+    def _decreaseMagnificationHandler(self, inputEvent=None):
         """The decreaseMagnification handler.
         """
-        log.debug("_decreaseMagnification: %s" % inputEvent)
+        log.debug("_decreaseMagnificationHandler: %s" % inputEvent)
+    # Translators: this command decreases the magnification
+    # level.
+    #
+    _decreaseMagnificationHandler.description = \
+        _("Decreases the magnification level.")
 
-    def _toggleMagnifier(self, inputEvent=None, modifiers=None):
+    def _toggleMagnifierHandler(self, inputEvent=None):
         """The toggleMagnifier handler.
         """
-        log.debug("_toggleMagnifier: %s" % inputEvent)
+        log.debug("_toggleMagnifierHandler: %s" % inputEvent)
+    # Translators: Orca allows the user to turn the magnifier
+    # on or off. This command not only toggles magnification,
+    # but also all of the color and pointer customizations
+    # made through the magnifier.
+    #
+    _toggleMagnifierHandler.description = \
+        _("Toggles the magnifier.")
 
-    def _cycleZoomerType(self, inputEvent=None, modifiers=None):
+    def _cycleZoomerTypeHandler(self, inputEvent=None):
         """The cycleZoomerType handler.
         """
-        log.debug("_cycleZoomerType: %s" % inputEvent)
+        log.debug("_cycleZoomerTypeHandler: %s" % inputEvent)
+    # Translators: the user can choose between several different
+    # types of magnification, including full screen and split
+    # screen.  The "position" here refers to location of the
+    # magnifier.
+    #
+    _cycleZoomerTypeHandler.description = \
+        _("Cycles to the next magnifier position.")
+
+    def _toggleMouseReviewHandler(self, inputEvent=None):
+        """The toggleMouseReview handler.
+        """
+        log.debug("_toggleMouseReviewHandler: %s" % inputEvent)
+    # Translators: Orca allows the item under the pointer to
+    # be spoken. This toggles the feature.
+    #
+    _toggleMouseReviewHandler.description = \
+        _("Toggle mouse review mode.")
 
-    def _bypassNextCommand(self, inputEvent=None, modifiers=None):
+    def _bypassNextCommandHandler(self, inputEvent=None):
         """The bypassNextCommand handler.
         """
-        log.debug("_bypassNextCommand: %s" % inputEvent)
+        log.debug("_bypassNextCommandHandler: %s" % inputEvent)
+    # Translators: Orca normally intercepts all keyboard
+    # commands and only passes them along to the current
+    # application when they are not Orca commands.  This
+    # command causes the next command issued to be passed
+    # along to the current application, bypassing Orca's
+    # interception of it.
+    #
+    _bypassNextCommandHandler.description = \
+        _("Passes the next command on to the current application.")
 
 if __name__ == "__main__":
     print Script(None)

Added: branches/phase2/src/orca/input_binding.py
==============================================================================
--- (empty file)
+++ branches/phase2/src/orca/input_binding.py	Fri Sep 26 19:16:35 2008
@@ -0,0 +1,377 @@
+# Copyright 2005-2008 Sun Microsystems Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA  02110-1301 USA.
+
+"""Provides classes for expressing interest in input events."""
+
+__id__        = "$Id$"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__   = "LGPL"
+
+import logging
+log = logging.getLogger('orca.input_binding')
+
+try:
+    # This can fail due to gtk not being available.  We want to
+    # be able to recover from that if possible.  The main driver
+    # for this is to allow "orca --text-setup" to work even if
+    # the desktop is not running.
+    #
+    import gtk
+except ImportError:
+    pass
+
+import pyatspi
+
+import input_event
+
+########################################################################
+#                                                                      #
+# METHODS FOR DEALING WITH CONVERTING X KEYSYMS TO KEYCODES            #
+#                                                                      #
+########################################################################
+
+_keysymsCache = {}
+_keycodeCache = {}
+
+def getAllKeysyms(keysym):
+    """Given a keysym, find all other keysyms associated with the key
+    that is mapped to the given keysym.  This allows us, for example,
+    to determine that the key bound to KP_Insert is also bound to KP_0.
+    """
+    if keysym not in _keysymsCache:
+        # The keysym itself is always part of the list.
+        #
+        _keysymsCache[keysym] = [keysym]
+
+        # Find the numerical value of the keysym
+        #
+        keyval = gtk.gdk.keyval_from_name(keysym)
+
+        if keyval != 0:
+            # Find the keycodes for the keysym.  Since a keysym
+            # can be associated with more than one key, we'll shoot
+            # for the keysym that's in group 0, regardless of shift
+            # level (each entry is of the form [keycode, group,
+            # level]).
+            #
+            keymap = gtk.gdk.keymap_get_default()
+            entries = keymap.get_entries_for_keyval(keyval)
+            keycode = 0
+            if entries:
+                for entry in entries:
+                    if entry[1] == 0:  # group = 0
+                        keycode = entry[0]
+                        break
+
+            # Find the keysyms bound to the keycode.  These are what
+            # we are looking for.
+            #
+            if keycode != 0:
+                entries = keymap.get_entries_for_keycode(keycode)
+                if entries:
+                    for entry in entries:
+                        keyval = entry[0]
+                        name = gtk.gdk.keyval_name(keyval)
+                        if name and (name != keysym):
+                            _keysymsCache[keysym].append(name)
+
+    return _keysymsCache[keysym]
+
+def getKeycode(keysym):
+    """Converts an XKeysym string (e.g., 'KP_Enter') to a keycode that
+    should match the event.hw_code for key events.
+
+    This whole situation is caused by the fact that Solaris chooses
+    to give us different keycodes for the same key, and the keypad
+    is the primary place where this happens: if NumLock is not on,
+    there is no telling the difference between keypad keys and the
+    other navigation keys (e.g., arrows, page up/down, etc.).  One,
+    for example, would expect to get KP_End for the '1' key on the
+    keypad if NumLock were not on.  Instead, we get 'End' and the
+    keycode for it matches the keycode for the other 'End' key.  Odd.
+    If NumLock is on, we at least get KP_* keys.
+
+    So...when setting up keyboardbindings, we say we're interested in
+    KeySyms, but those keysyms are carefully chosen so as to result
+    in a keycode that matches the actual key on the keyboard.  This
+    is why we use KP_1 instead of KP_End and so on in our keyboardbindings.
+
+    Arguments:
+    - keysym: a string that is a valid representation of an XKeysym.
+
+    Returns an integer representing a key code that should match the
+    event.hw_code for key events.
+    """
+    if not keysym:
+        return 0
+
+    if keysym not in _keycodeCache:
+        keymap = gtk.gdk.keymap_get_default()
+
+        # Find the numerical value of the keysym
+        #
+        keyval = gtk.gdk.keyval_from_name(keysym)
+        if keyval == 0:
+            return 0
+
+        # Now find the keycodes for the keysym.   Since a keysym can
+        # be associated with more than one key, we'll shoot for the
+        # keysym that's in group 0, regardless of shift level (each
+        # entry is of the form [keycode, group, level]).
+        #
+        _keycodeCache[keysym] = 0
+        entries = keymap.get_entries_for_keyval(keyval)
+        if entries:
+            for entry in entries:
+                if entry[1] == 0:  # group = 0
+                    _keycodeCache[keysym] = entry[0]
+                    break
+                if _keycodeCache[keysym] == 0:
+                    _keycodeCache[keysym] = entries[0][0]
+
+    return _keycodeCache[keysym]
+
+########################################################################
+#                                                                      #
+# INPUT HANDLER                                                        #
+#                                                                      #
+########################################################################
+
+class InputHandler:
+    """Maps an input binding to a function.
+    """
+    def __init__(self, function, description, bindings):
+        """Creates a new Handler instance.
+        
+        Arguments:
+
+        - function: the function to call
+
+        - description: a human consumable description of 
+        this handler
+
+        - bindings: a list of InputBinding instances that
+        will cause this handler to be used       
+        """
+        self.function = function
+        self.description = description
+        self.bindings = bindings
+
+    def __str__(self):
+        bindingsString = ""
+        for binding in self.bindings:
+            bindingsString += "%s," % binding
+        return "%s [%s]" % (self.description, bindingsString)
+
+    def handlesEvent(self, inputEvent):
+        """Returns True if this Handler has an InputBinding
+        that matches the given inputEvent.
+        """
+        for binding in self.bindings:
+            if binding.matches(inputEvent):
+                return True
+
+########################################################################
+#                                                                      #
+# INPUT BINDING CLASSES                                                #
+#                                                                      #
+########################################################################
+
+class InputBinding:
+    """An input event binding, consisting of a command, a keyboard
+    modifier mask, keyboard modifiers, and a click count.
+    """
+    def __init__(self, 
+                 command, 
+                 modifierMask, 
+                 modifiers, 
+                 clickCount = 0,
+                 learnMode = True):
+        """Creates a new input binding.
+
+        Arguments:
+
+        - command: a string or integer describing the input event.
+          For braille events, it can be something like KEY_CMD_ROUTE,
+          KEY_CMD_FWINLT, etc.  For keyboard events, we want a
+          KeySym string - this is typically a string from
+          /usr/include/X11/keysymdef.h with the preceding 'XK_'
+          removed (e.g., XK_KP_Enter becomes the string 'KP_Enter').
+          For mouse events, it is the mouse button.
+
+        - modifierMask: bit mask where a set bit tells us what
+          keyboard modifiers we care about (see pyatspi.MODIFIER_*).
+          That is, if a bit is set in this mask, we want the modifier
+          state specified in the modifiers field to be exactly what it
+          is set to.  This allows us, for example, to ignore some
+          modifiers.
+
+        - modifiers: the state the keyboard modifiers we care about
+          must be in for this key binding to match an input event (see
+          also pyatspi.MODIFIER_*)
+
+        - clickCount: how many times the command should be pressed in
+          a row.  A value of 0 means match any number of clicks.
+
+        - learnMode: if True, the description is presented in learn mode.
+        """
+        self.command = command
+        self.modifierMask = modifierMask
+        self.modifiers = modifiers
+        self.clickCount = clickCount
+        self.learnMode = learnMode
+        self._hardwareCode = self._getHardwareCode()
+
+    def __str__(self):
+        return "[%s command=%s modifierMask=%x modifiers=%x clickCount=%d]" % \
+            (self.__class__.__name__,
+             self.command,
+             self.modifierMask,
+             self.modifiers,
+             self.clickCount)
+
+    def _getHardwareCode(self):
+        """Returns a hardware code for the command associated with
+        this InputBinding.  By default, it is the same as the command.
+        Subclasses, such as KeyboardBinding, might override this so
+        that the command remains a KeySym string, but the hardware
+        code represents the keycode associated with the KeySym string.
+        """
+        return self.command
+
+    def matches(self, inputEvent):
+        """Returns true if this binding matches the given input event.
+        """
+        return (inputEvent.hw_code == self._hardwareCode) \
+               and ((inputEvent.modifiers & self.modifierMask) \
+                    == self.modifiers) \
+               and ((self.clickCount == 0) \
+                    or (self.clickCount == inputEvent.click_count))
+
+class KeyboardBinding(InputBinding):
+    """A single keyboard binding.
+    """
+    def __init__(self, 
+                 command, 
+                 modifierMask, 
+                 modifiers, 
+                 clickCount = 0,
+                 learnMode = True,
+                 keyboardLayout = 0):
+        """Creates a new key binding.
+
+        Arguments:
+
+        - command: a KeySym string from /usr/include/X11/keysymdef.h
+          with the preceding 'XK_' removed (e.g., XK_KP_Enter becomes
+          the string 'KP_Enter').
+
+        - modifierMask: bit mask where a set bit tells us what
+          keyboard modifiers we care about (see pyatspi.MODIFIER_*).
+          That is, if a bit is set in this mask, we want the modifier
+          state specified in the modifiers field to be exactly what it
+          is set to.  This allows us, for example, to ignore some
+          modifiers.
+
+        - modifiers: the state the keyboard modifiers we care about
+          must be in for this key binding to match an input event (see
+          also pyatspi.MODIFIER_*)
+
+        - clickCount: how many times the command should be pressed in
+          a row.  A value of 0 means match any number of clicks.
+
+        - learnMode: if True, the description is presented in learn mode.
+
+        - keyboardLayout: specifies if this is for
+          settings.GENERAL_KEYBOARD_LAYOUT_ALL (default),
+          settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP, or
+          settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP.
+        """
+        InputBinding.__init__(self, 
+                              command, 
+                              modifierMask,
+                              modifiers,
+                              clickCount,
+                              learnMode)
+        self.keyboardLayout = keyboardLayout
+
+    def _getHardwareCode(self):
+        """Converts the command into a hardware code"""
+        return getKeycode(self.command)
+
+    def matches(self, inputEvent):
+        """Returns true if this binding matches the given input event.
+        """
+        return isinstance(inputEvent, input_event.KeyboardEvent) \
+               and InputBinding.matches(self, inputEvent)
+
+class BrailleBinding(InputBinding):
+    """A single braille binding.
+    """
+    def __init__(self, 
+                 command, 
+                 modifierMask, 
+                 modifiers, 
+                 clickCount = 0,
+                 learnMode = True):
+        """Creates a new braille binding.
+
+        Arguments:
+        - command: A BrlAPI KEY_CMD_* command.
+
+        - modifierMask: bit mask where a set bit tells us what
+          keyboard modifiers we care about (see pyatspi.MODIFIER_*).
+          That is, if a bit is set in this mask, we want the modifier
+          state specified in the modifiers field to be exactly what it
+          is set to.  This allows us, for example, to ignore some
+          modifiers.
+
+        - modifiers: the state the keyboard modifiers we care about
+          must be in for this key binding to match an input event (see
+          also pyatspi.MODIFIER_*)
+
+        - clickCount: how many times the command should be pressed in
+          a row.  A value of 0 means match any number of clicks.
+
+        - learnMode: if True, the description is presented in learn mode.
+        """
+        InputBinding.__init__(self, 
+                              command, 
+                              modifierMask,
+                              modifiers,
+                              clickCount,
+                              learnMode)
+
+    def matches(self, inputEvent):
+        """Returns true if this binding matches the given input event.
+        """
+        return isinstance(inputEvent, input_event.BrailleEvent) \
+               and InputBinding.matches(self, inputEvent)
+
+if __name__ == "__main__":
+    logging.basicConfig(format="%(name)s %(message)s")
+    log.setLevel(logging.DEBUG)
+
+    print getAllKeysyms("Insert")
+    print getKeycode("Insert")
+
+    print KeyboardBinding("Insert", 0x1ff, 0, 2)
+    print KeyboardBinding("Return", 0xf, 0xf, 0)
+
+    import brlapi
+    print BrailleBinding(brlapi.KEY_CMD_ROUTE, 0x1ff, 0, 2)
+    print BrailleBinding(brlapi.KEY_CMD_FWINRT, 0, 0, 3)

Modified: branches/phase2/src/orca/input_event.py
==============================================================================
--- branches/phase2/src/orca/input_event.py	(original)
+++ branches/phase2/src/orca/input_event.py	Fri Sep 26 19:16:35 2008
@@ -17,9 +17,8 @@
 
 """Provides support for handling input events.  This provides several
 classes to define input events (InputEvent, KeyboardEvent,
-BrailleEvent, MouseButtonEvent), and also provides a InputEventHandler
-class.  It is intended that instances of InputEventHandler will be
-used which should be used to handle all input events."""
+BrailleEvent, MouseButtonEvent) as a means to normalize Orca's
+use of them."""
 
 __id__        = "$Id$"
 __copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
@@ -33,6 +32,13 @@
 
 from orca_i18n import _ # for gettext support
 
+# Constants describing the type of event.  This is for keyboard,
+# braille, and mouse events.  We just borrow the constants from
+# AT-SPI keyboard events.
+#
+PRESSED  = pyatspi.KEY_PRESSED_EVENT
+RELEASED = pyatspi.KEY_RELEASED_EVENT
+
 # A new modifier to use (set by the press of any key in the
 # orcaModifierKeys list) to represent the Orca modifier.
 #
@@ -132,20 +138,48 @@
 
 class InputEvent:
     """Super class for all input events."""
-    def __init__(self):
-        """Creates a new input event of the given type.
+    def __init__(self,
+                 raw_event,
+                 command,
+                 hw_code,
+                 eventType,
+                 modifiers):
+        """Creates a new InputEvent.
+
+        Arguments:
+
+        - raw_event: the raw input event
+
+        - command: a string or integer describing the input event.
+          For braille events, it can be something like KEY_CMD_ROUTE,
+          KEY_CMD_FWINLT, etc.  For keyboard events, we want a
+          KeySym string - this is typically a string from
+          /usr/include/X11/keysymdef.h with the preceding 'XK_'
+          removed (e.g., XK_KP_Enter becomes the string 'KP_Enter').
+          For mouse events, it is the mouse button.
+
+        - hw_code: the hardware code associated with the command.
+
+        - type: PRESSED or RELEASED
+
+        - modifiers: any keyboard modifiers
         """
-        pass
+        self.raw_event   = raw_event
+        self.command     = command
+        self.hw_code     = hw_code
+        self.type        = eventType
+        self.modifiers   = modifiers
+        self.time        = time.time()
+        self.click_count = 0 # filled in later
 
 class KeyboardEvent(InputEvent):
     """An InputEvent that comes from the keyboard."""
     def __init__(self, event):
-        """Creates a new InputEvent of type KEYBOARD_EVENT.
+        """Creates a new KeyboardEvent.
 
         Arguments:
         - event: the AT-SPI keyboard event
         """
-        InputEvent.__init__(self)
 
         # Control characters come through as control characters, so we
         # just turn them into their ASCII equivalent.  NOTE that the
@@ -164,67 +198,62 @@
 
         # Filter out the NUMLOCK modifier -- it always causes problems.
         #
-        event.modifiers = event.modifiers & ALL_BUT_NUMLOCK_MODIFIER_MASK
+        modifiers = event.modifiers & ALL_BUT_NUMLOCK_MODIFIER_MASK
 
-        self.type = event.type
-        self.hw_code = event.hw_code
-        self.modifiers = event.modifiers
-        self.event_string = event_string
-        self.is_text = event.is_text
-        self.time = time.time()
-        self.click_count = 0
+        InputEvent.__init__(self,
+                            event,
+                            event_string,
+                            event.hw_code,
+                            event.type,
+                            modifiers)
 
     def __str__(self):
-        if self.type == pyatspi.KEY_PRESSED_EVENT:
-            s = "key '%s' pressed (modifiers=0x%x, click_count=%d)" \
-                % (self.event_string, self.modifiers, self.click_count)
-        else:
-            s = "key '%s' released (modifiers=0x%x, click_count=%d)" \
-                % (self.event_string, self.modifiers, self.click_count)
-        return s
+        return "key '%s' %s (modifiers=0x%x, click_count=%d)" \
+               % (self.command, 
+                  self.type == PRESSED and "pressed" or "released",
+                  self.modifiers, 
+                  self.click_count)
 
 class BrailleEvent(InputEvent):
     """An InputEvent that comes from the braille display."""
     def __init__(self, event):
-        """Creates a new InputEvent of type BRAILLE_EVENT.
+        """Creates a new BrailleEvent.  Note that if this is a cursor
+        routing key event, self.raw_event["argument"] is the cursor
+        routing key.
 
         Arguments:
         - event: the integer BrlTTY command for this event.
         """
-        InputEvent.__init__(self)
-        self.event = event
-        self.command = event["command"]
-        self.type = event["type"]
-        self.argument = event["argument"]
-        self.flags = event["flags"]
-        self.time = time.time()
-        self.click_count = 0
+        InputEvent.__init__(self,
+                            event,
+                            event["command"],
+                            event["command"],
+                            PRESSED,
+                            0) # keyboard modifiers added later
 
     def __str__(self):
         return "braille event %s (click_count=%d)" \
-               % (self.event, self.click_count)
+               % (self.raw_event, self.click_count)
 
 class MouseButtonEvent(InputEvent):
     """An InputEvent that comes from pressing a mouse button."""
     def __init__(self, event):
-        """Creates a new InputEvent of type MOUSE_BUTTON_EVENT.
+        """Creates a new MouseButtonEvent
         """
-        InputEvent.__init__(self)
-        self.x = event.detail1
-        self.y = event.detail2
-        self.pressed = event.type.endswith('p')
-        self.button = event.type[len("mouse:button:"):-1]
-        self.time = time.time()
-        self.click_count = 0
+        InputEvent.__init__(self,
+                            event,
+                            event.type[len("mouse:button:"):-1],
+                            event.type[len("mouse:button:"):-1],
+                            event.type.endswith('p') and PRESSED or RELEASED,
+                            0) # keyboard modifiers added later
 
     def __str__(self):
-        if self.pressed:
-            s = "mouse button '%s' pressed at (%d,%y) (click_count=%d)" \
-                % (self.button, self.x, self.y, self.click_count)
-        else:
-            s = "mouse button '%s' released at (%d,%y) (click_count=%d)" \
-                % (self.button, self.x, self.y, self.click_count)
-        return s
+        return "mouse button '%s' %s at (%d,%y) (click_count=%d)" \
+               % (self.command, 
+                  self.type == PRESSED and "pressed" or "released",
+                  self.raw_event.detail1, 
+                  self.raw_event.detail2,
+                  self.click_count)
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/orca.py
==============================================================================
--- branches/phase2/src/orca/orca.py	(original)
+++ branches/phase2/src/orca/orca.py	Fri Sep 26 19:16:35 2008
@@ -189,27 +189,6 @@
 
     print _("Report bugs to orca-list gnome org ")
 
-def loadUserSettings(defaultSettings):
-    """Loads (and reloads) the user settings module.
-    """
-    global _userSettings
-
-    if _userSettings:
-        try:
-            reload(_userSettings)
-        except:
-            log.exception("exception handled while reloading user_settings:")
-    else:
-        try:
-            _userSettings = __import__("user_settings")
-            return _userSettings.getSettings(defaultSettings)
-        except ImportError:
-            log.debug("user_settings not found (this is OK).")
-        except:
-            log.exception("exception handled while importing user_settings:")
-
-    return settings.Settings(defaultSettings)
-
 def _start(commandLineSettings):
     """Starts Orca.
     """
@@ -346,6 +325,27 @@
 
     return commandLineSettings
 
+def loadUserSettings(defaultSettings):
+    """Loads (and reloads) the user settings module.
+    """
+    global _userSettings
+
+    if _userSettings:
+        try:
+            reload(_userSettings)
+        except:
+            log.exception("exception handled while reloading user_settings:")
+    else:
+        try:
+            _userSettings = __import__("user_settings")
+            return _userSettings.getSettings(defaultSettings)
+        except ImportError:
+            log.debug("user_settings not found (this is OK).")
+        except:
+            log.exception("exception handled while importing user_settings:")
+
+    return settings.Settings(defaultSettings)
+
 def main():
     """The main entry point for Orca.  The exit codes for Orca will
     loosely be based on signals, where the exit code will be the

Modified: branches/phase2/src/orca/plugin.py
==============================================================================
--- branches/phase2/src/orca/plugin.py	(original)
+++ branches/phase2/src/orca/plugin.py	Fri Sep 26 19:16:35 2008
@@ -42,18 +42,18 @@
         self._script = owner
         script.Script.__init__(self, owner, scriptSettings)
 
+    def __str__(self):
+        """Returns a human readable representation of the script.
+        """
+        return "plugin %s for %s" % (self.__module__, self._script)
+
     def _completeInit(self):
         """Completes the __init__ step.
         """
         self.application = self._script.application
         log.debug("NEW PLUGIN: %s" % self)
 
-    def __str__(self):
-        """Returns a human readable representation of the script.
-        """
-        return "plugin %s for %s" % (self.__module__, self._script)
-
-    def _setupBrailleKeyRanges(self):
+    def _registerBrailleKeys(self):
         """Sets up the BrlAPI commands this script and all of its plugins
         care about.
         """
@@ -61,7 +61,7 @@
         # setting is done in one fell swoop.
         pass
 
-    def _clearBrailleKeyRanges(self):
+    def _unregisterBrailleKeys(self):
         """Clears the BrlAPI commands this script and all of its plugins
         care about.
         """
@@ -79,14 +79,6 @@
             name = name + __name__.strip("orca") + ".settings"
         return name
 
-    def getPronunciations(self):
-        """Defines the application specific pronunciations for this script.
-
-        Returns a dictionary where the keys are the actual text strings and
-        the values are the replacement strings that are spoken instead.
-        """
-        return self._script.getPronunciations()
-
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")
     log.setLevel(logging.DEBUG)

Modified: branches/phase2/src/orca/plugins/automatic.py
==============================================================================
--- branches/phase2/src/orca/plugins/automatic.py	(original)
+++ branches/phase2/src/orca/plugins/automatic.py	Fri Sep 26 19:16:35 2008
@@ -27,6 +27,7 @@
 import logging
 log = logging.getLogger('orca.plugins.automatic')
 
+import orca.input_binding as input_binding
 import orca.input_event as input_event
 import orca.plugin as plugin
 
@@ -51,23 +52,30 @@
         """
         plugin.Plugin.__init__(self, owner, scriptSettings)
 
-    def floopyDooHandler(self, inputEvent=None, modifiers=None):
+    def floopyDooHandler(self, inputEvent=None):
         """The floopy doo handler.
         """
         log.debug("floopyDooHandler: %s" % inputEvent)
-    floopyDooHandler.keyboardBindings = [
-        ["a", input_event.defaultModifierMask, input_event.ORCA_CTRL_ALT_MODIFIER_MASK, 1]
-    ]
     floopyDooHandler.description = _("Floopy doo.")
+    floopyDooHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "a", 
+            input_event.defaultModifierMask, 
+            input_event.ORCA_CTRL_ALT_MODIFIER_MASK)
+    ]
 
-    def floopyDeeHandler(self, inputEvent=None, modifiers=None):
+    def floopyDeeHandler(self, inputEvent=None):
         """The floopy dee handler.
         """
         log.debug("floopyDeeHandler: %s" % inputEvent)
-    floopyDeeHandler.keyboardBindings = [
-        ["b", input_event.defaultModifierMask, input_event.ORCA_CTRL_ALT_MODIFIER_MASK, 1]
-    ]
     floopyDeeHandler.description = _("Floopy dee.")
+    floopyDeeHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "b", 
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_ALT_MODIFIER_MASK,
+            2)
+    ]
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/plugins/bookmarks/Makefile.am
==============================================================================
--- branches/phase2/src/orca/plugins/bookmarks/Makefile.am	(original)
+++ branches/phase2/src/orca/plugins/bookmarks/Makefile.am	Fri Sep 26 19:16:35 2008
@@ -2,8 +2,6 @@
 
 orca_python_PYTHON = \
 	__init__.py \
-	braille_bindings.py \
-	keyboard_bindings.py \
 	plugin.py
 
 orca_pythondir=$(pyexecdir)/orca/plugins/bookmarks

Modified: branches/phase2/src/orca/plugins/bookmarks/plugin.py
==============================================================================
--- branches/phase2/src/orca/plugins/bookmarks/plugin.py	(original)
+++ branches/phase2/src/orca/plugins/bookmarks/plugin.py	Fri Sep 26 19:16:35 2008
@@ -25,19 +25,12 @@
 import logging
 log = logging.getLogger('orca.plugins.bookmarks.plugin')
 
-import orca.input_bindings as input_bindings
+import orca.input_binding as input_binding
+import orca.input_event as input_event
 import orca.plugin as plugin
 
 from orca.orca_i18n import _ # for gettext support
 
-from keyboard_bindings import bindings as keyboardBindings
-
-try:
-    from braille_bindings import bindings as brailleBindings
-except:
-    log.exception("Not using braille bindings because of this exception:")
-    brailleBindings = []
-
 class Plugin(plugin.Plugin):
     """A plugin for handling bookmarks.
     """
@@ -52,105 +45,105 @@
         """
         plugin.Plugin.__init__(self, owner, scriptSettings)
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-        """
-        handlers = plugin.Plugin._createInputEventHandlers(self)
-        handlers.update({
-            "bookmarkCurrentWhereAmI" : input_bindings.Handler(
-                Plugin._bookmarkCurrentWhereAmI,
-                # Translators: this command announces information regarding
-                # the relationship of the given bookmark to the current
-                # position
-                #
-                _("Bookmark where am I with respect to current position.")),
-
-            "goToBookmark" : input_bindings.Handler(
-                Plugin._goToBookmark,
-                # Translators: this command moves the current position to the
-                # location stored at the bookmark.
-                #
-                _("Go to bookmark.")),
-
-            "addBookmark" : input_bindings.Handler(
-                Plugin._addBookmark,
-                # Translators: this event handler binds an in-page accessible
-                # object location to the given input key command.
-                #
-                _("Add bookmark.")),
-
-            "saveBookmarks" : input_bindings.Handler(
-                Plugin._saveBookmarks,
-                # Translators: this event handler saves all bookmarks for the
-                # current application to disk.
-                #
-                _("Save bookmarks.")),
-
-            "goToNextBookmark" : input_bindings.Handler(
-                Plugin._goToNextBookmark,
-                # Translators: this event handler cycles through the registered
-                # bookmarks and takes the user to the next bookmark location.
-                #
-                _("Go to next bookmark location.")),
-
-            "goToPrevBookmark" : input_bindings.Handler(
-                Plugin._goToPrevBookmark,
-                # Translators: this event handler cycles through the
-                # registered bookmarks and takes the user to the previous
-                # bookmark location.
-                #
-                _("Go to previous bookmark location.")),
-        })
-        return handlers
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        bindings = plugin.Plugin._createKeyboardBindings(self, handlers)
-        bindings.extend(keyboardBindings)
-        return bindings
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings.
-        """
-        bindings = plugin.Plugin._createBrailleBindings(self, handlers)
-        bindings.extend(brailleBindings)
-        return bindings
-
-    def _bookmarkCurrentWhereAmI(self, inputEvent=None, modifiers=None):
-        """The bookmarkCurrentWhereAmI handler.
-        """
-        log.debug("_bookmarkCurrentWhereAmI: %s" % inputEvent)
-
-    def _goToBookmark(self, inputEvent=None, modifiers=None):
-        """The goToBookmark handler.
-        """
-        log.debug("_goToBookmark: %s" % inputEvent)
-
-    def _addBookmark(self, inputEvent=None, modifiers=None):
-        """The addBookmark handler.
-        """
-        log.debug("_addBookmark: %s" % inputEvent)
-
-    def _saveBookmarks(self, inputEvent=None, modifiers=None):
-        """The saveBookmarks handler.
-        """
-        log.debug("_saveBookmarks: %s" % inputEvent)
-
-    def _goToNextBookmark(self, inputEvent=None, modifiers=None):
-        """The goToNextBookmark handler.
-        """
-        log.debug("_goToNextBookmark: %s" % inputEvent)
-
-    def _goToPrevBookmark(self, inputEvent=None, modifiers=None):
-        """The goToPrevBookmark handler.
+    def _bookmarkCurrentWhereAmIHandler(self, inputEvent=None):
+        """The bookmarkCurrentWhereAmIHandler handler.
         """
-        log.debug("_goToPrevBookmark: %s" % inputEvent)
+        log.debug("_bookmarkCurrentWhereAmIHandler: %s" % inputEvent)
+    # Translators: this command announces information regarding
+    # the relationship of the given bookmark to the current
+    # position
+    #
+    _bookmarkCurrentWhereAmIHandler.description = \
+        _("Bookmark where am I with respect to current position.")
+    _bookmarkCurrentWhereAmIHandler.bindings = \
+        map(lambda x: input_binding.KeyboardBinding(
+                          str(x),
+                          input_event.defaultModifierMask,
+                          input_event.SHIFT_ALT_MODIFIER_MASK),
+            xrange(1, 7))
+
+    def _goToBookmarkHandler(self, inputEvent=None):
+        """The goToBookmarkHandler handler.
+        """
+        log.debug("_goToBookmarkHandler: %s" % inputEvent)
+    # Translators: this command moves the current position to the
+    # location stored at the bookmark.
+    #
+    _goToBookmarkHandler.description = \
+        _("Go to bookmark.")
+    _goToBookmarkHandler.bindings = \
+        map(lambda x: input_binding.KeyboardBinding(
+                          str(x),
+                          input_event.defaultModifierMask,
+                          input_event.ORCA_MODIFIER_MASK),
+            xrange(1, 7))
+
+    def _addBookmarkHandler(self, inputEvent=None):
+        """The addBookmarkHandler handler.
+        """
+        log.debug("_addBookmarkHandler: %s" % inputEvent)
+    # Translators: this event handler binds an in-page accessible
+    # object location to the given input key command.
+    #
+    _addBookmarkHandler.description = \
+        _("Add bookmark.")
+    _addBookmarkHandler.bindings = \
+        map(lambda x: input_binding.KeyboardBinding(
+                          str(x),
+                          input_event.defaultModifierMask,
+                          input_event.ORCA_ALT_MODIFIER_MASK),
+            xrange(1, 7))
+
+    def _saveBookmarksHandler(self, inputEvent=None):
+        """The saveBookmarksHandler handler.
+        """
+        log.debug("_saveBookmarksHandler: %s" % inputEvent)
+    # Translators: this event handler saves all bookmarks for the
+    # current application to disk.
+    #
+    _saveBookmarksHandler.description = \
+        _("Save bookmarks.")
+    _saveBookmarksHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "b",
+            input_event.defaultModifierMask,
+            input_event.ORCA_ALT_MODIFIER_MASK)
+    ]
+
+    def _goToNextBookmarkHandler(self, inputEvent=None):
+        """The goToNextBookmarkHandler handler.
+        """
+        log.debug("_goToNextBookmarkHandler: %s" % inputEvent)
+    # Translators: this event handler cycles through the registered
+    # bookmarks and takes the user to the next bookmark location.
+    #
+    _goToNextBookmarkHandler.description = \
+        _("Go to next bookmark location.")
+    _goToNextBookmarkHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "b",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            "goToNextBookmark"),
+    ]
+
+    def _goToPrevBookmarkHandler(self, inputEvent=None):
+        """The goToPrevBookmarkHandler handler.
+        """
+        log.debug("_goToPrevBookmarkHandler: %s" % inputEvent)
+    # Translators: this event handler cycles through the
+    # registered bookmarks and takes the user to the previous
+    # bookmark location.
+    #
+    _goToPrevBookmarkHandler.description = \
+        _("Go to previous bookmark location.")
+    _goToPrevBookmarkHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "b",
+            input_event.defaultModifierMask,
+            input_event.ORCA_SHIFT_MODIFIER_MASK,
+            "goToPrevBookmark")
+    ]
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/plugins/debug_actions/Makefile.am
==============================================================================
--- branches/phase2/src/orca/plugins/debug_actions/Makefile.am	(original)
+++ branches/phase2/src/orca/plugins/debug_actions/Makefile.am	Fri Sep 26 19:16:35 2008
@@ -2,8 +2,6 @@
 
 orca_python_PYTHON = \
 	__init__.py \
-	braille_bindings.py \
-	keyboard_bindings.py \
 	plugin.py
 
 orca_pythondir=$(pyexecdir)/orca/plugins/debug_actions

Modified: branches/phase2/src/orca/plugins/debug_actions/plugin.py
==============================================================================
--- branches/phase2/src/orca/plugins/debug_actions/plugin.py	(original)
+++ branches/phase2/src/orca/plugins/debug_actions/plugin.py	Fri Sep 26 19:16:35 2008
@@ -25,19 +25,14 @@
 import logging
 log = logging.getLogger('orca.plugins.debug_actions.plugin')
 
-import orca.input_bindings as input_bindings
+import brlapi
+
+import orca.input_binding as input_binding
+import orca.input_event as input_event
 import orca.plugin as plugin
 
 from orca.orca_i18n import _ # for gettext support
 
-from keyboard_bindings import bindings as keyboardBindings
-
-try:
-    from braille_bindings import bindings as brailleBindings
-except:
-    log.exception("Not using braille bindings because of this exception:")
-    brailleBindings = []
-
 class Plugin(plugin.Plugin):
     """A plugin for getting debug information.
     """
@@ -52,96 +47,86 @@
         """
         plugin.Plugin.__init__(self, owner, scriptSettings)
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-        """
-        handlers = plugin.Plugin._createInputEventHandlers(self)
-        handlers.update({
-            "printAppsHandler" : input_bindings.Handler(
-                Plugin._printAppsHandler,
-                # Translators: this is a debug message that Orca users
-                # will not normally see. It describes a debug routine
-                # that prints a list of all known applications currently
-                # running on the desktop, to stdout.
-                #
-                _("Prints a debug listing of all known applications to the " \
-                  "console where Orca is running.")),
-
-            "printAncestryHandler" : input_bindings.Handler(
-                Plugin._printAncestryHandler,
-                # Translators: this is a debug message that Orca users
-                # will not normally see. It describes a debug routine
-                # that will take the component in the currently running
-                # application that has focus, and print debug information
-                # to the console giving its component ancestry (i.e. all
-                # the components that are its descendants in the component
-                # tree).
-                #
-                _("Prints debug information about the ancestry of the " \
-                  "object with focus.")),
-
-            "printHierarchyHandler" : input_bindings.Handler(
-                Plugin._printHierarchyHandler,
-                # Translators: this is a debug message that Orca users
-                # will not normally see. It describes a debug routine
-                # that will take the currently running application, and
-                # print debug information to the console giving its
-                # component hierarchy (i.e. all the components and all
-                # their descendants in the component tree).
-                #
-                _("Prints debug information about the application with " \
-                  "focus.")),
-
-            "reportScriptInfoHandler" : input_bindings.Handler(
-                Plugin._reportScriptInfo,
-                # Translators: this is a debug message that Orca users
-                # will not normally see. It describes a debug routine
-                # that outputs useful information on the current script
-                #  via speech and braille. This information will be
-                # helpful to script writers.
-                #
-                _("Reports information on current script.")),
-        })
-        return handlers
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        bindings = plugin.Plugin._createKeyboardBindings(self, handlers)
-        bindings.extend(keyboardBindings)
-        return bindings
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings.
-        """
-        bindings = plugin.Plugin._createBrailleBindings(self, handlers)
-        bindings.extend(brailleBindings)
-        return bindings
-
-    def _printAppsHandler(self, inputEvent=None, modifiers=None):
+    def _printAppsHandler(self, inputEvent=None):
         """The printAppsHandler handler.
         """
         log.debug("_printAppsHandler: %s" % inputEvent)
+    # Translators: this is a debug message that Orca users
+    # will not normally see. It describes a debug routine
+    # that prints a list of all known applications currently
+    # running on the desktop, to stdout.
+    #
+    _printAppsHandler.description = \
+        _("Prints a debug listing of all known applications to the " \
+          "console where Orca is running.")
+    _printAppsHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "End",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_ALT_MODIFIER_MASK)
+    ]
 
-    def _printAncestryHandler(self, inputEvent=None, modifiers=None):
+    def _printAncestryHandler(self, inputEvent=None):
         """The printAncestryHandler handler.
         """
         log.debug("_printAncestryHandler: %s" % inputEvent)
+    # Translators: this is a debug message that Orca users
+    # will not normally see. It describes a debug routine
+    # that will take the component in the currently running
+    # application that has focus, and print debug information
+    # to the console giving its component ancestry (i.e. all
+    # the components that are its descendants in the component
+    # tree).
+    #
+    _printAncestryHandler.description = \
+        _("Prints debug information about the ancestry of the " \
+          "object with focus.")
+    _printAncestryHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "Page_Up",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_ALT_MODIFIER_MASK)
+    ]
 
-    def _printHierarchyHandler(self, inputEvent=None, modifiers=None):
+    def _printHierarchyHandler(self, inputEvent=None):
         """The printHierarchyHandler handler.
         """
         log.debug("_printHierarchyHandler: %s" % inputEvent)
+    # Translators: this is a debug message that Orca users
+    # will not normally see. It describes a debug routine
+    # that will take the currently running application, and
+    # print debug information to the console giving its
+    # component hierarchy (i.e. all the components and all
+    # their descendants in the component tree).
+    #
+    _printHierarchyHandler.description = \
+        _("Prints debug information about the application with " \
+          "focus.")
+    _printHierarchyHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "Page_Down",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_ALT_MODIFIER_MASK)
+    ]
 
-    def _reportScriptInfo(self, inputEvent=None, modifiers=None):
+    def _reportScriptInfoHandler(self, inputEvent=None):
         """The reportScriptInfo handler.
         """
-        log.debug("_reportScriptInfo: %s" % inputEvent)
+        log.debug("_reportScriptInfoHandler: %s" % inputEvent)
+    # Translators: this is a debug message that Orca users
+    # will not normally see. It describes a debug routine
+    # that outputs useful information on the current script
+    #  via speech and braille. This information will be
+    # helpful to script writers.
+    #
+    _reportScriptInfoHandler.description = \
+        _("Reports information on current script.")
+    _reportScriptInfoHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "Home",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_ALT_MODIFIER_MASK)
+    ]
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/plugins/flat_review/Makefile.am
==============================================================================
--- branches/phase2/src/orca/plugins/flat_review/Makefile.am	(original)
+++ branches/phase2/src/orca/plugins/flat_review/Makefile.am	Fri Sep 26 19:16:35 2008
@@ -2,8 +2,6 @@
 
 orca_python_PYTHON = \
 	__init__.py \
-	braille_bindings.py \
-	keyboard_bindings.py \
 	plugin.py
 
 orca_pythondir=$(pyexecdir)/orca/plugins/flat_review

Modified: branches/phase2/src/orca/plugins/flat_review/plugin.py
==============================================================================
--- branches/phase2/src/orca/plugins/flat_review/plugin.py	(original)
+++ branches/phase2/src/orca/plugins/flat_review/plugin.py	Fri Sep 26 19:16:35 2008
@@ -25,19 +25,15 @@
 import logging
 log = logging.getLogger('orca.plugins.flat_review.plugin')
 
-import orca.input_bindings as input_bindings
+import brlapi
+
+import orca.input_binding as input_binding
+import orca.input_event as input_event
 import orca.plugin as plugin
+import orca.settings as settings
 
 from orca.orca_i18n import _ # for gettext support
 
-from keyboard_bindings import bindings as keyboardBindings
-
-try:
-    from braille_bindings import bindings as brailleBindings
-except:
-    log.exception("Not using braille bindings because of this exception:")
-    brailleBindings = []
-
 class Plugin(plugin.Plugin):
     """A plugin for handling flat review analysis of a window.
     """
@@ -52,566 +48,944 @@
         """
         plugin.Plugin.__init__(self, owner, scriptSettings)
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-        """
-        handlers = plugin.Plugin._createInputEventHandlers(self)
-        handlers.update({
-            "leftClickReviewItemHandler" : input_bindings.Handler(
-                Plugin._leftClickReviewItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  A left click means to generate
-                # a left mouse button click on the current item.
-                #
-                _("Performs left click on current flat review item.")),
-
-            "rightClickReviewItemHandler" : input_bindings.Handler(
-                Plugin._rightClickReviewItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  A right click means to generate
-                # a right mouse button click on the current item.
-                #
-                _("Performs right click on current flat review item.")),
-
-            "toggleFlatReviewModeHandler" : input_bindings.Handler(
-                Plugin._toggleFlatReviewMode,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.
-                #
-                _("Enters and exits flat review mode.")),
-
-            "reviewPreviousLineHandler" : input_bindings.Handler(
-                Plugin._reviewPreviousLine,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.
-                #
-                _("Moves flat review to the beginning of the previous line.")),
-
-            "reviewHomeHandler" : input_bindings.Handler(
-                Plugin._reviewHome,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  The home position is the
-                # beginning of the content in the window.
-                #
-                _("Moves flat review to the home position.")),
-
-            "reviewCurrentLineHandler" : input_bindings.Handler(
-                Plugin._reviewCurrentLine,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  This particular command will
-                # cause Orca to speak the current line.
-                #
-                _("Speaks the current flat review line.")),
-
-            "reviewSpellCurrentLineHandler" : input_bindings.Handler(
-                Plugin._reviewSpellCurrentLine,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}. This particular command will
-                # cause Orca to spell the current line.
-                #
-                _("Spells the current flat review line.")),
-
-            "reviewPhoneticCurrentLineHandler" : input_bindings.Handler(
-                Plugin._reviewPhoneticCurrentLine,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}. This particular command will
-                # cause Orca to "phonetically spell" the current line,
-                # saying "Alpha" for "a", "Bravo" for "b" and so on.
-                #
-                _("Phonetically spells the current flat review line.")),
-
-            "reviewNextLineHandler" : input_bindings.Handler(
-                Plugin._reviewNextLine,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.
-                #
-                _("Moves flat review to the beginning of the next line.")),
-
-            "reviewEndHandler" : input_bindings.Handler(
-                Plugin._reviewEnd,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  The end position is the last
-                # bit of information in the window.
-                #
-                _("Moves flat review to the end position.")),
-
-            "reviewPreviousItemHandler" : input_bindings.Handler(
-                Plugin._reviewPreviousItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Previous will go backwards
-                # in the window until you reach the top (i.e., it will
-                # wrap across lines if necessary).
-                #
-                _("Moves flat review to the previous item or word.")),
-
-            "reviewAboveHandler" : input_bindings.Handler(
-                Plugin._reviewAbove,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Above in this case means
-                # geographically above, as if you drew a vertical line
-                # in the window.
-                #
-                _("Moves flat review to the word above the current word.")),
-
-            "reviewCurrentItemHandler" : input_bindings.Handler(
-                Plugin._reviewCurrentItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  This command will speak the
-                # current word or item.
-                #
-                _("Speaks the current flat review item or word.")),
-
-            "reviewSpellCurrentItemHandler" : input_bindings.Handler(
-                Plugin._reviewSpellCurrentItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  This command will spell out
-                # the current word or item letter by letter.
-                #
-                _("Spells the current flat review item or word.")),
-
-            "reviewPhoneticCurrentItemHandler" : input_bindings.Handler(
-                Plugin._reviewPhoneticCurrentItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  This command will spell out
-                # the current word or item phonetically, saying "Alpha"
-                # for "a", "Bravo" for "b" and so on.
-                #
-                _("Phonetically spells the current flat review item or " \
-                  "word.")),
-
-            "reviewCurrentAccessibleHandler" : input_bindings.Handler(
-                Plugin._reviewCurrentAccessible,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  The flat review object is
-                # typically something like a pushbutton, a label, or
-                # some other GUI widget.  The 'speaks' means it will
-                # speak the text associated with the object.
-                #
-                _("Speaks the current flat review object.")),
-
-            "reviewNextItemHandler" : input_bindings.Handler(
-                Plugin._reviewNextItem,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Next will go forwards
-                # in the window until you reach the end (i.e., it will
-                # wrap across lines if necessary).
-                #
-                _("Moves flat review to the next item or word.")),
-
-            "reviewBelowHandler" : input_bindings.Handler(
-                Plugin._reviewBelow,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Below in this case means
-                # geographically below, as if you drew a vertical line
-                # downward on the screen.
-                #
-                _("Moves flat review to the word below the current word.")),
-
-            "reviewPreviousCharacterHandler" : input_bindings.Handler(
-                Plugin._reviewPreviousCharacter,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Previous will go backwards
-                # in the window until you reach the top (i.e., it will
-                # wrap across lines if necessary).
-                #
-                _("Moves flat review to the previous character.")),
-
-            "reviewEndOfLineHandler" : input_bindings.Handler(
-                Plugin._reviewEndOfLine,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.
-                #
-                _("Moves flat review to the end of the line.")),
-
-            "reviewCurrentCharacterHandler" : input_bindings.Handler(
-                Plugin._reviewCurrentCharacter,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Previous will go backwards
-                # in the window until you reach the top (i.e., it will
-                # wrap across lines if necessary).  The 'speaks' in
-                # this case will be the spoken language form of the
-                # character currently being reviewed.
-                #
-                _("Speaks the current flat review character.")),
-
-            "reviewSpellCurrentCharacterHandler" : input_bindings.Handler(
-                Plugin._reviewSpellCurrentCharacter,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Previous will go backwards
-                # in the window until you reach the top (i.e., it will
-                # wrap across lines if necessary).  This command will
-                # cause Orca to speak a phonetic representation of the
-                # character currently being reviewed, saying "Alpha"
-                # for "a", "Bravo" for "b" and so on.
-                #
-                _("Phonetically speaks the current flat review character.")),
-
-            "reviewNextCharacterHandler" : input_bindings.Handler(
-                Plugin._reviewNextCharacter,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Next will go forwards
-                # in the window until you reach the end (i.e., it will
-                # wrap across lines if necessary).
-                #
-                _("Moves flat review to the next character.")),
-            "reviewBottomLeftHandler" : input_bindings.Handler(
-                Plugin._reviewBottomLeft,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  The bottom left is the bottom
-                # left of the window currently being reviewed.
-                #
-                _("Moves flat review to the bottom left.")),
-
-            "findHandler" : input_bindings.Handler(
-                Plugin._showFindGUI,
-                # Translators: the Orca "Find" dialog allows a user to
-                # search for text in a window and then move focus to
-                # that text.  For example, they may want to find the
-                # "OK" button.
-                #
-                _("Opens the Orca Find dialog.")),
-
-            "findNextHandler" : input_bindings.Handler(
-                Plugin._findNext,
-                # Translators: the Orca "Find" dialog allows a user to
-                # search for text in a window and then move focus to
-                # that text.  For example, they may want to find the
-                # "OK" button.  This string is used for finding the
-                # next occurence of a string.
-                #
-                _("Searches for the next instance of a string.")),
-
-            "findPreviousHandler" : input_bindings.Handler(
-                Plugin._findPrevious,
-                # Translators: the Orca "Find" dialog allows a user to
-                # search for text in a window and then move focus to
-                # that text.  For example, they may want to find the
-                # "OK" button.  This string is used for finding the
-                # previous occurence of a string.
-                #
-                _("Searches for the previous instance of a string.")),
-
-            "goBrailleHomeHandler" : input_bindings.Handler(
-                Plugin._goBrailleHome,
-                # Translators: the 'flat review' feature of Orca
-                # allows the blind user to explore the text in a
-                # window in a 2D fashion.  That is, Orca treats all
-                # the text from all objects in a window (e.g.,
-                # buttons, labels, etc.) as a sequence of words in a
-                # sequence of lines.  The flat review feature allows
-                # the user to explore this text by the {previous,next}
-                # {line,word,character}.  Flat review is modal, and
-                # the user can be exploring the window without changing
-                # which object in the window which has focus.  The
-                # feature used here will return the flat review to the
-                # object with focus.
-                #
-                _("Returns to object with keyboard focus.")),
-        })
-        return handlers
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        bindings = plugin.Plugin._createKeyboardBindings(self, handlers)
-        bindings.extend(keyboardBindings)
-        return bindings
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings.
-        """
-        bindings = plugin.Plugin._createBrailleBindings(self, handlers)
-        bindings.extend(brailleBindings)
-        return bindings
-
-    def _leftClickReviewItem(self, inputEvent=None, modifiers=None):
-        """The leftClickReviewItem handler.
-        """
-        log.debug("_leftClickReviewItem: %s" % inputEvent)
-
-    def _rightClickReviewItem(self, inputEvent=None, modifiers=None):
-        """The rightClickReviewItem handler.
-        """
-        log.debug("_rightClickReviewItem: %s" % inputEvent)
-
-    def _toggleFlatReviewMode(self, inputEvent=None, modifiers=None):
-        """The toggleFlatReviewMode handler.
-        """
-        log.debug("_toggleFlatReviewMode: %s" % inputEvent)
-
-    def _reviewPreviousLine(self, inputEvent=None, modifiers=None):
-        """The reviewPreviousLine handler.
-        """
-        log.debug("_reviewPreviousLine: %s" % inputEvent)
-
-    def _reviewHome(self, inputEvent=None, modifiers=None):
-        """The reviewHome handler.
-        """
-        log.debug("_reviewHome: %s" % inputEvent)
-
-    def _reviewCurrentLine(self, inputEvent=None, modifiers=None):
-        """The reviewCurrentLine handler.
-        """
-        log.debug("_reviewCurrentLine: %s" % inputEvent)
-
-    def _reviewSpellCurrentLine(self, inputEvent=None, modifiers=None):
-        """The reviewSpellCurrentLine handler.
-        """
-        log.debug("_reviewSpellCurrentLine: %s" % inputEvent)
-
-    def _reviewPhoneticCurrentLine(self, inputEvent=None, modifiers=None):
-        """The reviewPhoneticCurrentLine handler.
-        """
-        log.debug("_reviewPhoneticCurrentLine: %s" % inputEvent)
-
-    def _reviewNextLine(self, inputEvent=None, modifiers=None):
-        """The reviewNextLine handler.
-        """
-        log.debug("_reviewNextLine: %s" % inputEvent)
-
-    def _reviewEnd(self, inputEvent=None, modifiers=None):
-        """The reviewEnd handler.
-        """
-        log.debug("_reviewEnd: %s" % inputEvent)
-
-    def _reviewPreviousItem(self, inputEvent=None, modifiers=None):
-        """The reviewPreviousItem handler.
-        """
-        log.debug("_reviewPreviousItem: %s" % inputEvent)
-
-    def _reviewAbove(self, inputEvent=None, modifiers=None):
-        """The reviewAbove handler.
-        """
-        log.debug("_reviewAbove: %s" % inputEvent)
-
-    def _reviewCurrentItem(self, inputEvent=None, modifiers=None):
-        """The reviewCurrentItem handler.
-        """
-        log.debug("_reviewCurrentItem: %s" % inputEvent)
-
-    def _reviewSpellCurrentItem(self, inputEvent=None, modifiers=None):
-        """The reviewSpellCurrentItem handler.
-        """
-        log.debug("_reviewSpellCurrentItem: %s" % inputEvent)
-
-    def _reviewPhoneticCurrentItem(self, inputEvent=None, modifiers=None):
-        """The reviewPhoneticCurrentItem handler.
-        """
-        log.debug("_reviewPhoneticCurrentItem: %s" % inputEvent)
-
-    def _reviewCurrentAccessible(self, inputEvent=None, modifiers=None):
-        """The reviewCurrentAccessible handler.
-        """
-        log.debug("_reviewCurrentAccessible: %s" % inputEvent)
-
-    def _reviewNextItem(self, inputEvent=None, modifiers=None):
-        """The reviewNextItem handler.
-        """
-        log.debug("_reviewNextItem: %s" % inputEvent)
-
-    def _reviewBelow(self, inputEvent=None, modifiers=None):
-        """The reviewBelow handler.
-        """
-        log.debug("_reviewBelow: %s" % inputEvent)
-
-    def _reviewPreviousCharacter(self, inputEvent=None, modifiers=None):
-        """The reviewPreviousCharacter handler.
-        """
-        log.debug("_reviewPreviousCharacter: %s" % inputEvent)
-
-    def _reviewEndOfLine(self, inputEvent=None, modifiers=None):
-        """The reviewEndOfLine handler.
-        """
-        log.debug("_reviewEndOfLine: %s" % inputEvent)
-
-    def _reviewCurrentCharacter(self, inputEvent=None, modifiers=None):
-        """The reviewCurrentCharacter handler.
-        """
-        log.debug("_reviewCurrentCharacter: %s" % inputEvent)
-
-    def _reviewSpellCurrentCharacter(self, inputEvent=None, modifiers=None):
-        """The reviewSpellCurrentCharacter handler.
-        """
-        log.debug("_reviewSpellCurrentCharacter: %s" % inputEvent)
-
-    def _reviewNextCharacter(self, inputEvent=None, modifiers=None):
-        """The reviewNextCharacter handler.
-        """
-        log.debug("_reviewNextCharacter: %s" % inputEvent)
-
-    def _reviewBottomLeft(self, inputEvent=None, modifiers=None):
-        """The reviewBottomLeft handler.
-        """
-        log.debug("_reviewBottomLeft: %s" % inputEvent)
-
-    def _showFindGUI(self, inputEvent=None, modifiers=None):
-        """The showFindGUI handler.
-        """
-        log.debug("_showFindGUI: %s" % inputEvent)
-
-    def _findNext(self, inputEvent=None, modifiers=None):
-        """The findNext handler.
-        """
-        log.debug("_findNext: %s" % inputEvent)
-
-    def _findPrevious(self, inputEvent=None, modifiers=None):
-        """The findPrevious handler.
-        """
-        log.debug("_findPrevious: %s" % inputEvent)
-
-    def _goBrailleHome(self, inputEvent=None, modifiers=None):
-        """The goBrailleHome handler.
+    def _leftClickReviewItemHandler(self, inputEvent=None):
+        """The leftClickReviewItemHandler handler.
         """
-        log.debug("_goBrailleHome: %s" % inputEvent)
+        log.debug("_leftClickReviewItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  A left click means to generate
+    # a left mouse button click on the current item.
+    #
+    _leftClickReviewItemHandler.description = \
+        _("Performs left click on current flat review item.")
+    _leftClickReviewItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Divide",
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "7",
+            input_event.ORCA_MODIFIER_MASK,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _rightClickReviewItemHandler(self, inputEvent=None):
+        """The rightClickReviewItemHandler handler.
+        """
+        log.debug("_rightClickReviewItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  A right click means to generate
+    # a right mouse button click on the current item.
+    #
+    _rightClickReviewItemHandler.description = \
+        _("Performs right click on current flat review item.")
+    _rightClickReviewItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Multiply",
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "8",
+            input_event.ORCA_MODIFIER_MASK,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _toggleFlatReviewModeHandler(self, inputEvent=None):
+        """The toggleFlatReviewModeHandler handler.
+        """
+        log.debug("_toggleFlatReviewModeHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.
+    #
+    _toggleFlatReviewModeHandler.description = \
+        _("Enters and exits flat review mode.")
+    _toggleFlatReviewModeHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Subtract",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "p",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewPreviousLineHandler(self, inputEvent=None):
+        """The reviewPreviousLineHandler handler.
+        """
+        log.debug("_reviewPreviousLineHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.
+    #
+    _reviewPreviousLineHandler.description = \
+        _("Moves flat review to the beginning of the previous line.")
+    _reviewPreviousLineHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_7",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Home",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "u",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewHomeHandler(self, inputEvent=None):
+        """The reviewHomeHandler handler.
+        """
+        log.debug("_reviewHomeHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  The home position is the
+    # beginning of the content in the window.
+    #
+    _reviewHomeHandler.description = \
+        _("Moves flat review to the home position.")
+    _reviewHomeHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_7",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Home",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "u",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewCurrentLineHandler(self, inputEvent=None):
+        """The reviewCurrentLineHandler handler.
+        """
+        log.debug("_reviewCurrentLineHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  This particular command will
+    # cause Orca to speak the current line.
+    #
+    _reviewCurrentLineHandler.description = \
+        _("Speaks the current flat review line.")
+    _reviewCurrentLineHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_8",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Up",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "i",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_TOP_LEFT,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK)
+    ]
+
+    def _reviewSpellCurrentLineHandler(self, inputEvent=None):
+        """The reviewSpellCurrentLineHandler handler.
+        """
+        log.debug("_reviewSpellCurrentLineHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}. This particular command will
+    # cause Orca to spell the current line.
+    #
+    _reviewSpellCurrentLineHandler.description = \
+        _("Spells the current flat review line.")
+    _reviewSpellCurrentLineHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_8",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Up",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "i",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewPhoneticCurrentLineHandler(self, inputEvent=None):
+        """The reviewPhoneticCurrentLineHandler handler.
+        """
+        log.debug("_reviewPhoneticCurrentLineHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}. This particular command will
+    # cause Orca to "phonetically spell" the current line,
+    # saying "Alpha" for "a", "Bravo" for "b" and so on.
+    #
+    _reviewPhoneticCurrentLineHandler.description = \
+        _("Phonetically spells the current flat review line.")
+    _reviewPhoneticCurrentLineHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_8",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 3,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Up",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 3,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "i",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 3,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewNextLineHandler(self, inputEvent=None):
+        """The reviewNextLineHandler handler.
+        """
+        log.debug("_reviewNextLineHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.
+    #
+    _reviewNextLineHandler.description = \
+        _("Moves flat review to the beginning of the next line.")
+    _reviewNextLineHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_9",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Page_Up",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "o",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewEndHandler(self, inputEvent=None):
+        """The reviewEndHandler handler.
+        """
+        log.debug("_reviewEndHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  The end position is the last
+    # bit of information in the window.
+    #
+    _reviewEndHandler.description = \
+        _("Moves flat review to the end position.")
+    _reviewEndHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_9",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Page_Up",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "o",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewPreviousItemHandler(self, inputEvent=None):
+        """The reviewPreviousItemHandler handler.
+        """
+        log.debug("_reviewPreviousItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Previous will go backwards
+    # in the window until you reach the top (i.e., it will
+    # wrap across lines if necessary).
+    #
+    _reviewPreviousItemHandler.description = \
+        _("Moves flat review to the previous item or word.")
+    _reviewPreviousItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_4",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Left",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "j",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewAboveHandler(self, inputEvent=None):
+        """The reviewAboveHandler handler.
+        """
+        log.debug("_reviewAboveHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Above in this case means
+    # geographically above, as if you drew a vertical line
+    # in the window.
+    #
+    _reviewAboveHandler.description = \
+        _("Moves flat review to the word above the current word.")
+    _reviewAboveHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_4",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Left",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK, 
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "j",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_LNUP,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK),
+    ]
+
+    def _reviewCurrentItemHandler(self, inputEvent=None):
+        """The reviewCurrentItemHandler handler.
+        """
+        log.debug("_reviewCurrentItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  This command will speak the
+    # current word or item.
+    #
+    _reviewCurrentItemHandler.description = \
+        _("Speaks the current flat review item or word.")
+    _reviewCurrentItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_5",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Begin",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "k",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewSpellCurrentItemHandler(self, inputEvent=None):
+        """The reviewSpellCurrentItemHandler handler.
+        """
+        log.debug("_reviewSpellCurrentItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  This command will spell out
+    # the current word or item letter by letter.
+    #
+    _reviewSpellCurrentItemHandler.description = \
+        _("Spells the current flat review item or word.")
+    _reviewSpellCurrentItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_5",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Begin",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "k",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewPhoneticCurrentItemHandler(self, inputEvent=None):
+        """The reviewPhoneticCurrentItemHandler handler.
+        """
+        log.debug("_reviewPhoneticCurrentItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  This command will spell out
+    # the current word or item phonetically, saying "Alpha"
+    # for "a", "Bravo" for "b" and so on.
+    #
+    _reviewPhoneticCurrentItemHandler.description = \
+        _("Phonetically spells the current flat review item or word.")
+    _reviewPhoneticCurrentItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_5",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 3,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Begin",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 3,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "k",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 3,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewCurrentAccessibleHandler(self, inputEvent=None):
+        """The reviewCurrentAccessibleHandler handler.
+        """
+        log.debug("_reviewCurrentAccessibleHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  The flat review object is
+    # typically something like a pushbutton, a label, or
+    # some other GUI widget.  The 'speaks' means it will
+    # speak the text associated with the object.
+    #
+    _reviewCurrentAccessibleHandler.description = \
+        _("Speaks the current flat review object.")
+    _reviewCurrentAccessibleHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_5",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Begin",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "k",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewNextItemHandler(self, inputEvent=None):
+        """The reviewNextItemHandler handler.
+        """
+        log.debug("_reviewNextItemHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Next will go forwards
+    # in the window until you reach the end (i.e., it will
+    # wrap across lines if necessary).
+    #
+    _reviewNextItemHandler.description = \
+        _("Moves flat review to the next item or word.")
+    _reviewNextItemHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_6",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Right",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "l",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewBelowHandler(self, inputEvent=None):
+        """The reviewBelowHandler handler.
+        """
+        log.debug("_reviewBelowHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Below in this case means
+    # geographically below, as if you drew a vertical line
+    # downward on the screen.
+    #
+    _reviewBelowHandler.description = \
+        _("Moves flat review to the word below the current word.")
+    _reviewBelowHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_6",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Right",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "l",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_LNDN,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK),
+    ]
+
+    def _reviewPreviousCharacterHandler(self, inputEvent=None):
+        """The reviewPreviousCharacterHandler handler.
+        """
+        log.debug("_reviewPreviousCharacterHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Previous will go backwards
+    # in the window until you reach the top (i.e., it will
+    # wrap across lines if necessary).
+    #
+    _reviewPreviousCharacterHandler.description = \
+        _("Moves flat review to the previous character.")
+    _reviewPreviousCharacterHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_1",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_End",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "m",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewEndOfLineHandler(self, inputEvent=None):
+        """The reviewEndOfLineHandler handler.
+        """
+        log.debug("_reviewEndOfLineHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.
+    #
+    _reviewEndOfLineHandler.description = \
+        _("Moves flat review to the end of the line.")
+    _reviewEndOfLineHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_1",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_End",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "m",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewCurrentCharacterHandler(self, inputEvent=None):
+        """The reviewCurrentCharacterHandler handler.
+        """
+        log.debug("_reviewCurrentCharacterHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Previous will go backwards
+    # in the window until you reach the top (i.e., it will
+    # wrap across lines if necessary).  The 'speaks' in
+    # this case will be the spoken language form of the
+    # character currently being reviewed.
+    #
+    _reviewCurrentCharacterHandler.description = \
+        _("Speaks the current flat review character.")
+    _reviewCurrentCharacterHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_2",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Down",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "comma",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewSpellCurrentCharacterHandler(self, inputEvent=None):
+        """The reviewSpellCurrentCharacterHandler handler.
+        """
+        log.debug("_reviewSpellCurrentCharacterHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Previous will go backwards
+    # in the window until you reach the top (i.e., it will
+    # wrap across lines if necessary).  This command will
+    # cause Orca to speak a phonetic representation of the
+    # character currently being reviewed, saying "Alpha"
+    # for "a", "Bravo" for "b" and so on.
+    #
+    _reviewSpellCurrentCharacterHandler.description = \
+        _("Phonetically speaks the current flat review character.")
+    _reviewSpellCurrentCharacterHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_2",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Down",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "comma",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewNextCharacterHandler(self, inputEvent=None):
+        """The reviewNextCharacterHandler handler.
+        """
+        log.debug("_reviewNextCharacterHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Next will go forwards
+    # in the window until you reach the end (i.e., it will
+    # wrap across lines if necessary).
+    #
+    _reviewNextCharacterHandler.description = \
+        _("Moves flat review to the next character.")
+    _reviewNextCharacterHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_3",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "KP_Page_Down",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "period",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _reviewBottomLeftHandler(self, inputEvent=None):
+        """The reviewBottomLeftHandler handler.
+        """
+        log.debug("_reviewBottomLeftHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  The bottom left is the bottom
+    # left of the window currently being reviewed.
+    #
+    _reviewBottomLeftHandler.description = \
+        _("Moves flat review to the bottom left.")
+    _reviewBottomLeftHandler.bindings = [
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_BOT_LEFT,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK),
+    ]
+
+    def _showFindGUIHandler(self, inputEvent=None):
+        """The showFindGUIHandler handler.
+        """
+        log.debug("_showFindGUIHandler: %s" % inputEvent)
+    # Translators: the Orca "Find" dialog allows a user to
+    # search for text in a window and then move focus to
+    # that text.  For example, they may want to find the
+    # "OK" button.
+    #
+    _showFindGUIHandler.description = \
+        _("Opens the Orca Find dialog.")
+    _showFindGUIHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Delete",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "bracketleft",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _findNextHandler(self, inputEvent=None):
+        """The findNextHandler handler.
+        """
+        log.debug("_findNextHandler: %s" % inputEvent)
+    # Translators: the Orca "Find" dialog allows a user to
+    # search for text in a window and then move focus to
+    # that text.  For example, they may want to find the
+    # "OK" button.  This string is used for finding the
+    # next occurence of a string.
+    #
+    _findNextHandler.description = \
+        _("Searches for the next instance of a string.")
+    _findNextHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Delete",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "bracketright",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _findPreviousHandler(self, inputEvent=None):
+        """The findPreviousHandler handler.
+        """
+        log.debug("_findPreviousHandler: %s" % inputEvent)
+    # Translators: the Orca "Find" dialog allows a user to
+    # search for text in a window and then move focus to
+    # that text.  For example, they may want to find the
+    # "OK" button.  This string is used for finding the
+    # previous occurence of a string.
+    #
+    _findPreviousHandler.description = \
+        _("Searches for the previous instance of a string.")
+    _findPreviousHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Delete",
+            input_event.defaultModifierMask,
+            input_event.ORCA_SHIFT_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "bracketright",
+            input_event.defaultModifierMask,
+            input_event.ORCA_CTRL_MODIFIER_MASK,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP),
+    ]
+
+    def _goBrailleHomeHandler(self, inputEvent=None):
+        """The goBrailleHomeHandler handler.
+        """
+        log.debug("_goBrailleHomeHandler: %s" % inputEvent)
+    # Translators: the 'flat review' feature of Orca
+    # allows the blind user to explore the text in a
+    # window in a 2D fashion.  That is, Orca treats all
+    # the text from all objects in a window (e.g.,
+    # buttons, labels, etc.) as a sequence of words in a
+    # sequence of lines.  The flat review feature allows
+    # the user to explore this text by the {previous,next}
+    # {line,word,character}.  Flat review is modal, and
+    # the user can be exploring the window without changing
+    # which object in the window which has focus.  The
+    # feature used here will return the flat review to the
+    # object with focus.
+    #
+    _goBrailleHomeHandler.description = \
+        _("Returns to object with keyboard focus.")
+    _goBrailleHomeHandler.bindings = [
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_HOME,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK),
+    ]
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/plugins/speech_parameters/Makefile.am
==============================================================================
--- branches/phase2/src/orca/plugins/speech_parameters/Makefile.am	(original)
+++ branches/phase2/src/orca/plugins/speech_parameters/Makefile.am	Fri Sep 26 19:16:35 2008
@@ -2,8 +2,6 @@
 
 orca_python_PYTHON = \
 	__init__.py \
-	braille_bindings.py \
-	keyboard_bindings.py \
 	plugin.py
 
 orca_pythondir=$(pyexecdir)/orca/plugins/speech_parameters

Modified: branches/phase2/src/orca/plugins/speech_parameters/plugin.py
==============================================================================
--- branches/phase2/src/orca/plugins/speech_parameters/plugin.py	(original)
+++ branches/phase2/src/orca/plugins/speech_parameters/plugin.py	Fri Sep 26 19:16:35 2008
@@ -25,19 +25,14 @@
 import logging
 log = logging.getLogger('orca.plugins.speech_parameters.plugin')
 
-import orca.input_bindings as input_bindings
+import brlapi
+
+import orca.input_binding as input_binding
+import orca.input_event as input_event
 import orca.plugin as plugin
 
 from orca.orca_i18n import _ # for gettext support
 
-from keyboard_bindings import bindings as keyboardBindings
-
-try:
-    from braille_bindings import bindings as brailleBindings
-except:
-    log.exception("Not using braille bindings because of this exception:")
-    brailleBindings = []
-
 class Plugin(plugin.Plugin):
     """A plugin for adjusting speech parameters.
     """
@@ -52,81 +47,59 @@
         """
         plugin.Plugin.__init__(self, owner, scriptSettings)
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-        """
-        handlers = plugin.Plugin._createInputEventHandlers(self)
-        handlers.update({
-            "decreaseSpeechRateHandler" : input_bindings.Handler(
-                Plugin._decreaseSpeechRate,
-                # Translators: the speech rate is how fast the speech
-                # synthesis engine will generate speech.
-                #
-                _("Decreases the speech rate.")),
-
-            "increaseSpeechRateHandler" : input_bindings.Handler(
-                Plugin._increaseSpeechRate,
-                # Translators: the speech rate is how fast the speech
-                # synthesis engine will generate speech.
-                #
-                _("Increases the speech rate.")),
-
-            "decreaseSpeechPitchHandler" : input_bindings.Handler(
-                Plugin._decreaseSpeechPitch,
-                # Translators: the speech pitch is how high or low in
-                # pitch/frequency the speech synthesis engine will
-                # generate speech.
-                #
-                _("Decreases the speech pitch.")),
-
-            "increaseSpeechPitchHandler" : input_bindings.Handler(
-                Plugin._increaseSpeechPitch,
-                # Translators: the speech pitch is how high or low in
-                # pitch/frequency the speech synthesis engine will
-                # generate speech.
-                #
-                _("Increases the speech pitch.")),
-        })
-        return handlers
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        bindings = plugin.Plugin._createKeyboardBindings(self, handlers)
-        bindings.extend(keyboardBindings)
-        return bindings
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings.
-        """
-        bindings = plugin.Plugin._createBrailleBindings(self, handlers)
-        bindings.extend(brailleBindings)
-        return bindings
-
-    def _decreaseSpeechRate(self, inputEvent=None, modifiers=None):
-        """The decreaseSpeechRate handler.
-        """
-        log.debug("_decreaseSpeechRate: %s" % inputEvent)
-
-    def _increaseSpeechRate(self, inputEvent=None, modifiers=None):
-        """The increaseSpeechRate handler.
-        """
-        log.debug("_increaseSpeechRate: %s" % inputEvent)
-
-    def _decreaseSpeechPitch(self, inputEvent=None, modifiers=None):
-        """The decreaseSpeechPitch handler.
-        """
-        log.debug("_decreaseSpeechPitch: %s" % inputEvent)
-
-    def _increaseSpeechPitch(self, inputEvent=None, modifiers=None):
-        """The increaseSpeechPitch handler.
+    def _decreaseSpeechRateHandler(self, inputEvent=None):
+        """The decreaseSpeechRateHandler handler.
         """
-        log.debug("_increaseSpeechPitch: %s" % inputEvent)
+        log.debug("_decreaseSpeechRateHandler: %s" % inputEvent)
+    # Translators: the speech rate is how fast the speech
+    # synthesis engine will generate speech.
+    #
+    _decreaseSpeechRateHandler.description = \
+        _("Decreases the speech rate.")
+    _decreaseSpeechRateHandler.bindings = [
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_SAY_SLOWER,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK)
+    ]
+
+    def _increaseSpeechRateHandler(self, inputEvent=None):
+        """The increaseSpeechRateHandler handler.
+        """
+        log.debug("_increaseSpeechRateHandler: %s" % inputEvent)
+    # Translators: the speech rate is how fast the speech
+    # synthesis engine will generate speech.
+    #
+    _increaseSpeechRateHandler.description = \
+        _("Increases the speech rate.")
+    _increaseSpeechRateHandler.bindings = [
+        input_binding.BrailleBinding(
+            brlapi.KEY_CMD_SAY_FASTER,
+            input_event.NO_MODIFIER_MASK,
+            input_event.NO_MODIFIER_MASK)
+    ]
+
+    def _decreaseSpeechPitchHandler(self, inputEvent=None):
+        """The decreaseSpeechPitchHandler handler.
+        """
+        log.debug("_decreaseSpeechPitchHandler: %s" % inputEvent)
+    # Translators: the speech pitch is how high or low in
+    # pitch/frequency the speech synthesis engine will
+    # generate speech.
+    #
+    _decreaseSpeechPitchHandler.description = \
+        _("Decreases the speech pitch.")
+
+    def _increaseSpeechPitchHandler(self, inputEvent=None):
+        """The increaseSpeechPitchHandler handler.
+        """
+        log.debug("_increaseSpeechPitchHandler: %s" % inputEvent)
+    # Translators: the speech pitch is how high or low in
+    # pitch/frequency the speech synthesis engine will
+    # generate speech.
+    #
+    _increaseSpeechPitchHandler.description = \
+        _("Increases the speech pitch.")
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/plugins/where_am_i/Makefile.am
==============================================================================
--- branches/phase2/src/orca/plugins/where_am_i/Makefile.am	(original)
+++ branches/phase2/src/orca/plugins/where_am_i/Makefile.am	Fri Sep 26 19:16:35 2008
@@ -2,8 +2,6 @@
 
 orca_python_PYTHON = \
 	__init__.py \
-	braille_bindings.py \
-	keyboard_bindings.py \
 	plugin.py
 
 orca_pythondir=$(pyexecdir)/orca/plugins/where_am_i

Modified: branches/phase2/src/orca/plugins/where_am_i/plugin.py
==============================================================================
--- branches/phase2/src/orca/plugins/where_am_i/plugin.py	(original)
+++ branches/phase2/src/orca/plugins/where_am_i/plugin.py	Fri Sep 26 19:16:35 2008
@@ -25,19 +25,13 @@
 import logging
 log = logging.getLogger('orca.plugins.where_am_i.plugin')
 
-import orca.input_bindings as input_bindings
+import orca.input_binding as input_binding
+import orca.input_event as input_event
 import orca.plugin as plugin
+import orca.settings as settings
 
 from orca.orca_i18n import _ # for gettext support
 
-from keyboard_bindings import bindings as keyboardBindings
-
-try:
-    from braille_bindings import bindings as brailleBindings
-except:
-    log.exception("Not using braille bindings because of this exception:")
-    brailleBindings = []
-
 class Plugin(plugin.Plugin):
     """A plugin for getting Where Am I information.
     """
@@ -52,87 +46,110 @@
         """
         plugin.Plugin.__init__(self, owner, scriptSettings)
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-        """
-        handlers = plugin.Plugin._createInputEventHandlers(self)
-        handlers.update({
-            "whereAmIBasicHandler" : input_bindings.Handler(
-                Plugin._whereAmIBasic,
-                # Translators: the "Where am I" feature of Orca allows
-                # a user to press a key and then have information
-                # about their current context spoken and brailled to
-                # them.  For example, the information may include the
-                # name of the current pushbutton with focus as well as
-                # its mnemonic.
-                #
-                _("Performs the basic where am I operation.")),
-
-            "whereAmIDetailedHandler" : input_bindings.Handler(
-                Plugin._whereAmIDetailed,
-                # Translators: the "Where am I" feature of Orca allows
-                # a user to press a key and then have information
-                # about their current context spoken and brailled to
-                # them.  For example, the information may include the
-                # name of the current pushbutton with focus as well as
-                # its mnemonic.
-                #
-                _("Performs the detailed where am I operation.")),
-
-            "getTitleHandler" : input_bindings.Handler(
-                Plugin._getTitle,
-                # Translators: This command will cause the window's
-                # title to be spoken.
-                #
-                _("Speaks the title bar.")),
-
-            "getStatusBarHandler" : input_bindings.Handler(
-                Plugin._getStatusBar,
-                # Translators: This command will cause the window's
-                # status bar contents to be spoken.
-                #
-                _("Speaks the status bar.")),
-        })
-        return handlers
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        bindings = plugin.Plugin._createKeyboardBindings(self, handlers)
-        bindings.extend(keyboardBindings)
-        return bindings
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings.
-        """
-        bindings = plugin.Plugin._createBrailleBindings(self, handlers)
-        bindings.extend(brailleBindings)
-        return bindings
-
-    def _whereAmIBasic(self, inputEvent=None, modifiers=None):
-        """The whereAmIBasic handler.
-        """
-        log.debug("_whereAmIBasic: %s" % inputEvent)
-
-    def _whereAmIDetailed(self, inputEvent=None, modifiers=None):
-        """The whereAmIDetailed handler.
-        """
-        log.debug("_whereAmIDetailed: %s" % inputEvent)
-
-    def _getTitle(self, inputEvent=None, modifiers=None):
-        """The getTitle handler.
-        """
-        log.debug("_getTitle: %s" % inputEvent)
-
-    def _getStatusBar(self, inputEvent=None, modifiers=None):
-        """The getStatusBar handler.
+    def _whereAmIBasicHandler(self, inputEvent=None):
+        """The whereAmIBasicHandler handler.
         """
-        log.debug("_getStatusBar: %s" % inputEvent)
+        log.debug("_whereAmIBasicHandler: %s" % inputEvent)
+    # Translators: the "Where am I" feature of Orca allows
+    # a user to press a key and then have information
+    # about their current context spoken and brailled to
+    # them.  For example, the information may include the
+    # name of the current pushbutton with focus as well as
+    # its mnemonic.
+    #
+    _whereAmIBasicHandler.description = \
+        _("Performs the basic where am I operation.")
+    _whereAmIBasicHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Enter",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "Return",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP)
+    ]
+
+    def _whereAmIDetailedHandler(self, inputEvent=None):
+        """The whereAmIDetailedHandler handler.
+        """
+        log.debug("_whereAmIDetailedHandler: %s" % inputEvent)
+    # Translators: the "Where am I" feature of Orca allows
+    # a user to press a key and then have information
+    # about their current context spoken and brailled to
+    # them.  For example, the information may include the
+    # name of the current pushbutton with focus as well as
+    # its mnemonic.
+    #
+    _whereAmIDetailedHandler.description = \
+        _("Performs the detailed where am I operation.")
+    _whereAmIDetailedHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Enter",
+            input_event.defaultModifierMask,
+            input_event.NO_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "Return",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP)
+    ]
+
+    def _getTitleHandler(self, inputEvent=None):
+        """The getTitleHandler handler.
+        """
+        log.debug("_getTitleHandler: %s" % inputEvent)
+    # Translators: This command will cause the window's
+    # title to be spoken.
+    #
+    _getTitleHandler.description = \
+        _("Speaks the title bar.")
+    _getTitleHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Enter",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "slash",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 1,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP)
+    ]
+
+
+    def _getStatusBarHandler(self, inputEvent=None):
+        """The getStatusBarHandler handler.
+        """
+        log.debug("_getStatusBarHandler: %s" % inputEvent)
+    # Translators: This command will cause the window's
+    # status bar contents to be spoken.
+    #
+    _getStatusBarHandler.description = \
+        _("Speaks the status bar.")
+    _getStatusBarHandler.bindings = [
+        input_binding.KeyboardBinding(
+            "KP_Enter",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP),
+        input_binding.KeyboardBinding(
+            "slash",
+            input_event.defaultModifierMask,
+            input_event.ORCA_MODIFIER_MASK,
+            clickCount = 2,
+            keyboardLayout = settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP)
+    ]
 
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")

Modified: branches/phase2/src/orca/script.py
==============================================================================
--- branches/phase2/src/orca/script.py	(original)
+++ branches/phase2/src/orca/script.py	Fri Sep 26 19:16:35 2008
@@ -16,13 +16,9 @@
 # Boston MA  02110-1301 USA.
 
 # TODO: Add ability for script to find/load/save its own settings file.
-# TODO: Add bookmarks support
-# TODO: Add where am I support
 # TODO: Add braille generator support
 # TODO: Add speech generator support
 # TODO: Add tutorial support
-# TODO: Add structural navigation support
-# TODO: Add flat review support
 # TODO: Add hook to override key bindings
 # TODO: Add hook to override braille bindings
 # TODO: Add hook to override pronunciations
@@ -52,7 +48,8 @@
 log = logging.getLogger('orca.script')
 
 import braille
-import input_bindings
+import input_binding
+import input_event
 import script_manager
 import settings
 import utils
@@ -79,12 +76,7 @@
         self.presentIfInactive = False
 
         self._objectEventListeners = self._introspectObjectEventListeners()
-        self._inputEventHandlers = self._createInputEventHandlers()
-        self._keyboardBindings = \
-            self._createKeyboardBindings(self._inputEventHandlers)
-        self._brailleBindings = \
-            self._createBrailleBindings(self._inputEventHandlers)
-        self._introspectInputEventBindings()
+        self._inputEventHandlers = self._introspectInputEventHandlers()
 
         # Load custom settings and also give the module a chance to
         # override our keyboard and braille bindings.
@@ -112,14 +104,77 @@
         self._completeInit()
         log.debug("%s settings:\n%s" % (self, self._settings))
 
-    def getSettingsModuleName(self):
-        """Get the name of the user settings module for this script.
+    def __str__(self):
+        """Returns a human readable representation of the script.
         """
-        name = script_manager.ScriptManager.getScriptModuleName(
-            self.application)
-        if name and len(name):
-            name = "script_settings." + name + ".settings"
-        return name
+        try:
+            name = self.application.name
+        except:
+            name = "None"
+        return "script %s (module=%s)" % (name, self.__module__)
+
+    def _completeInit(self):
+        """Completes the __init__ step.
+        """
+        log.info("NEW SCRIPT: %s" % self)
+
+    def _introspectObjectEventListeners(self):
+        """Find the AT-SPI listeners based upon their method name.
+        """
+        # Find all the things that look like Listener methods.
+        #
+        methods = \
+            filter(lambda z: callable(z),
+                   map(lambda y: getattr(self, y).__get__(self, self.__class__),
+                       filter(lambda x: x.endswith("Listener"), dir(self))))
+
+        # Now create a dictionary where the keys are AT-SPI event types
+        # and the values are the methods.  We do this by looking for the
+        # 'events' attribute of the method, which should be a list of
+        # AT-SPI event type strings.
+        #
+        listeners = {}
+        for method in methods:
+            try:
+                events = method.events
+            except:
+                events = []
+            for event in events:
+                listeners[event] = method
+    
+        return listeners
+
+    def _introspectInputEventHandlers(self):
+        """Find the input event handlers for this object based upon their 
+        method name.
+        """
+        # Find all the things that look like Handler methods.
+        #
+        methods = \
+            filter(lambda z: callable(z),
+                   map(lambda y: getattr(self, y).__get__(self, self.__class__),
+                       filter(lambda x: x.endswith("Handler"), dir(self))))
+
+        # Now create all the Handlers as a list based upon what we find
+        # in the things that look like Handler methods.  We expect to
+        # find a list of InputBinding instances and a description on
+        # each handler.
+        #
+        handlers = []
+        for method in methods:
+            try:
+                description = method.description
+            except AttributeError:
+                log.warning("No description for %s.  Not registering." % method)
+                continue
+            try:
+                bindings = method.bindings
+            except AttributeError:
+                bindings = []
+            handlers.append(input_binding.InputHandler(method,
+                                                       description, 
+                                                       bindings))
+        return handlers
 
     def _loadSettings(self, userSettings):
         """Load the user's specific settings for a script.
@@ -159,78 +214,6 @@
 
         return scriptSettings
 
-    def _completeInit(self):
-        """Completes the __init__ step.
-        """
-        log.info("NEW SCRIPT: %s" % self)
-
-    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):
-                    try:
-                        events = method.events
-                    except:
-                        events = []
-                    for event in events:
-                        listeners[event] = method
-        return listeners
-
-    def _introspectInputEventBindings(self):
-        """TODO: EXPERIMENTAL method to find the input event handlers for this
-        object based upon their method name.
-        """
-        # 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.
-        #
-        for symbol, method in methodList:
-            try:
-                self._inputEventHandlers[symbol] = input_bindings.Handler(
-                    method, method.description)
-            except:
-                log.warning("No description for %s.  Not registering." % symbol)
-                continue
-            try:
-                for keysym, mask, modifiers, clickCount in method.keyboardBindings:
-                    self._keyboardBindings.append(
-                        input_bindings.KeyboardBinding(
-                            keysym, mask, modifiers, symbol, clickCount))
-            except:
-                pass
-            try:
-                for command, mask, modifiers, clickCount in method.brailleBindings:
-                    self._brailleBindings.append(
-                        input_bindings.BrailleBinding(
-                            command, mask, modifiers, symbol, clickCount))
-            except:
-                pass
-
-    def __str__(self):
-        """Returns a human readable representation of the script.
-        """
-        try:
-            name = self.application.name
-        except:
-            name = "None"
-        return "script %s (module=%s)" % (name, self.__module__)
-
     def _getPluginClasses(self):
         """Returns a list of classes to instantiante for plugins.
         Subclasses should override this method to add their own
@@ -239,157 +222,47 @@
         """
         return []
 
-    def _createInputEventHandlers(self):
-        """Defines InputEventHandler fields for this script that can be
-        called by the key and braille bindings.
-
-        Returns a dictionary where the key is a handler name and the
-        values are instances if input_event.InputEventHandler.
-        """
-        return {}
-
-    def _createKeyboardBindings(self, handlers):
-        """Defines the key bindings for this script.
-
-        Returns an instance of input_bindings.KeyboardBindings.
-        """
-        return input_bindings.KeyboardBindings(handlers)
-
-    def _createBrailleBindings(self, handlers):
-        """Defines the braille bindings for this script.
-
-        Returns an instance of input_bindings.BrailleBindings
-        """
-        return input_bindings.BrailleBindings(handlers)
-
-    def getPronunciations(self):
-        """Defines the application specific pronunciations for this script.
-
-        Returns a dictionary where the keys are the actual text strings and
-        the values are the replacement strings that are spoken instead.
-        """
-        return {}
-
-    def getBrailleKeyRanges(self):
-        """Gets the BrlAPI commands this script and all of its plugins
+    def _getBrailleKeys(self):
+        """Gets the BrlAPI commands this script and all of its pluging
         care about.
         """
         keys = []
-        for binding in self._brailleBindings:
-            keys.append(binding.command)
+        for handler in self._inputEventHandlers:
+            keys.extend(
+                map(lambda y: y.command,
+                    filter(lambda x: isinstance(x,
+                                                input_binding.BrailleBinding),
+                           handler.bindings)))
+
         for plugin in self._plugins:
-            keys += plugin.getBrailleKeyRanges()
-        return keys
+            keys.extend(plugin._getBrailleKeys())
+ 
+	return keys
 
-    def _setupBrailleKeyRanges(self):
+    def _registerBrailleKeys(self):
         """Sets up the BrlAPI commands this script and all of its plugins
         care about.
         """
-        braille.setupKeyRanges(self.getBrailleKeyRanges())
+        braille.setKeys(self._getBrailleKeys())
 
-    def _clearBrailleKeyRanges(self):
+    def _unregisterBrailleKeys(self):
         """Clears the BrlAPI commands this script and all of its plugins
         care about.
         """
-        braille.setupKeyRanges([])
+        braille.setKeys([])
 
-    def getInputEventHandlerKey(self, inputEventHandler):
-        """Returns the name of the key that contains an inputEventHadler
+    def getHandlerForInputEvent(self, inputEvent):
+        """Returns the name of the key that contains an inputEventHandler
         passed as argument
         """
-        for keyName, handler in self._inputEventHandlers.iteritems():
-            if handler == inputEventHandler:
-                return keyName
-        return None
-
-    def consumesKeyboardEvent(self, keyboardEvent):
-        """Called when a key is pressed on the keyboard.  If we care
-        about it, our processKeyboardEvent method will get called a
-        bit later.
-
-        Arguments:
-        - keyboardEvent: an instance of input_event.KeyboardEvent
-
-        Returns True if the event is of interest.
-        """
-        # TODO: add in structural navigation model
-        consumes = False
-        if not consumes:
-            handler = self._keyboardBindings.getHandler(
-                keyboardEvent.hw_code,
-                keyboardEvent.modifiers,
-                keyboardEvent.click_count)
-            consumes = handler != None
-        if not consumes:
-            for plugin in self._plugins:
-                consumes = plugin.consumesKeyboardEvent(keyboardEvent)
-                if consumes:
-                    break
-        return consumes
-
-    def processKeyboardEvent(self, keyboardEvent):
-        """Called whenever a key is pressed on the keyboard
-        and we have an interest in it.
-        """
-        # TODO: add support for user-settings.py keyboardBindingsMap
-
-        # We'll annotate the event with a reference to this script.
-        # This will allow external scripts to muck with the script
-        # instance if they wish.
-        #
-        keyboardEvent.script = self
-        self._keyboardBindings.processInputEvent(
-            self,
-            keyboardEvent,
-            keyboardEvent.modifiers)
-        for plugin in self._plugins:
-            plugin.processKeyboardEvent(keyboardEvent)
-
-    def consumesBrailleEvent(self, brailleEvent):
-        """Called when a key is pressed on the braille display.  If we
-        care about it, our processBrailleEvent method will get called a
-        bit later.
-
-        Arguments:
-        - brailleEvent: an instance of input_event.BrailleEvent
-
-        Returns True if the event is of interest.
-        """
-        # TODO: add support for user-settings.py brailleBindingsMap
-        consumes = False
-        if not consumes:
-            handler = self._brailleBindings.getHandler(
-                brailleEvent.command,
-                0, # TODO: add current keyboard modifiers
-                brailleEvent.click_count)
-            consumes = handler != None
-        if not consumes:
-            for plugin in self._plugins:
-                consumes = plugin.consumesBrailleEvent(brailleEvent)
-                if consumes:
-                    break
-        return consumes
-
-    def processBrailleEvent(self, brailleEvent):
-        """Called whenever a key is pressed on the Braille display
-        and we have an interest in it.
-
-        Arguments:
-        - brailleEvent: an instance of input_event.BrailleEvent
-        """
-        # TODO: add support for user-settings.py brailleBindingsMap
-
-        # We'll annotate the event with a reference to this script.
-        # This will allow external scripts to muck with the script
-        # instance if they wish.
-        #
-        brailleEvent.script = self
-        self._brailleBindings.processInputEvent(
-            self,
-            brailleEvent,
-            0) # TODO: add current keyboard modifiers
+        for handler in self._inputEventHandlers:
+            if handler.handlesEvent(inputEvent):
+                return handler
         for plugin in self._plugins:
-            plugin.processBrailleEvent(brailleEvent)
+            handler = plugin.getHandlerForInputEvent(inputEvent)
+            if handler:
+                return handler
+        return None
 
     def processObjectEvent(self, event):
         """Processes all AT-SPI object events of interest to this
@@ -425,6 +298,15 @@
         for plugin in self._plugins:
             plugin.processObjectEvent(event)
 
+    def getSettingsModuleName(self):
+        """Get the name of the user settings module for this script.
+        """
+        name = script_manager.ScriptManager.getScriptModuleName(
+            self.application)
+        if name and len(name):
+            name = "script_settings." + name + ".settings"
+        return name
+
     def activate(self):
         """Called when this script is activated.
         """
@@ -436,7 +318,7 @@
         for eventType in self._objectEventListeners.keys():
             utils.registerEventListener(eventType)
         
-        self._setupBrailleKeyRanges()
+        self._registerBrailleKeys()
 
         for plugin in self._plugins:
             plugin.activate()
@@ -459,7 +341,7 @@
         for eventType in self._objectEventListeners.keys():
             utils.deregisterEventListener(eventType)
 
-        self._clearBrailleKeyRanges()
+        self._unregisterBrailleKeys()
 
         self._isActive = False
 

Modified: branches/phase2/src/orca/script_manager.py
==============================================================================
--- branches/phase2/src/orca/script_manager.py	(original)
+++ branches/phase2/src/orca/script_manager.py	Fri Sep 26 19:16:35 2008
@@ -265,30 +265,6 @@
 
         return script
 
-    def _reclaimScripts(self):
-        """Compares the list of known scripts to the list of known apps,
-        deleting any scripts as necessary.
-        """
-        # Sometimes the desktop can become unavailable.  This happens
-        # often when synaptic is used to load new modules (see the bug
-        # report http://bugzilla.gnome.org/show_bug.cgi?id=342022).
-        # So...if this happens, we'll just move along.  The next
-        # successful call to _reclaimScripts will reclaim anything we
-        # didn't reclaim this time.
-        #
-        try:
-            desktop = pyatspi.Registry.getDesktop(0)
-
-            for application in self._knownScripts.keys():
-                if application not in desktop:
-                    script = self._knownScripts[application]
-                    script.deactivate()
-                    del self._knownScripts[application]
-                    del application
-                    del script
-        except:
-            log.exception("exception while reclaiming scripts:")
-
     def _getScript(self, application):
         """Get a script for an application (and make it if necessary).
         This is used instead of a simple call to Script's constructor.
@@ -335,173 +311,95 @@
         log.info("ACTIVE SCRIPT: %s (reason=%s)"
                  % (self._activeScript, reason))
 
-    ########################################################################
-    #                                                                      #
-    # METHODS PROCESSING AND DISPATCHING EVENTS                            #
-    #                                                                      #
-    ########################################################################
-
-    def _dispatchKeyboardEvent(self, keyboardEvent):
-        """Processes the given keyboard event based on the keyboard
-        binding from the currently active script.
-
-        Arguments:
-        - keyboardEvent: an instance of input_event.KeyboardEvent
+    def _reclaimScripts(self):
+        """Compares the list of known scripts to the list of known apps,
+        deleting any scripts as necessary.
         """
+        # Sometimes the desktop can become unavailable.  This happens
+        # often when synaptic is used to load new modules (see the bug
+        # report http://bugzilla.gnome.org/show_bug.cgi?id=342022).
+        # So...if this happens, we'll just move along.  The next
+        # successful call to _reclaimScripts will reclaim anything we
+        # didn't reclaim this time.
+        #
         try:
-            self._activeScript.processKeyboardEvent(keyboardEvent)
-        except:
-            log.exception("handled exception while processing keyboard event:")
-
-    def _dispatchBrailleEvent(self, brailleEvent):
-        """Called whenever we get a braille input event.
+            desktop = pyatspi.Registry.getDesktop(0)
 
-        Arguments:
-        - brailleEvent: an instance of input_event.BrailleEvent
-        """
-        try:
-            self._activeScript.processBrailleEvent(brailleEvent)
+            for application in self._knownScripts.keys():
+                if application not in desktop:
+                    script = self._knownScripts[application]
+                    script.deactivate()
+                    del self._knownScripts[application]
+                    del application
+                    del script
         except:
-            log.exception("handled exception while processing braille event:")
-
-    def _dispatchObjectEvent(self, event):
-        """Handles all events destined for scripts.
-
-        Arguments:
-        - event: an AT-SPI event.
-        """
-        log.debug(event)
-
-    def _isModifierKey(self, event_string):
-        """Return an indication of whether this is a modifier key.
-
-        Arguments:
-        - event: the event string
-
-        Returns True if this is a modifier key
-        """
-        modifierKeys = self._settings.orcaModifierKeys \
-            + [ 'Alt_L', 'Alt_R', 'Control_L', 'Control_R',
-                'Shift_L', 'Shift_R', 'Meta_L', 'Meta_R' ]
-        return event_string in modifierKeys
-
-    def _setClickCount(self, inputEvent):
-        """Sets the count of the number of clicks a user has made to
-        one of the non-modifier keys on the keyboard, braille display,
-        or mouse.  Note that this looks at the event_string (keysym)
-        instead of hw_code (keycode) because the Java platform gives
-        us completely different keycodes for keys.
-
-        Arguments:
-        - inputEvent: the current input event.
-        """
-        lastInputEvent = self._lastNonModifierEvent
-
-        if (isinstance(inputEvent, input_event.KeyboardEvent) \
-                and (inputEvent.type == pyatspi.KEY_RELEASED_EVENT)) \
-            or (isinstance(inputEvent, input_event.MouseButtonEvent) \
-                and not inputEvent.pressed):
-            return
-
-        # We were getting pylint errors along the following lines for
-        # checks against the MouseButtonEvent:
-        #
-        # Instance of 'BrailleEvent' has no 'button' member
-        # Instance of 'KeyboardEvent' has no 'button' member
-        #
-        # Well, we're checking very hard to make sure things are 
-        # MouseButton events, so we'll disable that message here.
-        #
-        # pylint: disable-msg=E1101
-
-        if not lastInputEvent \
-            or not isinstance(inputEvent, lastInputEvent.__class__):
-            self._clickCount = 1
-        elif isinstance(lastInputEvent, input_event.KeyboardEvent) \
-            and ((lastInputEvent.event_string != inputEvent.event_string) \
-                 or (lastInputEvent.modifiers != inputEvent.modifiers)):
-            self._clickCount = 1
-        elif isinstance(lastInputEvent, input_event.MouseButtonEvent) \
-            and isinstance(inputEvent, input_event.MouseButtonEvent) \
-            and (lastInputEvent.button != inputEvent.button):
-            self._clickCount = 1
-        elif isinstance(lastInputEvent, input_event.BrailleEvent) \
-            and (lastInputEvent.command != inputEvent.command):
-            self._clickCount = 1
-        elif (inputEvent.time - lastInputEvent.time) \
-            < self._settings.doubleClickTimeout:
-            self._clickCount = min(3, self._clickCount + 1)
-        else:
-            self._clickCount = 1
-        
-        inputEvent.click_count = self._clickCount
+            log.exception("exception while reclaiming scripts:")
 
-        log.debug("set _clickCount to %d for %s" 
-                  % (self._clickCount, inputEvent))
+    ########################################################################
+    #                                                                      #
+    # METHODS FOR PROCESSING EVENTS ON THE EVENT QUEUE                     #
+    #                                                                      #
+    ########################################################################
 
-    def _processKeyboardEvent(self, event):
-        """Processes the given keyboard event based on the keyboard
-        binding from the currently active script. This method is
-        called synchronously from the at-spi registry and should be
-        performant.  In addition, it must return True if it has
-        consumed the event (and False if not).
+    def _enqueueEvent(self, e):
+        """Handles all events destined for scripts.
 
         Arguments:
-        - event: an instance of pyatspi.Event
-
-        Returns True if the event should be consumed.
+        - e: an at-spi event.
         """
-        keyboardEvent = input_event.KeyboardEvent(event)
-
-        # If this is a key event for a non-modifier key, save a handle
-        # to it.  This is needed to help determine user actions when a
-        # multi-key chord has been pressed, and we might get the key
-        # events in different orders.  See comment #15 of bug #435201
-        # for more details.  We also want to store the "click count"
-        # for the purpose of supporting bindings with unique behaviors
-        # when double- or triple-clicked.
-        #
-        if not self._isModifierKey(keyboardEvent.event_string):
-            self._setClickCount(keyboardEvent)
-            self._lastNonModifierEvent = keyboardEvent
-
-        isOrcaModifier = self._settings.orcaModifierKeys.count(
-            keyboardEvent.event_string) > 0
-        if keyboardEvent.type == pyatspi.KEY_PRESSED_EVENT:
-            if isOrcaModifier:
-                self._orcaModifierPressed = True
-        else:
-            if isOrcaModifier:
-                self._orcaModifierPressed = False
+        processSynchronously = synchronousMode
 
-        if self._orcaModifierPressed:
-            keyboardEvent.modifiers = \
-                keyboardEvent.modifiers | input_event.ORCA_MODIFIER_MASK
+        event = None
+        if isinstance(e, input_event.InputEvent):
+            event = e
+        elif isinstance(e, pyatspi.event.Event):
+            if e.type in ignoredEventsList:
+                return
 
-        consume = self._activeScript \
-                  and self._activeScript.consumesKeyboardEvent(keyboardEvent)
+            # We ignore defunct objects.
+            #
+            if e.type.startswith("object:state-changed:defunct"):
+                return
 
-        if consume:
-            self._enqueueEvent(keyboardEvent)
+            # We also generally do not like
+            # object:property-change:accessible-parent events because
+            # they indicate something is now whacked with the
+            # hierarchy.
+            #
+            if e.type.startswith("object:property-change:accessible-parent"):
+                return
 
-        return consume or isOrcaModifier
+            # At this point in time, we only care when objects are
+            # removed from the desktop.
+            #
+            if e.type.startswith("object:children-changed:remove") \
+                and (e.source != pyatspi.Registry.getDesktop(0)):
+                return
 
-    def _processBrailleEvent(self, event):
-        """Called whenever a cursor key is pressed on the Braille display.
+            # If the event doesn't have a source or that source is not marked
+            # valid, then we don't care about this event. Just return.
+            #            
+            event = e
+            if not event.source:
+                log.warning("IGNORING INVALID EVENT %s" % e.type)
 
-        Arguments:
-        - event: an expanded BrlTTY event (see braille.py)
+            # Some toolkits (e.g., Java - see bug #531869) need to
+            # have their events processed immediately.
+            #
+            try:
+                if event.host_application.toolkitName \
+                    in synchronousToolkits:
+                    processSynchronously = True
+            except:
+                pass
 
-        Returns True if the command was consumed; otherwise False
-        """
-        brailleEvent = input_event.BrailleEvent(event)
-        self._lastNonModifierEvent = brailleEvent
-        self._setClickCount(brailleEvent)
-        consume = self._activeScript \
-                  and self._activeScript.consumesBrailleEvent(brailleEvent)
-        if consume:
-            self._enqueueEvent(brailleEvent)
-        return consume
+        if event:
+            log.debug("QUEUEING %s" % str(event).replace("\n"," "))
+            self._eventQueue.put(event)
+            if processSynchronously:
+                self._dequeueEvent()
+            else:
+                self._gidleId = gobject.idle_add(self._dequeueEvent)
 
     def _processObjectEvent(self, event):
         """Handles all AT-SPI events.
@@ -630,68 +528,6 @@
                 log.exception("handled exception processing %s:" % event.type)
                 break
 
-    def _enqueueEvent(self, e):
-        """Handles all events destined for scripts.
-
-        Arguments:
-        - e: an at-spi event.
-        """
-        processSynchronously = synchronousMode
-
-        event = None
-        if isinstance(e, input_event.KeyboardEvent):
-            event = e
-        elif isinstance(e, input_event.BrailleEvent):
-            event = e
-        else:
-            if e.type in ignoredEventsList:
-                return
-
-            # We ignore defunct objects.
-            #
-            if e.type.startswith("object:state-changed:defunct"):
-                return
-
-            # We also generally do not like
-            # object:property-change:accessible-parent events because
-            # they indicate something is now whacked with the
-            # hierarchy.
-            #
-            if e.type.startswith("object:property-change:accessible-parent"):
-                return
-
-            # At this point in time, we only care when objects are
-            # removed from the desktop.
-            #
-            if e.type.startswith("object:children-changed:remove") \
-                and (e.source != pyatspi.Registry.getDesktop(0)):
-                return
-
-            # If the event doesn't have a source or that source is not marked
-            # valid, then we don't care about this event. Just return.
-            #            
-            event = e
-            if not event.source:
-                log.warning("IGNORING INVALID EVENT %s" % e.type)
-
-            # Some toolkits (e.g., Java - see bug #531869) need to
-            # have their events processed immediately.
-            #
-            try:
-                if event.host_application.toolkitName \
-                    in synchronousToolkits:
-                    processSynchronously = True
-            except:
-                pass
-
-        if event:
-            log.debug("QUEUEING %s" % str(event).replace("\n"," "))
-            self._eventQueue.put(event)
-            if processSynchronously:
-                self._dequeueEvent()
-            else:
-                self._gidleId = gobject.idle_add(self._dequeueEvent)
-
     def _dequeueEvent(self):
         """Handles all events destined for scripts.  Called by the GTK
         idle thread.
@@ -702,10 +538,9 @@
             event = self._eventQueue.get_nowait()
             log.debug("DEQUEUED %s\n" % str(event).replace("\n"," "))
             log.info("vvvvv PROCESS %s vvvvv" % str(event).replace("\n"," "))
-            if isinstance(event, input_event.KeyboardEvent):
-                self._dispatchKeyboardEvent(event)
-            elif isinstance(event, input_event.BrailleEvent):
-                self._dispatchBrailleEvent(event)
+            if isinstance(event, input_event.InputEvent):
+                if event.type != input_event.RELEASED:
+                    event.handler.function(event)
             else:
                 self._processObjectEvent(event)
             log.info("^^^^^ PROCESS %s ^^^^^\n" % str(event).replace("\n"," "))
@@ -714,8 +549,135 @@
         except:
             log.exception("handled exception processing event:")
 
+        
         return rerun
 
+    ########################################################################
+    #                                                                      #
+    # METHODS FOR PROCESSING RAW INPUT EVENTS                              #
+    #                                                                      #
+    ########################################################################
+
+    def _isModifierKey(self, command):
+        """Return an indication of whether this is a modifier key.
+
+        Arguments:
+        - event: the event string
+
+        Returns True if this is a modifier key
+        """
+        modifierKeys = self._settings.orcaModifierKeys \
+            + [ 'Alt_L', 'Alt_R', 'Control_L', 'Control_R',
+                'Shift_L', 'Shift_R', 'Meta_L', 'Meta_R' ]
+        return command in modifierKeys
+
+    def _setClickCount(self, inputEvent):
+        """Sets the count of the number of clicks a user has made to
+        one of the non-modifier keys on the keyboard, braille display,
+        or mouse.  Note that this looks at the command (keysym)
+        instead of hw_code (keycode) because the Java platform gives
+        us completely different keycodes for keys.
+
+        Arguments:
+        - inputEvent: the current input event.
+        """
+        lastInputEvent = self._lastNonModifierEvent
+
+        if (isinstance(inputEvent, input_event.KeyboardEvent) \
+            or isinstance(inputEvent, input_event.MouseButtonEvent)) \
+            and (inputEvent.type == input_event.RELEASED):
+            inputEvent.click_count = self._clickCount
+            return
+
+        if not lastInputEvent \
+            or not isinstance(inputEvent, lastInputEvent.__class__):
+            self._clickCount = 1
+        elif isinstance(lastInputEvent, input_event.KeyboardEvent) \
+            and ((lastInputEvent.command != inputEvent.command) \
+                 or (lastInputEvent.modifiers != inputEvent.modifiers)):
+            self._clickCount = 1
+        elif isinstance(lastInputEvent, input_event.MouseButtonEvent) \
+            and isinstance(inputEvent, input_event.MouseButtonEvent) \
+            and (lastInputEvent.command != inputEvent.button):
+            self._clickCount = 1
+        elif isinstance(lastInputEvent, input_event.BrailleEvent) \
+            and (lastInputEvent.command != inputEvent.command):
+            self._clickCount = 1
+        elif (inputEvent.time - lastInputEvent.time) \
+            < self._settings.doubleClickTimeout:
+            self._clickCount = min(3, self._clickCount + 1)
+        else:
+            self._clickCount = 1
+        
+        inputEvent.click_count = self._clickCount
+
+        log.debug("set _clickCount to %d for %s" 
+                  % (self._clickCount, inputEvent))
+
+    def _processKeyboardEvent(self, event):
+        """Processes the given keyboard event based on the keyboard
+        binding from the currently active script. This method is
+        called synchronously from the at-spi registry and should be
+        performant.  In addition, it must return True if it has
+        consumed the event (and False if not).
+
+        Arguments:
+        - event: an instance of pyatspi.event.Event
+
+        Returns True if the event should be consumed.
+        """
+        keyboardEvent = input_event.KeyboardEvent(event)
+
+        isOrcaModifier = self._settings.orcaModifierKeys.count(
+            keyboardEvent.command) > 0
+        if isOrcaModifier:
+            self._orcaModifierPressed = \
+                keyboardEvent.type == input_event.PRESSED
+        if self._orcaModifierPressed:
+            keyboardEvent.modifiers = \
+                keyboardEvent.modifiers | input_event.ORCA_MODIFIER_MASK
+
+        # If this is a key event for a non-modifier key, save a handle
+        # to it.  This is needed to help determine user actions when a
+        # multi-key chord has been pressed, and we might get the key
+        # events in different orders.  See comment #15 of bug #435201
+        # for more details.  We also want to store the "click count"
+        # for the purpose of supporting bindings with unique behaviors
+        # when double- or triple-clicked.
+        #
+        if not self._isModifierKey(keyboardEvent.command):
+            self._setClickCount(keyboardEvent)
+            self._lastNonModifierEvent = keyboardEvent
+
+        handler = self._activeScript \
+                  and self._activeScript.getHandlerForInputEvent(keyboardEvent)
+
+        if handler:
+            keyboardEvent.handler = handler
+            self._enqueueEvent(keyboardEvent)
+        return (handler != None) or isOrcaModifier
+
+    def _processBrailleEvent(self, event):
+        """Called whenever a cursor key is pressed on the Braille display.
+
+        Arguments:
+        - event: an expanded BrlTTY event (see braille.py)
+
+        Returns True if the command was consumed; otherwise False
+        """
+        brailleEvent = input_event.BrailleEvent(event)
+        self._lastNonModifierEvent = brailleEvent
+        self._setClickCount(brailleEvent)
+
+        handler = self._activeScript \
+                  and self._activeScript.getHandlerForInputEvent(brailleEvent)
+
+        if handler:
+            brailleEvent.handler = handler
+            self._enqueueEvent(brailleEvent)
+
+        return handler != None
+
 if __name__ == "__main__":
     logging.basicConfig(format="%(name)s %(message)s")
     log.setLevel(logging.DEBUG)

Modified: branches/phase2/src/orca/settings.py
==============================================================================
--- branches/phase2/src/orca/settings.py	(original)
+++ branches/phase2/src/orca/settings.py	Fri Sep 26 19:16:35 2008
@@ -406,6 +406,7 @@
 
 # Keyboard layout options (see keyboardLayout).
 #
+GENERAL_KEYBOARD_LAYOUT_ALL     = 0
 GENERAL_KEYBOARD_LAYOUT_DESKTOP = 1
 GENERAL_KEYBOARD_LAYOUT_LAPTOP  = 2
 keyboardLayout                  = GENERAL_KEYBOARD_LAYOUT_DESKTOP



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