[Nvda-dev] commit r2869 - in trunk/source: NVDAObjects NVDAObjects/IAccessible appModules config gui

NVDA Subversion svn at nvda-project.org
Tue Apr 14 23:21:07 UTC 2009


Author: nvda
Date: Tue Apr 14 23:20:56 2009
New Revision: 2869

Log:
Changes to progress bar update reporting.
*Move progress bar update reporting code from an IAccessible-specific NVDAObject in to its own module (NVDAObjects.progressBar). This is so that it could be used from other APIs such as Java Access bridge or UI Automation.
*Change configuration options for progress bar reporting:
-add a 'progressBarUpdates' subsection under the presentation section of nvda.ini. and remove old reportProgressBarUpdates option.
-Add options 'progressBarOutputMode', 'reportBackgroundProgressBars', 'speechPercentageInterval', 'beepPercentageInterval', 'beepMinHZ'.
-Object presentation settings dialog now contains a progress bar output combo box allowing you to select from 'off', 'speak', 'beep', and 'beep and speak'. This combo box replaces the old one.
-Object presentation settings dialog now contains a checkbox for configuring whether or not you wish to have background progress bars reported.
 -toggleBeepsForProgressBars script in default appModule is now called toggleProgressBarOutput, and toggles between off, speak, beep, and beep and speak. Note that currently there is now no shortcut for configuring background progress bars, but this could be added if users wanted it.
*Refactered progressBar's event_valueChange to make use of all the new config options, and to make it a bit more abstract (e.g. not relying on foreground windows etc).
It now detects background progress bars by trying to get the object at the screen location of the progress bar, and if its not the progress bar itself, then it must be a background progress bar. 
It now also is smarter about handling multiple progress bars at the same time by caching the last progress value at a particular screen location. 
When only reporting at particular percentage intervals (e.g. speak each 10%) it now will report if the value has changed by that interval, rather than just if it hits that exact interval. For example: if the progress bar starts as 2, it will not speak again until its 12 or above. This makes sure that if the progress bar jumps a value, reporting will still happen.
Beeps can be limited by interval also.


Added:
   trunk/source/NVDAObjects/progressBar.py   (contents, props changed)
Modified:
   trunk/source/NVDAObjects/IAccessible/__init__.py
   trunk/source/appModules/_default.py
   trunk/source/appModules/_default_desktop.kbd
   trunk/source/appModules/_default_laptop.kbd
   trunk/source/config/__init__.py
   trunk/source/gui/settingsDialogs.py

Modified: trunk/source/NVDAObjects/IAccessible/__init__.py
==============================================================================
--- trunk/source/NVDAObjects/IAccessible/__init__.py	(original)
+++ trunk/source/NVDAObjects/IAccessible/__init__.py	Tue Apr 14 23:20:56 2009
@@ -24,6 +24,7 @@
 import eventHandler
 import mouseHandler
 import queueHandler
+from NVDAObjects.progressBar import ProgressBar
 
 def getNVDAObjectFromEvent(hwnd,objectID,childID):
 	accHandle=IAccessibleHandler.accessibleObjectFromEvent(hwnd,objectID,childID)
@@ -559,13 +560,13 @@
 		return res if isinstance(res,int) else 0
 
 	def _get_states(self):
+		states=set()
 		try:
 			IAccessibleStates=self.IAccessibleStates
 		except:
 			log.debugWarning("could not get IAccessible states",exc_info=True)
-			states=set()
 		else:
-			states=set(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in (y for y in (1<<z for z in xrange(32)) if y&IAccessibleStates) if IAccessibleHandler.IAccessibleStatesToNVDAStates.has_key(x))
+			states.update(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in (y for y in (1<<z for z in xrange(32)) if y&IAccessibleStates) if IAccessibleHandler.IAccessibleStatesToNVDAStates.has_key(x))
 		if not hasattr(self.IAccessibleObject,'states'):
 			return states
 		try:
@@ -1112,24 +1113,6 @@
 		if child:
 			speech.speakObject(child,reason=speech.REASON_FOCUS)
 
