Module api
[hide private]
[frames] | no frames]

Source Code for Module api

  1  #api.py 
  2  #A part of NonVisual Desktop Access (NVDA) 
  3  #Copyright (C) 2006-2007 NVDA Contributors <http://www.nvda-project.org/> 
  4  #This file is covered by the GNU General Public License. 
  5  #See the file COPYING for more details. 
  6   
  7  """General functions for NVDA""" 
  8   
  9  import config 
 10  import textInfos 
 11  import globalVars 
 12  from logHandler import log 
 13  import ui 
 14  import treeInterceptorHandler 
 15  import NVDAObjects 
 16  import NVDAObjects.IAccessible 
 17  import winUser 
 18  import controlTypes 
 19  import win32clipboard 
 20  import win32con 
 21  import eventHandler 
 22  import braille 
 23  import watchdog 
 24   
 25  #User functions 
 26   
27 -def getFocusObject():
28 """ 29 Gets the current object with focus. 30 @returns: the object with focus 31 @rtype: L{NVDAObjects.NVDAObject} 32 """ 33 return globalVars.focusObject
34
35 -def getForegroundObject():
36 """Gets the current foreground object. 37 @returns: the current foreground object 38 @rtype: L{NVDAObjects.NVDAObject} 39 """ 40 return globalVars.foregroundObject
41
42 -def setForegroundObject(obj):
43 """Stores the given object as the current foreground object. (Note: it does not physically change the operating system foreground window, but only allows NVDA to keep track of what it is). 44 @param obj: the object that will be stored as the current foreground object 45 @type obj: NVDAObjects.NVDAObject 46 """ 47 if not isinstance(obj,NVDAObjects.NVDAObject): 48 return False 49 globalVars.foregroundObject=obj 50 return True
51
52 -def setFocusObject(obj):
53 """Stores an object as the current focus object. (Note: this does not physically change the window with focus in the operating system, but allows NVDA to keep track of the correct object). 54 Before overriding the last object, this function calls event_loseFocus on the object to notify it that it is loosing focus. 55 @param obj: the object that will be stored as the focus object 56 @type obj: NVDAObjects.NVDAObject 57 """ 58 if not isinstance(obj,NVDAObjects.NVDAObject): 59 return False 60 if globalVars.focusObject: 61 eventHandler.executeEvent("loseFocus",globalVars.focusObject) 62 oldFocusLine=globalVars.focusAncestors 63 #add the old focus to the old focus ancestors, but only if its not None (is none at NVDA initialization) 64 if globalVars.focusObject: 65 oldFocusLine.append(globalVars.focusObject) 66 oldAppModuleSet=set(o.appModule for o in oldFocusLine if o and o.appModule) 67 ancestors=[] 68 tempObj=obj 69 matchedOld=False 70 focusDifferenceLevel=0 71 oldFocusLineLength=len(oldFocusLine) 72 # Starting from the focus, move up the ancestor chain. 73 safetyCount=0 74 while tempObj: 75 if safetyCount<100: 76 safetyCount+=1 77 else: 78 try: 79 log.error("Never ending focus ancestry: last object: %s, %s, window class %s, application name %s"%(tempObj.name,controlTypes.speechRoleLabels[tempObj.role],tempObj.windowClassName,tempObj.appModule.appName)) 80 except: 81 pass 82 tempObj=getDesktopObject() 83 # Scan backwards through the old ancestors looking for a match. 84 for index in xrange(oldFocusLineLength-1,-1,-1): 85 watchdog.alive() 86 if tempObj==oldFocusLine[index]: 87 # Match! The old and new focus ancestors converge at this point. 88 # Copy the old ancestors up to and including this object. 89 origAncestors=oldFocusLine[0:index+1] 90 #make sure to cache the last old ancestor as a parent on the first new ancestor so as not to leave a broken parent cache 91 if ancestors and origAncestors: 92 ancestors[0].parent=origAncestors[-1] 93 origAncestors.extend(ancestors) 94 ancestors=origAncestors 95 focusDifferenceLevel=index+1 96 # We don't need to process any more in either this loop or the outer loop; we have all of the ancestors. 97 matchedOld=True 98 break 99 if matchedOld: 100 break 101 # We're moving backwards along the ancestor chain, so add this to the start of the list. 102 ancestors.insert(0,tempObj) 103 container=tempObj.container 104 tempObj.container=container # Cache the parent. 105 tempObj=container 106 #Remove the final new ancestor as this will be the new focus object 107 del ancestors[-1] 108 newAppModuleSet=set(o.appModule for o in ancestors+[obj] if o and o.appModule) 109 for removedMod in oldAppModuleSet-newAppModuleSet: 110 if not removedMod.sleepMode and hasattr(removedMod,'event_appModule_loseFocus'): 111 try: 112 removedMod.event_appModule_loseFocus() 113 except watchdog.CallCancelled: 114 pass 115 for addedMod in newAppModuleSet-oldAppModuleSet: 116 if not addedMod.sleepMode and hasattr(addedMod,'event_appModule_gainFocus'): 117 addedMod.event_appModule_gainFocus() 118 try: 119 treeInterceptorHandler.cleanup() 120 except watchdog.CallCancelled: 121 pass 122 treeInterceptorObject=None 123 o=None 124 watchdog.alive() 125 for o in ancestors[focusDifferenceLevel:]+[obj]: 126 treeInterceptorObject=treeInterceptorHandler.update(o) 127 #Always make sure that the focus object's treeInterceptor is forced to either the found treeInterceptor (if its in it) or to None 128 #This is to make sure that the treeInterceptor does not have to be looked up, which can cause problems for winInputHook 129 if obj is o or obj in treeInterceptorObject: 130 obj.treeInterceptor=treeInterceptorObject 131 else: 132 obj.treeInterceptor=None 133 # Set global focus variables. 134 globalVars.focusDifferenceLevel=focusDifferenceLevel 135 globalVars.focusObject=obj 136 globalVars.focusAncestors=ancestors 137 braille.invalidateCachedFocusAncestors(focusDifferenceLevel) 138 if config.conf["reviewCursor"]["followFocus"]: 139 setNavigatorObject(obj if not obj.treeInterceptor or obj.treeInterceptor.passThrough or not obj.treeInterceptor.isReady else obj.treeInterceptor.rootNVDAObject) 140 return True
141
142 -def getFocusDifferenceLevel():
143 return globalVars.focusDifferenceLevel
144
145 -def getFocusAncestors():
146 return globalVars.focusAncestors
147
148 -def getMouseObject():
149 """Returns the object that is directly under the mouse""" 150 return globalVars.mouseObject
151
152 -def setMouseObject(obj):
153 """Tells NVDA to remember the given object as the object that is directly under the mouse""" 154 globalVars.mouseObject=obj
155
156 -def getDesktopObject():
157 """Get the desktop object""" 158 return globalVars.desktopObject
159
160 -def setDesktopObject(obj):
161 """Tells NVDA to remember the given object as the desktop object""" 162 globalVars.desktopObject=obj
163
164 -def getReviewPosition():
165 """Retreaves the current TextInfo instance representing the user's review position. If it is not set, it uses the user's set navigator object and creates a TextInfo from that. 166 """ 167 if globalVars.reviewPosition: 168 return globalVars.reviewPosition 169 else: 170 obj=globalVars.navigatorObject 171 ti=obj.treeInterceptor 172 if ti and not ti.passThrough and ti.isReady and ti.rootNVDAObject==obj: 173 obj=ti 174 try: 175 globalVars.reviewPosition=obj.makeTextInfo(textInfos.POSITION_CARET) 176 except (NotImplementedError, RuntimeError): 177 globalVars.reviewPosition=obj.makeTextInfo(textInfos.POSITION_FIRST) 178 globalVars.reviewPositionObj=globalVars.reviewPosition.obj 179 return globalVars.reviewPosition
180
181 -def setReviewPosition(reviewPosition):
182 """Sets a TextInfo instance as the review position. It sets the current navigator object to None so that the next time the navigator object is asked for it fetches it from the review position. 183 """ 184 globalVars.reviewPosition=reviewPosition.copy() 185 globalVars.reviewPositionObj=reviewPosition.obj 186 globalVars.navigatorObject=None 187 import braille 188 braille.handler.handleReviewMove()
189
190 -def getNavigatorObject():
191 """Gets the current navigator object. Navigator objects can be used to navigate around the operating system (with the number pad) with out moving the focus. If the navigator object is not set, it fetches it from the review position. 192 @returns: the current navigator object 193 @rtype: L{NVDAObjects.NVDAObject} 194 """ 195 if globalVars.navigatorObject: 196 return globalVars.navigatorObject 197 else: 198 obj=globalVars.reviewPosition.obj 199 globalVars.navigatorObject=getattr(obj,'rootNVDAObject',None) or obj 200 return globalVars.navigatorObject
201
202 -def setNavigatorObject(obj):
203 """Sets an object to be the current navigator object. Navigator objects can be used to navigate around the operating system (with the number pad) with out moving the focus. It also sets the current review position to None so that next time the review position is asked for, it is created from the navigator object. 204 @param obj: the object that will be set as the current navigator object 205 @type obj: NVDAObjects.NVDAObject 206 """ 207 if not isinstance(obj,NVDAObjects.NVDAObject): 208 return False 209 globalVars.navigatorObject=obj 210 globalVars.reviewPosition=None 211 globalVars.reviewPositionObj=None 212 eventHandler.executeEvent("becomeNavigatorObject",obj)
213
214 -def isTypingProtected():
215 """Checks to see if key echo should be suppressed because the focus is currently on an object that has its protected state set. 216 @returns: True if it should be suppressed, False otherwise. 217 @rtype: boolean 218 """ 219 focusObject=getFocusObject() 220 if focusObject and (controlTypes.STATE_PROTECTED in focusObject.states or focusObject.role==controlTypes.ROLE_PASSWORDEDIT): 221 return True 222 else: 223 return False
224
225 -def createStateList(states):
226 """Breaks down the given integer in to a list of numbers that are 2 to the power of their position.""" 227 return [x for x in [1<<y for y in xrange(32)] if x&states]
228 229
230 -def moveMouseToNVDAObject(obj):
231 """Moves the mouse to the given NVDA object's position""" 232 location=obj.location 233 if location and (len(location)==4): 234 (left,top,width,height)=location 235 x=(left+left+width)/2 236 y=(top+top+height)/2 237 winUser.setCursorPos(x,y)
238
239 -def processPendingEvents(processEventQueue=True):
240 # Import late to avoid circular import. 241 import IAccessibleHandler 242 import JABHandler 243 import wx 244 import queueHandler 245 watchdog.alive() 246 wx.Yield() 247 JABHandler.pumpAll() 248 IAccessibleHandler.pumpAll() 249 import baseObject 250 baseObject.AutoPropertyObject.invalidateCaches() 251 if processEventQueue: 252 queueHandler.flushQueue(queueHandler.eventQueue)
253
254 -def copyToClip(text):
255 """Copies the given text to the windows clipboard. 256 @returns: True if it succeeds, False otherwise. 257 @rtype: boolean 258 @param text: the text which will be copied to the clipboard 259 @type text: string 260 """ 261 if isinstance(text,basestring) and len(text)>0 and not text.isspace(): 262 try: 263 win32clipboard.OpenClipboard() 264 except win32clipboard.error: 265 return False 266 try: 267 win32clipboard.EmptyClipboard() 268 win32clipboard.SetClipboardData(win32con.CF_UNICODETEXT, text) 269 finally: 270 win32clipboard.CloseClipboard() 271 win32clipboard.OpenClipboard() # there seems to be a bug so to retrieve unicode text we have to reopen the clipboard 272 try: 273 got = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT) 274 finally: 275 win32clipboard.CloseClipboard() 276 if got == text: 277 return True 278 return False
279
280 -def getClipData():
281 """Receives text from the windows clipboard. 282 @returns: Clipboard text 283 @rtype: string 284 """ 285 text = "" 286 win32clipboard.OpenClipboard() 287 try: 288 text = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT) 289 finally: 290 win32clipboard.CloseClipboard() 291 return text
292
293 -def getStatusBar():
294 """Obtain the status bar for the current foreground object. 295 @return: The status bar object or C{None} if no status bar was found. 296 @rtype: L{NVDAObjects.NVDAObject} 297 """ 298 # The status bar is usually at the bottom of the screen. 299 # Therefore, get the object at the bottom left of the foreground object using screen coordinates. 300 foreground = getForegroundObject() 301 location=foreground.location 302 if not location: 303 return None 304 left, top, width, height = location 305 bottom = top + height - 1 306 obj = NVDAObjects.IAccessible.getNVDAObjectFromPoint(left, bottom) 307 308 # We may have landed in a child of the status bar, so search the ancestry for a status bar. 309 while obj and not obj.role == controlTypes.ROLE_STATUSBAR: 310 obj = obj.parent 311 312 return obj
313
314 -def getStatusBarText(obj):
315 """Get the text from a status bar. 316 This includes the name of the status bar and the names and values of all of its children. 317 @param obj: The status bar. 318 @type obj: L{NVDAObjects.NVDAObject} 319 @return: The status bar text. 320 @rtype: str 321 """ 322 text = obj.name 323 if text is None: 324 text = "" 325 return text + " ".join(chunk for child in obj.children for chunk in (child.name, child.value) if chunk and isinstance(chunk, basestring) and not chunk.isspace())
326
327 -def filterFileName(name):
328 """Replaces invalid characters in a given string to make a windows compatible file name. 329 @param name: The file name to filter. 330 @type name: str 331 @returns: The filtered file name. 332 @rtype: str 333 """ 334 invalidChars=':?*\|<>/"' 335 for c in invalidChars: 336 name=name.replace(c,'_') 337 return name
338