orca r3782 - in trunk: . src/orca
- From: eitani svn gnome org
- To: svn-commits-list gnome org
- Subject: orca r3782 - in trunk: . src/orca
- Date: Fri, 28 Mar 2008 20:41:32 +0000 (GMT)
Author: eitani
Date: Fri Mar 28 20:41:31 2008
New Revision: 3782
URL: http://svn.gnome.org/viewvc/orca?rev=3782&view=rev
Log:
* src/orca/mouse_review.py:
Fix for bug #520611.
New mouse review feature (all of the changes below too).
* src/orca/Makefile.am:
Added mouse_review.py.
* src/orca/default.py:
- Added unbound mouse review toggle key.
- Added getComponentAtDesktopCoords() (and
_getPopupItemAtDesktopCoords).
- Added speakWordUnderMouse().
- Added getWordAtCoords().
* src/orca/Gecko.py:
Added override for speakWordUnderMouse().
* src/orca/focus_tracking_presenter.py:
Chaged _getScript to a public getScript.
* src/orca/orca.py:
- Initialize mouse review on start up.
- Added getScriptForApp.
* src/orca/settings.py:
Added enableMouseReview and mouseDwellDelay
* src/orca/orca_gui_prefs.py:
* src/orca/orca-setup.glade
Toggle mouse review in general tab.
Added:
trunk/src/orca/mouse_review.py
Modified:
trunk/ChangeLog
trunk/src/orca/Gecko.py
trunk/src/orca/Makefile.am
trunk/src/orca/default.py
trunk/src/orca/focus_tracking_presenter.py
trunk/src/orca/orca-setup.glade
trunk/src/orca/orca.py
trunk/src/orca/orca_gui_prefs.py
trunk/src/orca/settings.py
Modified: trunk/src/orca/Gecko.py
==============================================================================
--- trunk/src/orca/Gecko.py (original)
+++ trunk/src/orca/Gecko.py Fri Mar 28 20:41:31 2008
@@ -10862,6 +10862,24 @@
speech.speak(string)
braille.displayMessage(string)
+
+
+ def speakWordUnderMouse(self, acc):
+ """Determine if the speak-word-under-mouse capability applies to
+ the given accessible.
+
+ Arguments:
+ - acc: Accessible to test.
+
+ Returns True if this accessible should provide the single word.
+ """
+ if self.inDocumentContent(acc):
+ try:
+ ai = acc.queryAction()
+ except NotImplementedError:
+ return True
+ default.Script.speakWordUnderMouse(self, acc)
+
####################################################################
# #
# Match Predicates #
Modified: trunk/src/orca/Makefile.am
==============================================================================
--- trunk/src/orca/Makefile.am (original)
+++ trunk/src/orca/Makefile.am Fri Mar 28 20:41:31 2008
@@ -33,6 +33,7 @@
keynames.py \
liveregions.py \
mag.py \
+ mouse_review.py \
orca.py \
orca_console_prefs.py \
orca_glade.py \
Modified: trunk/src/orca/default.py
==============================================================================
--- trunk/src/orca/default.py (original)
+++ trunk/src/orca/default.py Fri Mar 28 20:41:31 2008
@@ -62,6 +62,8 @@
import settings
import speech
import speechserver
+import mouse_review
+
from orca_i18n import _ # for gettext support
from orca_i18n import ngettext # for ngettext support
@@ -123,6 +125,8 @@
self.lastProgressBarTime = {}
self.lastProgressBarValue = {}
+ self.lastSelectedMenu = None
+
def setupInputEventHandlers(self):
"""Defines InputEventHandler fields for this script that can be
called by the key and braille bindings."""
@@ -938,6 +942,14 @@
#
_("Cycles to the next magnifier position."))
+ self.inputEventHandlers["toggleMouseReviewHandler"] = \
+ input_event.InputEventHandler(
+ mouse_review.toggle,
+ # Translators: Orca allows the item under the pointer to
+ # be spoken. This toggles the feature.
+ #
+ _("Toggle mouse review mode."))
+
def getInputEventHandlerKey(self, inputEventHandler):
"""Returns the name of the key that contains an inputEventHadler
passed as argument
@@ -1912,6 +1924,13 @@
0,
self.inputEventHandlers["panBrailleRightHandler"]))
+ keyBindings.add(
+ keybindings.KeyBinding(
+ None,
+ 0,
+ 0,
+ self.inputEventHandlers["toggleMouseReviewHandler"]))
+
keyBindings = settings.overrideKeyBindings(self, keyBindings)
return keyBindings
@@ -2837,7 +2856,6 @@
- event: if not None, the Event that caused this to happen
- obj: the Accessible whose visual appearance changed.
"""
-
# Check if this event is for a progress bar.
#
if obj.getRole() == pyatspi.ROLE_PROGRESS_BAR:
@@ -3646,6 +3664,15 @@
if not event or not event.source:
return
+ # Save the event source, if it is a menu or combo box. It will be
+ # useful for optimizing getComponentAtDesktopCoords in the case
+ # that the pointer is hovering over a menu item. The alternative is
+ # to traverse the application's tree looking for potential moused-over
+ # menu items.
+ if event.source.getRole() in (pyatspi.ROLE_COMBO_BOX,
+ pyatspi.ROLE_MENU):
+ self.lastSelectedMenu = event.source
+
# Avoid doing this with objects that manage their descendants
# because they'll issue a descendant changed event.
#
@@ -6789,10 +6816,10 @@
"""Creates a Python dict from a typical attributes list returned from
different AT-SPI methods.
+
Arguments:
- dict_string: A list of colon seperated key/value pairs seperated by
semicolons.
-
Returns a Python dict of the given attributes.
"""
try:
@@ -6802,6 +6829,77 @@
except ValueError:
return {}
+ def _getPopupItemAtDesktopCoords(self, x, y):
+ """Since pop-up items often don't contain nested components, we need
+ a way to efficiently determine if the cursor is over a menu item.
+
+ Arguments:
+ - x: X coordinate.
+ - y: Y coordinate.
+
+ Returns a menu item the mouse is over, or None.
+ """
+ suspect_children = []
+ if self.lastSelectedMenu:
+ try:
+ si = self.lastSelectedMenu.querySelection()
+ except NotImplementedError:
+ return None
+
+ if si.nSelectedChildren > 0:
+ suspect_children = [si.getSelectedChild(0)]
+ else:
+ suspect_children = self.lastSelectedMenu
+ for child in suspect_children:
+ try:
+ ci = child.queryComponent()
+ except NotImplementedError:
+ continue
+
+ if ci.contains(x,y, pyatspi.DESKTOP_COORDS) and \
+ ci.getLayer() == pyatspi.LAYER_POPUP:
+ return child
+
+ def getComponentAtDesktopCoords(self, parent, x, y):
+ """Get the descendant component at the given desktop coordinates.
+
+ Arguments:
+
+ - parent: The parent component we are searching below.
+ - x: X coordinate.
+ - y: Y coordinate.
+
+ Returns end-node that contains the given coordinates, or None.
+ """
+ acc = self._getPopupItemAtDesktopCoords(x, y)
+ if acc:
+ return acc
+
+ container = parent
+ while True:
+ if container.getRole() == pyatspi.ROLE_PAGE_TAB_LIST:
+ try:
+ si = container.querySelection()
+ container = si.getSelectedChild(0)[0]
+ except NotImplementedError:
+ pass
+ try:
+ ci = container.queryComponent()
+ except:
+ return None
+ else:
+ inner_container = container
+ container = ci.getAccessibleAtPoint(x, y, pyatspi.DESKTOP_COORDS)
+ if not container or container.queryComponent() == ci:
+ # The gecko bridge simply has getAccessibleAtPoint return
+ # itself if there are no further children.
+ # TODO: Put in Gecko.py
+ break
+ if inner_container == parent:
+ return None
+ else:
+ return inner_container
+
def getTextSelections(self, acc):
"""Get a list of text selections in the given accessible object,
equivelent to getNSelections()*texti.getSelection()
@@ -6824,6 +6922,17 @@
return rv
+ def speakWordUnderMouse(self, acc):
+ """Determine if the speak-word-under-mouse capability applies to
+ the given accessible.
+
+ Arguments:
+ - acc: Accessible to test.
+
+ Returns True if this accessible should provide the single word.
+ """
+ return acc and acc.getState().contains(pyatspi.STATE_EDITABLE)
+
def getTextAttributes(self, acc, offset, get_defaults=False):
"""Get the text attributes run for a given offset in a given accessible
@@ -6853,6 +6962,58 @@
return rv, start, end
+ def getWordAtCoords(self, acc, x, y):
+ """Get the word at the given coords in the accessible.
+
+ Arguments:
+ - acc: Accessible that supports the Text interface.
+ - x: X coordinate.
+ - y: Y coordinate.
+
+ Returns a tuple containing the word, start offset, and end offset.
+ """
+ try:
+ ti = acc.queryText()
+ except NotImplementedError:
+ return '', 0, 0
+
+ text_contents = ti.getText(0, -1)
+ line_offsets = []
+ start_offset = 0
+ while True:
+ try:
+ end_offset = text_contents.index('\n', start_offset)
+ except ValueError:
+ line_offsets.append((start_offset, len(text_contents)))
+ break
+ line_offsets.append((start_offset, end_offset))
+ start_offset = end_offset + 1
+ for start, end in line_offsets:
+ bx, by, bw, bh = \
+ ti.getRangeExtents(start, end, pyatspi.DESKTOP_COORDS)
+ bb = mouse_review.BoundingBox(bx, by, bw, bh)
+ if bb.isInBox(x, y):
+ start_offset = 0
+ word_offsets = []
+ while True:
+ try:
+ end_offset = \
+ text_contents[start:end].index(' ', start_offset)
+ except ValueError:
+ word_offsets.append((start_offset,
+ len(text_contents[start:end])))
+ break
+ word_offsets.append((start_offset, end_offset))
+ start_offset = end_offset + 1
+ for a, b in word_offsets:
+ bx, by, bw, bh = \
+ ti.getRangeExtents(start+a, start+b,
+ pyatspi.DESKTOP_COORDS)
+ bb = mouse_review.BoundingBox(bx, by, bw, bh)
+ if bb.isInBox(x, y):
+ return text_contents[start+a:start+b], start+a, start+b
+ return '', 0, 0
+
# Dictionary that defines the state changes we care about for various
# objects. The key represents the role and the value represents a list
# of states that we care about.
Modified: trunk/src/orca/focus_tracking_presenter.py
==============================================================================
--- trunk/src/orca/focus_tracking_presenter.py (original)
+++ trunk/src/orca/focus_tracking_presenter.py Fri Mar 28 20:41:31 2008
@@ -266,7 +266,7 @@
return script
- def _getScript(self, app):
+ def getScript(self, app):
"""Get a script for an app (and make it if necessary). This is used
instead of a simple calls to Script's constructor.
@@ -575,7 +575,7 @@
# displayed. See Orca bug #409731 for more details.
#
if not event.type.startswith("mouse:"):
- s = self._getScript(event.host_application or \
+ s = self.getScript(event.host_application or \
event.source.getApplication())
else:
s = orca_state.activeScript
@@ -610,7 +610,7 @@
+ orca_state.activeScript.name)
self.setActiveScript(
- self._getScript(event.host_application or \
+ self.getScript(event.host_application or \
event.source.getApplication()))
# Load in the application specific settings for the
@@ -961,7 +961,7 @@
"""Restores script and application state information."""
try:
for [app, appState] in self._appStateInfo:
- script = self._getScript(app)
+ script = self.getScript(app)
script.setAppState(appState)
except:
pass
@@ -979,7 +979,7 @@
self._restoreAppStates()
- self.setActiveScript(self._getScript(None))
+ self.setActiveScript(self.getScript(None))
# Tell BrlTTY which commands we care about.
#
Added: trunk/src/orca/mouse_review.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/mouse_review.py Fri Mar 28 20:41:31 2008
@@ -0,0 +1,321 @@
+# Mouse reviewer for Orca
+#
+# Copyright 2008 Eitan Isaacson
+#
+# 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Mouse review mode."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2008 Eitan Isaacson"
+__license__ = "LGPL"
+
+import pyatspi
+import orca_state
+import wnck
+import gtk
+import speech
+import braille
+import gobject
+import settings
+import orca
+
+class BoundingBox:
+ """A bounding box, currently it is used to test if a given point is
+ inside the bounds of the box.
+ """
+ # TODO: Find if we pygtk or something already has this,
+ # if not, maybe this needs to be in a different Orca file.
+ def __init__(self, x, y, width, height):
+ """Initialize a bounding box.
+
+ Arguments:
+ - x: Left border of box.
+ - y: Top border of box.
+ - width: Width of box.
+ - height: Height of box.
+ """
+ self.x, self.y, self.width, self.height = x, y, width, height
+
+ def isInBox(self, x, y):
+ """Test if a given point is inside a box.
+
+ Arguments:
+ - x: X coordinate.
+ - y: Y coordinate.
+
+ Returns True if point is inside box.
+ """
+ return (self.x <= x <= self.x + self.width) and \
+ (self.y <= y <= self.y + self.height)
+
+class _WordContext:
+ """A word on which the mouse id hovering above. This class should have
+ enough info to make it unique, so we know when we have left the word.
+ """
+ def __init__(self, word, acc, start, end):
+ """Initialize a word context.
+
+ Arguments:
+ - word: The string of the word we are on.
+ - acc: The accessible object that contains the word.
+ - start: The start offset of the word in the text.
+ - end: The end offset of the word in the text.
+ """
+ self.word = word
+ self.acc = acc
+ self.start = start
+ self.end = end
+
+ def __cmp__(self, other):
+ """Compare two word contexts, if they refer to the same word, return 0.
+ Otherwise return 1
+ """
+ if other is None: return 1
+ return int(not(self.word == other.word and self.acc == other.acc and
+ self.start == other.start and self.end == other.end))
+
+class _ItemContext:
+ """An _ItemContext holds all the information of the item we are currently
+ hovering above. If the accessible supports word speaking, we also store
+ a word context here.
+ """
+ def __init__(self, x=0, y=0, acc=None, frame=None, app=None, script=None):
+ """Initialize an _ItemContext with all the information we have.
+
+ Arguments:
+ - x: The X coordinate of the pointer.
+ - y: The Y coordinate of the pointer.
+ - acc: The end-node accessible at that coordinate.
+ - frame: The top-level frame below the pointer.
+ - app: The application the pointer is hovering above.
+ - script: The script for the context's application.
+ """
+ self.acc = acc
+ self.frame = frame
+ self.app = app
+ self.script = script
+ self.word_ctx = self._getWordContext(x, y)
+
+ def _getWordContext(self, x, y):
+ """If the context's accessible supports it, retrieve the word we are
+ currently hovering above.
+
+ Arguments:
+ - x: The X coordinate of the pointer.
+ - y: The Y coordinate of the pointer.
+
+ Returns a _WordContext of the current word, or None.
+ """
+ if not self.script or not self.script.speakWordUnderMouse(self.acc):
+ return None
+ word, start, end = self.script.getWordAtCoords(self.acc, x, y)
+ return _WordContext(word, self.acc, start, end)
+
+class MouseReviewer:
+ """Main class for the mouse-review feature.
+ """
+ def __init__(self):
+ """Initalize a mouse reviewer class.
+ """
+ # Need to do this and allow the main loop to cycle once to get any info
+ wnck_screen = wnck.screen_get_default()
+ self.active = False
+ self._currentMouseOver = _ItemContext()
+ self._oldMouseOver = _ItemContext()
+ self._lastReportedCoord = None
+
+ def toggle(self, on=None):
+ """Toggle mouse reviewing on or off.
+
+ Arguments:
+ - on: If set to True or False, explicitly toggles reviewing on or off.
+ """
+ if on is None:
+ on = not self.active
+ if on and not self.active:
+ pyatspi.Registry.registerEventListener(self._onMouseMoved,
+ "mouse:abs")
+ elif not on and self.active:
+ pyatspi.Registry.deregisterEventListener(self._onMouseMoved,
+ "mouse:abs")
+ self.active = on
+
+
+ def _onMouseMoved(self, event):
+ """Callback for "mouse:abs" AT-SPI event. We will check after the dwell
+ delay if the mouse moved away, if it didn't we will review the
+ component under it.
+
+ Arguments:
+ - event: The event we recieved.
+ """
+ if settings.mouseDwellDelay:
+ gobject.timeout_add(settings.mouseDwellDelay, self._mouseDwellTimeout,
+ event.detail1, event.detail2)
+ else:
+ self._mouseDwellTimeout(event.detail1, event.detail2)
+
+ def _mouseDwellTimeout(self, prev_x, prev_y):
+ """Dwell timout callback. If we are still dwelling, review the
+ component.
+
+ Arguments:
+ - prev_x: Previuos X coordinate of mouse pointer.
+ - prev_y: Previuos Y coordinate of mouse pointer.
+ """
+ display = gtk.gdk.Display(gtk.gdk.get_display())
+ screen, x, y, flags = display.get_pointer()
+ if abs(prev_x - x) <= settings.mouseDwellMaxDrift and \
+ abs(prev_y - y) <= settings.mouseDwellMaxDrift and \
+ not (x, y) == self._lastReportedCoord:
+ self._lastReportedCoord = (x, y)
+ self._reportUnderMouse(x, y)
+ return False
+
+ def _reportUnderMouse(self, x, y):
+ """Report the element under the given coordinates:
+
+ Arguments:
+ - x: X coordinate.
+ - y: Y coordinate.
+ """
+ current_element = self._getContextUnderMouse(x, y)
+ self._currentMouseOver, self._oldMouseOver = \
+ current_element, self._currentMouseOver
+
+ output_obj = []
+
+ if current_element.acc.getRole() in (pyatspi.ROLE_MENU_ITEM,
+ pyatspi.ROLE_COMBO_BOX) and \
+ current_element.acc.getState().contains(
+ pyatspi.STATE_SELECTED):
+ # If it is selected, we are probably doing that by hovering over it
+ # Orca will report this in any case.
+ return
+
+ if self._currentMouseOver.frame != self._oldMouseOver.frame and \
+ settings.mouseDwellDelay == 0:
+ output_obj.append(self._currentMouseOver.frame)
+
+ if self._currentMouseOver.acc != self._oldMouseOver.acc \
+ or (settings.mouseDwellDelay > 0 and \
+ not self._currentMouseOver.word_ctx):
+ output_obj.append(self._currentMouseOver.acc)
+
+ if self._currentMouseOver.word_ctx:
+ if self._currentMouseOver.word_ctx != self._oldMouseOver.word_ctx:
+ output_obj.append(self._currentMouseOver.word_ctx.word)
+
+ self._outputElements(output_obj)
+ return False
+
+ def _outputElements(self, output_obj):
+ """Output the given elements.
+ TODO: Now we are mainly using WhereAmI, we might need to find out a
+ better, less verbose output method.
+
+ Arguments:
+ - output_obj: A list of objects to output, could be accessibles and
+ text.
+ """
+ if output_obj:
+ speech.stop()
+ for obj in output_obj:
+ if obj is None: continue
+ if isinstance(obj, str):
+ speech.speak(obj)
+ # TODO: There is probably something more useful that we could
+ # display.
+ braille.displayMessage(obj)
+ else:
+ speech.speakUtterances(
+ self._currentMouseOver.script.speechGenerator.getSpeech(
+ obj,
+ False))
+ self._currentMouseOver.script.updateBraille(obj)
+ def _getZOrder(self, frame_name):
+ """Determine the stack position of a given window.
+
+ Arguments:
+ - frame_name: The name of the window.
+
+ Returns position of given window in window-managers stack.
+ """
+ # This is neccesary because z-order is still broken in AT-SPI.
+ wnck_screen = wnck.screen_get_default()
+ window_order = \
+ [w.get_name() for w in wnck_screen.get_windows_stacked()]
+ return window_order.index(frame_name)
+
+ def _getContextUnderMouse(self, x, y):
+ """Get the context under the mouse.
+
+ Arguments:
+ - x: X coordinate.
+ - y: Y coordinate.
+
+ Returns _ItemContext of the component under the mouse.
+ """
+ # Inspect accessible under mouse
+ desktop = pyatspi.Registry.getDesktop(0)
+ top_window = [None, -1]
+ for app in desktop:
+ if not app:
+ continue
+ script = orca.getScriptForApp(app)
+ for frame in app:
+ if not frame:
+ continue
+ acc = script.getComponentAtDesktopCoords(
+ frame, x, y)
+ if acc:
+ try:
+ z_order = self._getZOrder(frame.name)
+ except ValueError:
+ # It's possibly a popup menu, so it would not be in
+ # our frame name list.
+ # And if it is, it is probably the top-most
+ # component.
+ try:
+ if acc.queryComponent().getLayer() == \
+ pyatspi.LAYER_POPUP:
+ return _ItemContext(x, y, acc, frame,
+ app, script)
+ except:
+ pass
+ else:
+ if z_order > top_window[-1]:
+ top_window = \
+ [_ItemContext(x, y, acc, frame, app, script),
+ z_order]
+ return top_window[0]
+
+
+# Initialize a singleton reviewer.
+mouse_reviewer = MouseReviewer()
+
+def toggle(script=None, event=None):
+ """
+ Toggle the reviewer on or off.
+
+ Arguments:
+ - script: Given script if this was called as a keybinding callback.
+ - event: Given event if this was called as a keybinding callback.
+ """
+ mouse_reviewer.toggle()
Modified: trunk/src/orca/orca-setup.glade
==============================================================================
--- trunk/src/orca/orca-setup.glade (original)
+++ trunk/src/orca/orca-setup.glade Fri Mar 28 20:41:31 2008
@@ -299,6 +299,26 @@
<property name="fill">False</property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkCheckButton" id="speakUnderMouseCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Speak object under mo_use</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">True</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="speakUnderMouseChecked" last_modification_time="Mon, 17 Mar 2008 06:29:21 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="tab_expand">False</property>
Modified: trunk/src/orca/orca.py
==============================================================================
--- trunk/src/orca/orca.py (original)
+++ trunk/src/orca/orca.py Fri Mar 28 20:41:31 2008
@@ -62,6 +62,7 @@
import platform
import settings
import speech
+import mouse_review
from input_event import BrailleEvent
from input_event import KeyboardEvent
@@ -141,6 +142,17 @@
_switchToPresentationManager(_currentPresentationManager + 1)
return True
+def getScriptForApp(app):
+ """Get the script for the given application object from the current
+ presentation manager.
+
+ Arguments:
+ - app: An application accessible.
+
+ Returns a Script instance.
+ """
+ return _PRESENTATION_MANAGERS[_currentPresentationManager].getScript(app)
+
########################################################################
# #
# METHODS TO HANDLE APPLICATION LIST AND FOCUSED OBJECTS #
@@ -890,6 +902,11 @@
debug.println(debug.LEVEL_CONFIGURATION,
"Magnification module has NOT been initialized.")
+
+ # I'm not sure where else this should go. But it doesn't really look
+ # right here.
+ mouse_review.mouse_reviewer.toggle(on=settings.enableMouseReview)
+
# We don't want the Caps_Lock modifier to act as a locking
# modifier if it used as the Orca modifier key. In addition, if
# the KP_Insert key is used as the Orca modifier key, we want to
Modified: trunk/src/orca/orca_gui_prefs.py
==============================================================================
--- trunk/src/orca/orca_gui_prefs.py (original)
+++ trunk/src/orca/orca_gui_prefs.py Fri Mar 28 20:41:31 2008
@@ -1456,6 +1456,9 @@
interval = prefs["progressBarUpdateInterval"]
self.get_widget("speakProgressBarSpinButton").set_value(interval)
+ enable = prefs["enableMouseReview"]
+ self.get_widget("speakUnderMouseCheckButton").set_active(enable)
+
# Braille pane.
#
self.get_widget("brailleSupportCheckbutton").set_active( \
@@ -2720,6 +2723,22 @@
self.prefsDict["progressBarUpdateInterval"] = widget.get_value_as_int()
+
+ def speakUnderMouseChecked(self, widget):
+ """Signal handler for the "toggled" signal for the
+ speakUnderMouseCheckButton GtkCheckButton widget.
+ The user has [un]checked the "Speak object under mouse" checkbox.
+ Set the 'enableMouseReview' preference to the new value.
+ Set the rest of the 'dwell time' hbox items [in]sensensitive
+ depending upon whether this checkbox is checked.
+
+ Arguments:
+ - widget: the component that generated the signal.
+ """
+
+ enable = widget.get_active()
+ self.prefsDict["enableMouseReview"] = enable
+
def abbrevRolenamesChecked(self, widget):
"""Signal handler for the "toggled" signal for the abbrevRolenames
GtkCheckButton widget. The user has [un]checked the 'Abbreviated
Modified: trunk/src/orca/settings.py
==============================================================================
--- trunk/src/orca/settings.py (original)
+++ trunk/src/orca/settings.py Fri Mar 28 20:41:31 2008
@@ -157,7 +157,9 @@
"enableProgressBarUpdates",
"progressBarUpdateInterval",
"enableContractedBraille",
- "brailleContractionTable"
+ "brailleContractionTable",
+ "enableMouseReview",
+ "mouseDwellDelay"
]
# The name of the module that hold the user interface for the main window
@@ -919,3 +921,17 @@
# Use Collection Interface?
#
useCollection = True
+
+
+# Report object under mouse.
+#
+enableMouseReview = False
+
+# Mouse dwell delay in milliseconds for mouse review mode.
+# If the value is zero, the review will be read time.
+#
+mouseDwellDelay = 0
+
+# Maximum allowed drift while pointer is dwelling in mouse review mode.
+#
+mouseDwellMaxDrift = 3
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]