-class ProgressBar(IAccessible):
-	BASE_BEEP_FREQ=110
-
-	def event_valueChange(self):
-		if config.conf["presentation"]["reportProgressBarUpdates"]=="off":
-			return super(ProgressBar,self).event_valueChange()
-		val=self.value
-		if val:
-			val=val.rstrip('%\x00')
-		if not val or val==globalVars.lastProgressValue:
-			return
-		percentage = min(max(0.0, float(val)), 100.0)
-		if config.conf["presentation"]["reportProgressBarUpdates"] =="all" or (config.conf["presentation"]["reportProgressBarUpdates"] =="visible" and controlTypes.STATE_INVISIBLE not in self.states and winUser.isWindowVisible(self.windowHandle) and winUser.isDescendantWindow(winUser.getForegroundWindow(),self.windowHandle)):
-			tones.beep(self.BASE_BEEP_FREQ*2**(percentage/25.0),40)
-		elif config.conf["presentation"]["reportProgressBarUpdates"] =="speak" and (int(val)%10)==0 and controlTypes.STATE_INVISIBLE not in self.states and winUser.isWindowVisible(self.windowHandle) and winUser.isDescendantWindow(winUser.getForegroundWindow(),self.windowHandle):
-			queueHandler.queueFunction(queueHandler.eventQueue,speech.speakMessage,_("%d percent")%percentage)
-		globalVars.lastProgressValue=val
-
 class InternetExplorerClient(IAccessible):
 
 	def _get_description(self):

Added: trunk/source/NVDAObjects/progressBar.py
==============================================================================
--- (empty file)
+++ trunk/source/NVDAObjects/progressBar.py	Tue Apr 14 23:20:56 2009
@@ -0,0 +1,43 @@
+#NVDAObjects/progressBar.py
+#A part of NonVisual Desktop Access (NVDA)
+#Copyright (C) 2006-2009 NVDA Contributors <http://www.nvda-project.org/>
+#This file is covered by the GNU General Public License.
+#See the file COPYING for more details.
+
+import tones
+import api
+import queueHandler
+import controlTypes
+import globalVars
+import speech
+import config
+from . import NVDAObject
+
+class ProgressBar(NVDAObject):
+
+	progressValueCache={} #key is made of "speech" or "beep" and an x,y coordinate, value is the last percentage
+ 
+	def event_valueChange(self):
+		pbConf=config.conf["presentation"]["progressBarUpdates"]
+		if pbConf["progressBarOutputMode"]=="off" or controlTypes.STATE_INVISIBLE in self.states:
+			return super(ProgressBar,self).event_valueChange()
+		val=self.value
+		if val:
+			val=val.rstrip('%\x00')
+		if not val:
+			return super(ProgressBar,self).event_valueChange()
+		percentage = min(max(0.0, float(val)), 100.0)
+		left,top,width,height=self.location
+		x=left+width/2
+		y=top+height/2
+		screenObj=api.getDesktopObject().objectFromPoint(x,y)
+		if not pbConf["reportBackgroundProgressBars"] and self!=screenObj: 
+			return
+		lastBeepProgressValue=self.progressValueCache.get("beep,%d,%d"%(x,y),None)
+		if pbConf["progressBarOutputMode"] in ("beep","both") and (lastBeepProgressValue is None or abs(percentage-lastBeepProgressValue)>=pbConf["beepPercentageInterval"]):
+			tones.beep(pbConf["beepMinHZ"]*2**(percentage/25.0),40)
+			self.progressValueCache["beep,%d,%d"%(x,y)]=percentage
+		lastSpeechProgressValue=self.progressValueCache.get("speech,%d,%d"%(x,y),None)
+		if pbConf["progressBarOutputMode"] in ("speak","both") and (lastSpeechProgressValue is None or abs(percentage-lastSpeechProgressValue)>=pbConf["speechPercentageInterval"]):
+			queueHandler.queueFunction(queueHandler.eventQueue,speech.speakMessage,_("%d percent")%percentage)
+			self.progressValueCache["speech,%d,%d"%(x,y)]=percentage

