1 new commit in controlUsageAssistant: https://bitbucket.org/nvdaaddonteam/controlusageassistant/commits/1288c61153c7/ Changeset: 1288c61153c7 Branch: master User: josephsl Date: 2013-05-22 21:46:31 Summary: Merged VBuffHandling - 2.0-dev. Affected #: 4 files diff --git a/addon/globalPlugins/controlUsageAssistant/__init__.py b/addon/globalPlugins/controlUsageAssistant/__init__.py index 24dfea9..0818e11 100755 --- a/addon/globalPlugins/controlUsageAssistant/__init__.py +++ b/addon/globalPlugins/controlUsageAssistant/__init__.py @@ -11,35 +11,99 @@ import globalPluginHandler # Basics of Global Plugin. import ui # For speaking and brailling help messages. import api # To fetch object properties. import controlTypes # The heart of this module. +import treeInterceptorHandler # Specifically to deal with virtual buffers. +from virtualBuffers import VirtualBuffer # Virtual buffer handling. import ctrltypelist # The control types and help messages dictionary. +import appModuleHandler # Apps. import addonHandler # Addon basics. addonHandler.initTranslation() # Internationalization. +import tones # For debugging. # Init: class GlobalPlugin(globalPluginHandler.GlobalPlugin): # NVDA+H: Obtain usage help on a particular control. # Depending on the type of control and its state(s), lookup a dictionary of control types and help messages. + # If the control is used differently in apps, then lookup the app entry and give the customized message. def script_obtainControlHelp(self, gesture): - ui.message(self.getHelpMessage(api.getFocusObject())) # The actual function is below. + obj = api.getFocusObject() + # The prototype UI message, the actual processing is done below. + ui.message(self.getHelpMessage(obj)) # Translators: Input help message for obtain control help command. script_obtainControlHelp.__doc__=_("Presents a short message on how to interact with the focused control.") - def getHelpMessage(self, curObj): # Here, we want to present the appropriate help message based on role and state. - msg = "" # An empty string to hold the message; needed to work better with braille. - curRole = curObj.role # Just an int, the key to the help messages dictionary. - curState = curObj._get_states() # To work with states to present appropriate help message. - if curRole not in ctrltypelist.helpMessages: - # Translators: Message presented when there is no help message for the focused control. - msg = _("No help for this control") - elif curRole == 8 and controlTypes.STATE_READONLY in curState: - msg = _(ctrltypelist.helpMessages[-8]) + # GetMessageOffset: Obtain message offset based on appModule and/or processes list. + # Return value: positive = appModule, negative = processes, 0 = default. + def getMessageOffset(self, curObj): + from apphelplist import appOffsets, procOffsets # To be used in the lookup only. + app = curObj.appModule # Detect which app we're running so to give custom help messages for controls. + curAppStr = app.appModuleName.split(".")[0] # Put a formattable string. + curApp = format(curAppStr) + curProc = appModuleHandler.getAppNameFromProcessID(curObj.processID,True) # Borrowed from NVDA core code, used when appModule return fails. + vbuffTest = treeInterceptorHandler.getTreeInterceptor(curObj) # To take care of virtual buffer. + # Lookup setup: + if curApp in appOffsets: + # If appModule is found: + return appOffsets[curApp] + elif curApp == "appModuleHandler" and curProc in procOffsets: + # In case appModule is not found but we do have the current process name registered. + return procOffsets[curProc] + elif isinstance(vbuffTest, VirtualBuffer): + # We're dealing with virtual buffer, so return 200. + return 200 else: - msg = _(ctrltypelist.helpMessages[curRole]) + # Found nothing, so return zero. + return 0 + + # GetHelpMessage: The actual function behind the script above. + def getHelpMessage(self, curObj): + # Present help messages based on role constant, state(s) and focused app. + msg = "" # A string (initially empty) to hold the message; needed to work better with braille. + offset = self.getMessageOffset(curObj) + if offset >= 0: + # We found an appModule. In case of 0, check object state(s). + offset += curObj.role + else: + # No appModule, so work with processes. + offset -= curObj.role + # In case offset is zero, then test for state(s). + # Special case 1: WE have encountered a read-only edit field. + curState = curObj._get_states() + if curObj.role == 8 and controlTypes.STATE_READONLY in curState: + msg = _(ctrltypelist.helpMessages[-8]) + # For general case: let's test if the offset key exists: + # First, if offset is greater than 200 or less than -200. + elif offset >= 200 or offset <= -200: + if offset in ctrltypelist.helpMessages: + msg = ctrltypelist.helpMessages[offset] + else: + msg = ctrltypelist.helpMessages[curObj.role] + # Penultimate: if we're strictly dealing with default messages. + else: + if offset in ctrltypelist.helpMessages: + msg = ctrltypelist.helpMessages[offset] + # Last resort: If we fail to obtain any default or app-specific message (because there is no entry for the role in the help messages), give the below message. + else: + # Translators: Message presented when there is no help message for the focused control. + msg = _("No help for this control") return msg + + # For development testing: + # GetAppName: To see if one can even print the name of the appModule. + def script_getAppName(self, gesture): + appObj = api.getFocusObject() + app = appObj.appModule + #if isinstance(appObj, virtualBuffers.VirtualBuffer): + #if virtualBuffers.VirtualBuffer.event_treeInterceptor_gainFocus(appObj): tones.beep(512, 100) + #elif virtualBuffers.VirtualBuffer.event_treeInterceptor_loseFocus(appObj): tones.beep(256, 100) + test = app.appModuleName.split(".")[0] + offs = self.getMessageOffset(appObj) + test += ", %d" %offs + ui.message(test) __gestures={ "KB:NVDA+H":"obtainControlHelp", + "KB:NVDA+G":"getAppName", } # End. \ No newline at end of file diff --git a/addon/globalPlugins/controlUsageAssistant/apphelplist.py b/addon/globalPlugins/controlUsageAssistant/apphelplist.py new file mode 100755 index 0000000..5957632 --- /dev/null +++ b/addon/globalPlugins/controlUsageAssistant/apphelplist.py @@ -0,0 +1,17 @@ +# Control Usage Assistant +# An add-on for NVDA +# Copyright 2013 Joseph Lee, released under GPL. + +# AppModule and process offsets: positive = appModule, negative = process. + +# App offsets: lookup the appModule. +appOffsets={ + "explorer":300, + "powerpnt":400 + } + +# Process offsets: come here when we fail to obtain appModules. +procOffsets={ + "EXCEL.EXE":-300 + } + diff --git a/addon/globalPlugins/controlUsageAssistant/ctrltypelist.py b/addon/globalPlugins/controlUsageAssistant/ctrltypelist.py index d89adc7..5751688 100755 --- a/addon/globalPlugins/controlUsageAssistant/ctrltypelist.py +++ b/addon/globalPlugins/controlUsageAssistant/ctrltypelist.py @@ -4,10 +4,13 @@ # The list of control types and their help messages. - # Help Messages Dictionary: key = obj role number. - #a negative role number indicates restricted control, such as read-only edit field. + # Help Messages Dictionary: key = obj role number, with offsets added based on apps and/or states. + #a negative role number between -1 and -199 indicates restricted control, such as read-only edit field. # A role number greater than 200 indicates additional features, such as multiline and virtual buffer instance. + # Anything beyond +/-400 means appModule or process-specific (positive = appModule, negative = process). helpMessages = { + # Default: universal across apps and states. + # Translators: Help message for a checkbox. 5:_("Press space to check or uncheck the checkbox"), # Translators: Help message for working with radio buttons. @@ -41,5 +44,23 @@ helpMessages = { # Translators: Help message for navigating table cells. 29:_("Press control, alt and arrow keys together to move between table cells"), # Translators: Help message for reading documents (mostly encountered in Internet Explorer windows). - 52:_("Use the arrow keys or object navigation commands to move through the document") + 52:_("Use the arrow keys or object navigation commands to move through the document"), + 64:"Press enter to interact with the embedded object. Press CONTROL+NVDA+SPACE to return to the website text", + + # 200: Virtual Buffer. + 252:"Use the browse mode and quick navigation commands to read through the webpage", + + # App-specific case 1: AppeModule for app is present. + + # 300: Explorer (to deal with specific cases. + 329:"Use the arrow keys to move between start screen tiles", + + # 400: Microsoft powerpoint (powerpnt): + 403:"Use up and down arrow keys to move between slides", + + + # App-specific case 2: AppeModule for app is not present (use processes). + # -300: Excel. + + -329:_("Use the arrow keys to move between spreadsheet cells") } diff --git a/buildVars.py b/buildVars.py index 46d1a0f..c5a483d 100755 --- a/buildVars.py +++ b/buildVars.py @@ -16,7 +16,7 @@ addon_info = { "addon-description" : _("""Allows you to find out how to interact with the focused control, useful for new computer users new to Windows and to NvDA. Press NvDA+H to get a short help message on using the focused control, such as moving through tables, checkboxes and so on."""), # version - "addon-version" : "1.0", + "addon-version" : "2.0-dev", # Author(s) "addon-author" : "Joseph Lee <joseph.lee22590@xxxxxxxxx>", # URL for the add-on documentation support Repository URL: https://bitbucket.org/nvdaaddonteam/controlusageassistant/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. ---------------------------------------------------------------- NVDA add-ons Central: A list for discussing NVDA add-ons To post a message, send an email to nvda-addons@xxxxxxxxxxxxx. To unsubscribe, send an email with the subject line of "unsubscribe" (without quotes) to nvda-addons-request@xxxxxxxxxxxxx. If you have questions for list moderators, please send a message to nvda-addons-moderators@xxxxxxxxxxxxx.