Modified: trunk/source/appModules/_default.py
==============================================================================
--- trunk/source/appModules/_default.py	(original)
+++ trunk/source/appModules/_default.py	Tue Apr 14 23:20:56 2009
@@ -714,22 +714,22 @@
 			speech.speakMessage("is unicode: %s"%ctypes.windll.user32.IsWindowUnicode(obj.windowHandle))
 	script_test_navigatorWindowInfo.__doc__ = _("reports some information about the current navigator object, mainly useful for developers. When pressed 2 times it copies control id, class and internal text to the windows clipboard")
 
-	def script_toggleBeepOnProgressBarUpdates(self,keyPress):
-		progressLabels = (
-			("off", _("off")),
-			("visible", _("Beep for visible")),
-			("all", _("Beep for all")),
-			("speak", _("Speak each 10 percent"))
-		)
-
-		for index, (setting, name) in enumerate(progressLabels):
-			if setting == config.conf["presentation"]["reportProgressBarUpdates"]:
-				new=(index+1)%4
-				break
-		config.conf["presentation"]["reportProgressBarUpdates"]=progressLabels[new][0]
-		speech.cancelSpeech()
-		ui.message(progressLabels[new][1])
-	script_toggleBeepOnProgressBarUpdates.__doc__=_("Toggles how NVDA reports progress bar updates. It can beep for all the progress bars or just for the progressbars in the foreground. Additionally it is possible to have current value spoken each 10 percent or it is possible to completely disable this reporting.")
+	def script_toggleProgressBarOutput(self,keyPress):
+		outputMode=config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]
+		if outputMode=="both":
+			outputMode="off"
+			ui.message(_("no progress bar updates"))
+		elif outputMode=="off":
+			outputMode="speak"
+			ui.message(_("speak progress bar updates"))
+		elif outputMode=="speak":
+			outputMode="beep"
+			ui.message(_("beep for progress bar updates"))
+		else:
+			outputMode="both"
+			ui.message(_("beep and speak progress bar updates"))
+		config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]=outputMode
+	script_toggleProgressBarOutput.__doc__=_("Toggles between beeps, speech, beeps and speech, and off, for reporting progress bar updates")
 
 	def script_toggleReportDynamicContentChanges(self,keyPress):
 		if globalVars.reportDynamicContentChanges:

Modified: trunk/source/appModules/_default_desktop.kbd
==============================================================================
--- trunk/source/appModules/_default_desktop.kbd	(original)
+++ trunk/source/appModules/_default_desktop.kbd	Tue Apr 14 23:20:56 2009
@@ -54,7 +54,7 @@
 NVDA+m=toggleMouseTracking
 NVDA+f1=test_navigatorWindowInfo
 Control+NVDA+f1=reportAppModuleInfo
-NVDA+u=toggleBeepOnProgressBarUpdates
+NVDA+u=toggleProgressBarOutput
 NVDA+shift+b=say_battery_status
 NVDA+5=toggleReportDynamicContentChanges
 NVDA+6=toggleCaretMovesReviewCursor

Modified: trunk/source/appModules/_default_laptop.kbd
==============================================================================
--- trunk/source/appModules/_default_laptop.kbd	(original)
+++ trunk/source/appModules/_default_laptop.kbd	Tue Apr 14 23:20:56 2009
@@ -25,7 +25,7 @@
 NVDA+f1=test_navigatorWindowInfo
 NVDA+f2=passNextKeyThrough
 Control+NVDA+f1=reportAppModuleInfo
-Control+NVDA+f2=toggleBeepOnProgressBarUpdates
+Control+NVDA+f2=toggleProgressBarOutput
 NVDA+shift+b=say_battery_status
 Shift+NVDA+ExtendedUp=reportCurrentSelection
 NVDA+ExtendedUp=reportCurrentLine

Modified: trunk/source/config/__init__.py
==============================================================================
--- trunk/source/config/__init__.py	(original)
+++ trunk/source/config/__init__.py	Tue Apr 14 23:20:56 2009
@@ -65,7 +65,13 @@
 		reportHelpBalloons = boolean(default=true)
 		reportObjectDescriptions = boolean(default=True)
 		sayStateFirst = boolean(default=False)
-		reportProgressBarUpdates = string(default=visible)
+	[[progressBarUpdates]]
+		reportBackgroundProgressBars = boolean(default=false)
+		#output modes are beep, speak, both, or off
+		progressBarOutputMode = string(default="beep")
+		speechPercentageInterval = integer(default=10)
+		beepPercentageInterval = integer(default=1)
+		beepMinHZ = integer(default=110)
 
 [mouse]
 	enableMouseTracking = boolean(default=True) #must be true for any of the other settings to work

Modified: trunk/source/gui/settingsDialogs.py
==============================================================================
--- trunk/source/gui/settingsDialogs.py	(original)
+++ trunk/source/gui/settingsDialogs.py	Tue Apr 14 23:20:56 2009
@@ -484,9 +484,9 @@
 	title = _("Object presentation")
 	progressLabels = (
 		("off", _("off")),
-		("visible", _("Beep for visible")),
-		("all", _("Beep for all")),
-		("speak", _("Speak each 10 percent"))
+		("speak", _("Speak")),
+		("beep", _("Beep")),
+		("both", _("Speak and beep")),
 	)
 
 	def makeSettings(self, settingsSizer):
@@ -509,18 +509,21 @@
 		self.stateFirstCheckBox.SetValue(config.conf["presentation"]["sayStateFirst"])
 		settingsSizer.Add(self.stateFirstCheckBox,border=10,flag=wx.BOTTOM)
 		progressSizer=wx.BoxSizer(wx.HORIZONTAL)
-		progressLabel=wx.StaticText(self,-1,label=_("Report progress &bar updates"))
+		progressLabel=wx.StaticText(self,-1,label=_("Progress &bar output"))
 		progressSizer.Add(progressLabel)
 		progressListID=wx.NewId()
-		self.progressList=wx.Choice(self,progressListID,name=_("Report progress bar updates"),choices=[name for setting, name in self.progressLabels])
+		self.progressList=wx.Choice(self,progressListID,name=_("Progress bar output"),choices=[name for setting, name in self.progressLabels])
 		for index, (setting, name) in enumerate(self.progressLabels):
-			if setting == config.conf["presentation"]["reportProgressBarUpdates"]:
+			if setting == config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]:
 				self.progressList.SetSelection(index)
 				break
 		else:
 			log.debugWarning("Could not set progress list to current report progress bar updates setting")
 		progressSizer.Add(self.progressList)
 		settingsSizer.Add(progressSizer,border=10,flag=wx.BOTTOM)
+		self.reportBackgroundProgressBarsCheckBox=wx.CheckBox(self,wx.NewId(),label=_("Report background progress bars"))
+		self.reportBackgroundProgressBarsCheckBox.SetValue(config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"])
+		settingsSizer.Add(self.reportBackgroundProgressBarsCheckBox,border=10,flag=wx.BOTTOM)
 
 	def postInit(self):
 		self.tooltipCheckBox.SetFocus()
@@ -532,7 +535,8 @@
 		config.conf["presentation"]["reportObjectPositionInformation"]=self.positionInfoCheckBox.IsChecked()
 		config.conf["presentation"]["reportObjectDescriptions"]=self.descriptionCheckBox.IsChecked()
 		config.conf["presentation"]["sayStateFirst"]=self.stateFirstCheckBox.IsChecked()
-		config.conf["presentation"]["reportProgressBarUpdates"]=self.progressLabels[self.progressList.GetSelection()][0]
+		config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]=self.progressLabels[self.progressList.GetSelection()][0]
+		config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"]=self.reportBackgroundProgressBarsCheckBox.IsChecked()
 		super(ObjectPresentationDialog, self).onOk(evt)
 
 class VirtualBuffersDialog(SettingsDialog):



More information about the Nvda-dev mailing list