Package NVDAObjects
[hide private]
[frames] | no frames]

Source Code for Package NVDAObjects

  1  #NVDAObjects/baseType.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  """Module that contains the base NVDA object type""" 
  8  from new import instancemethod 
  9  import time 
 10  import re 
 11  import weakref 
 12  from logHandler import log 
 13  import eventHandler 
 14  from displayModel import DisplayModelTextInfo 
 15  import baseObject 
 16  import speech 
 17  import api 
 18  import textInfos.offsets 
 19  import config 
 20  import controlTypes 
 21  import appModuleHandler 
 22  import treeInterceptorHandler 
 23  import braille 
 24  import globalPluginHandler 
25 26 -class NVDAObjectTextInfo(textInfos.offsets.OffsetsTextInfo):
27 """A default TextInfo which is used to enable text review of information about widgets that don't support text content. 28 The L{NVDAObject.basicText} attribute is used as the text to expose. 29 """ 30
31 - def _get_unit_mouseChunk(self):
32 return textInfos.UNIT_STORY
33
34 - def _getStoryText(self):
35 return self.obj.basicText
36
37 - def _getStoryLength(self):
38 return len(self._getStoryText())
39
40 - def _getTextRange(self,start,end):
41 text=self._getStoryText() 42 return text[start:end]
43
44 -class InvalidNVDAObject(RuntimeError):
45 """Raised by NVDAObjects during construction to inform that this object is invalid. 46 In this case, for the purposes of NVDA, the object should be considered non-existent. 47 Therefore, L{DynamicNVDAObjectType} will return C{None} if this exception is raised. 48 """
49
50 -class DynamicNVDAObjectType(baseObject.ScriptableObject.__class__):
51 _dynamicClassCache={} 52
53 - def __call__(self,chooseBestAPI=True,**kwargs):
54 if chooseBestAPI: 55 APIClass=self.findBestAPIClass(kwargs) 56 if not APIClass: return None 57 else: 58 APIClass=self 59 60 # Instantiate the requested class. 61 try: 62 obj=APIClass.__new__(APIClass,**kwargs) 63 obj.APIClass=APIClass 64 if isinstance(obj,self): 65 obj.__init__(**kwargs) 66 except InvalidNVDAObject, e: 67 log.debugWarning("Invalid NVDAObject: %s" % e, stack_info=True) 68 return None 69 70 clsList = [] 71 if "findOverlayClasses" in APIClass.__dict__: 72 obj.findOverlayClasses(clsList) 73 else: 74 clsList.append(APIClass) 75 # Allow app modules to choose overlay classes. 76 appModule=obj.appModule 77 if appModule and "chooseNVDAObjectOverlayClasses" in appModule.__class__.__dict__: 78 appModule.chooseNVDAObjectOverlayClasses(obj, clsList) 79 # Allow global plugins to choose overlay classes. 80 for plugin in globalPluginHandler.runningPlugins: 81 if "chooseNVDAObjectOverlayClasses" in plugin.__class__.__dict__: 82 plugin.chooseNVDAObjectOverlayClasses(obj, clsList) 83 84 # Determine the bases for the new class. 85 bases=[] 86 for index in xrange(len(clsList)): 87 # A class doesn't need to be a base if it is already implicitly included by being a superclass of a previous base. 88 if index==0 or not issubclass(clsList[index-1],clsList[index]): 89 bases.append(clsList[index]) 90 91 # Construct the new class. 92 if len(bases) == 1: 93 # We only have one base, so there's no point in creating a dynamic type. 94 newCls=bases[0] 95 else: 96 bases=tuple(bases) 97 newCls=self._dynamicClassCache.get(bases,None) 98 if not newCls: 99 name="Dynamic_%s"%"".join([x.__name__ for x in clsList]) 100 newCls=type(name,bases,{}) 101 self._dynamicClassCache[bases]=newCls 102 103 oldMro=frozenset(obj.__class__.__mro__) 104 # Mutate obj into the new class. 105 obj.__class__=newCls 106 107 # Initialise the overlay classes. 108 for cls in reversed(newCls.__mro__): 109 if cls in oldMro: 110 # This class was part of the initially constructed object, so its constructor would have been called. 111 continue 112 initFunc=cls.__dict__.get("initOverlayClass") 113 if initFunc: 114 initFunc(obj) 115 # Bind gestures specified on the class. 116 try: 117 obj.bindGestures(getattr(cls, "_%s__gestures" % cls.__name__)) 118 except AttributeError: 119 pass 120 121 # Allow app modules to make minor tweaks to the instance. 122 if appModule and hasattr(appModule,"event_NVDAObject_init"): 123 appModule.event_NVDAObject_init(obj) 124 125 return obj
126 127 @classmethod
128 - def clearDynamicClassCache(cls):
129 """Clear the dynamic class cache. 130 This should be called when a plugin is unloaded so that any used overlay classes in the unloaded plugin can be garbage collected. 131 """ 132 cls._dynamicClassCache.clear()
133
134 -class NVDAObject(baseObject.ScriptableObject):
135 """NVDA's representation of a single control/widget. 136 Every widget, regardless of how it is exposed by an application or the operating system, is represented by a single NVDAObject instance. 137 This allows NVDA to work with all widgets in a uniform way. 138 An NVDAObject provides information about the widget (e.g. its name, role and value), 139 as well as functionality to manipulate it (e.g. perform an action or set focus). 140 Events for the widget are handled by special event methods on the object. 141 Commands triggered by input from the user can also be handled by special methods called scripts. 142 See L{ScriptableObject} for more details. 143 144 The only attribute that absolutely must be provided is L{processID}. 145 However, subclasses should provide at least the L{name} and L{role} attributes in order for the object to be meaningful to the user. 146 Attributes such as L{parent}, L{firstChild}, L{next} and L{previous} link an instance to other NVDAObjects in the hierarchy. 147 In order to facilitate access to text exposed by a widget which supports text content (e.g. an editable text control), 148 a L{textInfos.TextInfo} should be implemented and the L{TextInfo} attribute should specify this class. 149 150 There are two main types of NVDAObject classes: 151 * API classes, which provide the core functionality to work with objects exposed using a particular API (e.g. MSAA/IAccessible). 152 * Overlay classes, which supplement the core functionality provided by an API class to handle a specific widget or type of widget. 153 Most developers need only be concerned with overlay classes. 154 The overlay classes to be used for an instance are determined using the L{findOverlayClasses} method on the API class. 155 An L{AppModule} can also choose overlay classes for an instance using the L{AppModule.chooseNVDAObjectOverlayClasses} method. 156 """ 157 158 __metaclass__=DynamicNVDAObjectType 159 cachePropertiesByDefault = True 160 161 #: The TextInfo class this object should use to provide access to text. 162 #: @type: type; L{textInfos.TextInfo} 163 TextInfo=NVDAObjectTextInfo 164 165 @classmethod
166 - def findBestAPIClass(cls,kwargs,relation=None):
167 """ 168 Finds out the highest-level APIClass this object can get to given these kwargs, and updates the kwargs and returns the APIClass. 169 @param relation: the relationship of a possible new object of this type to another object creating it (e.g. parent). 170 @param type: string 171 @param kwargs: the arguments necessary to construct an object of the class this method was called on. 172 @type kwargs: dictionary 173 @returns: the new APIClass 174 @rtype: DynamicNVDAObjectType 175 """ 176 newAPIClass=cls 177 if 'getPossibleAPIClasses' in newAPIClass.__dict__: 178 for possibleAPIClass in newAPIClass.getPossibleAPIClasses(kwargs,relation=relation): 179 if 'kwargsFromSuper' not in possibleAPIClass.__dict__: 180 log.error("possible API class %s does not implement kwargsFromSuper"%possibleAPIClass) 181 continue 182 if possibleAPIClass.kwargsFromSuper(kwargs,relation=relation): 183 return possibleAPIClass.findBestAPIClass(kwargs,relation=relation) 184 return newAPIClass if newAPIClass is not NVDAObject else None
185 186 187 @classmethod
188 - def getPossibleAPIClasses(cls,kwargs,relation=None):
189 """ 190 Provides a generator which can generate all the possible API classes (in priority order) that inherit directly from the class it was called on. 191 @param relation: the relationship of a possible new object of this type to another object creating it (e.g. parent). 192 @param type: string 193 @param kwargs: the arguments necessary to construct an object of the class this method was called on. 194 @type kwargs: dictionary 195 @returns: a generator 196 @rtype: generator 197 """ 198 import NVDAObjects.window 199 yield NVDAObjects.window.Window
200 201 @classmethod
202 - def kwargsFromSuper(cls,kwargs,relation=None):
203 """ 204 Finds out if this class can be instanciated from the given super kwargs. 205 If so it updates the kwargs to contain everything it will need to instanciate this class, and returns True. 206 If this class can not be instanciated, it returns False and kwargs is not touched. 207 @param relation: why is this class being instanciated? parent, focus, foreground etc... 208 @type relation: string 209 @param kwargs: the kwargs for constructing this class's super class. 210 @type kwargs: dict 211 @rtype: boolean 212 """ 213 raise NotImplementedError
214 215
216 - def findOverlayClasses(self, clsList):
217 """Chooses overlay classes which should be added to this object's class structure after the object has been initially instantiated. 218 After an NVDAObject class (normally an API-level class) is instantiated, this method is called on the instance to choose appropriate overlay classes. 219 This method may use properties, etc. on the instance to make this choice. 220 The object's class structure is then mutated to contain these classes. 221 L{initOverlayClass} is then called for each class which was not part of the initially instantiated object. 222 This process allows an NVDAObject to be dynamically created using the most appropriate NVDAObject subclass at each API level. 223 Classes should be listed with subclasses first. That is, subclasses should generally call super and then append their own classes to the list. 224 For example: Called on an IAccessible NVDAObjectThe list might contain DialogIaccessible (a subclass of IAccessible), Edit (a subclass of Window). 225 @param clsList: The list of classes, which will be modified by this method if appropriate. 226 @type clsList: list of L{NVDAObject} 227 """ 228 clsList.append(NVDAObject)
229 230 beTransparentToMouse=False #:If true then NVDA will never consider the mouse to be on this object, rather it will be on an ancestor. 231 232 @staticmethod
233 - def objectFromPoint(x,y):
234 """Retreaves an NVDAObject instance representing a control in the Operating System at the given x and y coordinates. 235 @param x: the x coordinate. 236 @type x: int 237 @param y: the y coordinate. 238 @param y: int 239 @return: The object at the given x and y coordinates. 240 @rtype: L{NVDAObject} 241 """ 242 kwargs={} 243 APIClass=NVDAObject.findBestAPIClass(kwargs,relation=(x,y)) 244 return APIClass(chooseBestAPI=False,**kwargs) if APIClass else None
245 246 @staticmethod
247 - def objectWithFocus():
248 """Retreaves the object representing the control currently with focus in the Operating System. This differens from NVDA's focus object as this focus object is the real focus object according to the Operating System, not according to NVDA. 249 @return: the object with focus. 250 @rtype: L{NVDAObject} 251 """ 252 kwargs={} 253 APIClass=NVDAObject.findBestAPIClass(kwargs,relation="focus") 254 return APIClass(chooseBestAPI=False,**kwargs) if APIClass else None
255 256 @staticmethod
257 - def objectInForeground():
258 """Retreaves the object representing the current foreground control according to the Operating System. This differes from NVDA's foreground object as this object is the real foreground object according to the Operating System, not according to NVDA. 259 @return: the foreground object 260 @rtype: L{NVDAObject} 261 """ 262 kwargs={} 263 APIClass=NVDAObject.findBestAPIClass(kwargs,relation="foreground") 264 return APIClass(chooseBestAPI=False,**kwargs) if APIClass else None
265 266
267 - def __init__(self):
268 super(NVDAObject,self).__init__() 269 self._mouseEntered=False #:True if the mouse has entered this object (for use in L{event_mouseMoved}) 270 self.textRepresentationLineLength=None #:If an integer greater than 0 then lines of text in this object are always this long.
271
272 - def _isEqual(self,other):
273 """Calculates if this object is equal to another object. Used by L{NVDAObject.__eq__}. 274 @param other: the other object to compare with. 275 @type other: L{NVDAObject} 276 @return: True if equal, false otherwise. 277 @rtype: boolean 278 """ 279 return True
280
281 - def __eq__(self,other):
282 """Compaires the objects' memory addresses, their type, and uses L{NVDAObject._isEqual} to see if they are equal. 283 """ 284 if self is other: 285 return True 286 if type(self) is not type(other): 287 return False 288 return self._isEqual(other)
289
290 - def __ne__(self,other):
291 """The opposite to L{NVDAObject.__eq__} 292 """ 293 return not self.__eq__(other)
294
296 """ 297 If this NVDAObject should use a treeInterceptor, then this property provides the L{treeInterceptorHandler.TreeInterceptor} class it should use. 298 If not then it should be not implemented. 299 """ 300 raise NotImplementedError
301
302 - def _get_treeInterceptor(self):
303 """Retreaves the treeInterceptor associated with this object. 304 If a treeInterceptor has not been specifically set, the L{treeInterceptorHandler} is asked if it can find a treeInterceptor containing this object. 305 @return: the treeInterceptor 306 @rtype: L{treeInterceptorHandler.TreeInterceptor} 307 """ 308 if hasattr(self,'_treeInterceptor'): 309 ti=self._treeInterceptor 310 if isinstance(ti,weakref.ref): 311 ti=ti() 312 if ti and ti in treeInterceptorHandler.runningTable: 313 return ti 314 else: 315 self._treeInterceptor=None 316 return None 317 else: 318 ti=treeInterceptorHandler.getTreeInterceptor(self) 319 if ti: 320 self._treeInterceptor=weakref.ref(ti) 321 return ti
322
323 - def _set_treeInterceptor(self,obj):
324 """Specifically sets a treeInterceptor to be associated with this object. 325 """ 326 if obj: 327 self._treeInterceptor=weakref.ref(obj) 328 else: #We can't point a weakref to None, so just set the private variable to None, it can handle that 329 self._treeInterceptor=None
330
331 - def _get_appModule(self):
332 """Retreaves the appModule representing the application this object is a part of by asking L{appModuleHandler}. 333 @return: the appModule 334 @rtype: L{appModuleHandler.AppModule} 335 """ 336 if not hasattr(self,'_appModuleRef'): 337 a=appModuleHandler.getAppModuleForNVDAObject(self) 338 if a: 339 self._appModuleRef=weakref.ref(a) 340 return a 341 else: 342 return self._appModuleRef()
343
344 - def _get_name(self):
345 """The name or label of this object (example: the text of a button). 346 @rtype: basestring 347 """ 348 return ""
349
350 - def _get_role(self):
351 """The role or type of control this object represents (example: button, list, dialog). 352 @return: a ROLE_* constant from L{controlTypes} 353 @rtype: int 354 """ 355 return controlTypes.ROLE_UNKNOWN
356
357 - def _get_value(self):
358 """The value of this object (example: the current percentage of a scrollbar, the selected option in a combo box). 359 @rtype: basestring 360 """ 361 return ""
362
363 - def _get_description(self):
364 """The description or help text of this object. 365 @rtype: basestring 366 """ 367 return ""
368
369 - def _get_actionCount(self):
370 """Retreaves the number of actions supported by this object.""" 371 return 0
372
373 - def getActionName(self,index=None):
374 """Retreaves the name of an action supported by this object. 375 If index is not given then the default action will be used if it exists. 376 @param index: the optional 0-based index of the wanted action. 377 @type index: int 378 @return: the action's name 379 @rtype: basestring 380 """ 381 raise NotImplementedError
382
383 - def doAction(self,index=None):
384 """Performs an action supported by this object. 385 If index is not given then the default action will be used if it exists. 386 """ 387 raise NotImplementedError
388
389 - def _get_defaultActionIndex(self):
390 """Retreaves the index of the action that is the default.""" 391 return 0
392
393 - def _get_keyboardShortcut(self):
394 """The shortcut key that activates this object(example: alt+t). 395 @rtype: basestring 396 """ 397 return ""
398
399 - def _get_isInForeground(self):
400 """ 401 Finds out if this object is currently within the foreground. 402 """ 403 raise NotImplementedError
404
405 - def _get_states(self):
406 """Retreaves the current states of this object (example: selected, focused). 407 @return: a set of STATE_* constants from L{controlTypes}. 408 @rtype: set of int 409 """ 410 return set()
411
412 - def _get_location(self):
413 """The location of this object on the screen. 414 @return: left, top, width and height of the object. 415 @rtype: tuple of int 416 """ 417 raise NotImplementedError
418
419 - def _get_parent(self):
420 """Retreaves this object's parent (the object that contains this object). 421 @return: the parent object if it exists else None. 422 @rtype: L{NVDAObject} or None 423 """ 424 return None
425
426 - def _get_container(self):
427 """ 428 Exactly like parent, however another object at this same sibling level may be retreaved first (e.g. a groupbox). Mostly used when presenting context such as focus ancestry. 429 """ 430 return self.parent
431
432 - def _get_next(self):
433 """Retreaves the object directly after this object with the same parent. 434 @return: the next object if it exists else None. 435 @rtype: L{NVDAObject} or None 436 """ 437 return None
438
439 - def _get_previous(self):
440 """Retreaves the object directly before this object with the same parent. 441 @return: the previous object if it exists else None. 442 @rtype: L{NVDAObject} or None 443 """ 444 return None
445
446 - def _get_firstChild(self):
447 """Retreaves the first object that this object contains. 448 @return: the first child object if it exists else None. 449 @rtype: L{NVDAObject} or None 450 """ 451 return None
452
453 - def _get_lastChild(self):
454 """Retreaves the last object that this object contains. 455 @return: the last child object if it exists else None. 456 @rtype: L{NVDAObject} or None 457 """ 458 return None
459
460 - def _get_children(self):
461 """Retreaves a list of all the objects directly contained by this object (who's parent is this object). 462 @rtype: list of L{NVDAObject} 463 """ 464 children=[] 465 child=self.firstChild 466 while child: 467 children.append(child) 468 child=child.next 469 return children
470
471 - def _get_rowNumber(self):
472 """Retreaves the row number of this object if it is in a table. 473 @rtype: int 474 """ 475 raise NotImplementedError
476
477 - def _get_columnNumber(self):
478 """Retreaves the column number of this object if it is in a table. 479 @rtype: int 480 """ 481 raise NotImplementedError
482
483 - def _get_rowCount(self):
484 """Retreaves the number of rows this object contains if its a table. 485 @rtype: int 486 """ 487 raise NotImplementedError
488
489 - def _get_columnCount(self):
490 """Retreaves the number of columns this object contains if its a table. 491 @rtype: int 492 """ 493 raise NotImplementedError
494 495 tableCellCoordsInName=False #:True if the object's name contains the cell coordinates, such as 'A1'. Speech and Braille can choose to in this case not present the actual row and column information as the name is already enough. 496
497 - def _get_table(self):
498 """Retreaves the object that represents the table that this object is contained in, if this object is a table cell. 499 @rtype: L{NVDAObject} 500 """ 501 raise NotImplementedError
502
504 """Recursively traverse and return the descendants of this object. 505 This is a depth-first forward traversal. 506 @return: The recursive descendants of this object. 507 @rtype: generator of L{NVDAObject} 508 """ 509 for child in self.children: 510 yield child 511 for recursiveChild in child.recursiveDescendants: 512 yield recursiveChild
513 514 presType_unavailable="unavailable" 515 presType_layout="layout" 516 presType_content="content" 517
518 - def _get_presentationType(self):
519 states=self.states 520 if controlTypes.STATE_INVISIBLE in states or controlTypes.STATE_UNAVAILABLE in states: 521 return self.presType_unavailable 522 role=self.role 523 524 #Static text should be content only if it really use usable text 525 if role==controlTypes.ROLE_STATICTEXT: 526 text=self.makeTextInfo(textInfos.POSITION_ALL).text 527 return self.presType_content if text and not text.isspace() else self.presType_layout 528 529 if role in (controlTypes.ROLE_UNKNOWN, controlTypes.ROLE_PANE, controlTypes.ROLE_TEXTFRAME, controlTypes.ROLE_ROOTPANE, controlTypes.ROLE_LAYEREDPANE, controlTypes.ROLE_SCROLLPANE, controlTypes.ROLE_SECTION,controlTypes.ROLE_PARAGRAPH,controlTypes.ROLE_TITLEBAR,controlTypes.ROLE_LABEL): 530 return self.presType_layout 531 name = self.name 532 description = self.description 533 if not name and not description: 534 if role in (controlTypes.ROLE_WINDOW,controlTypes.ROLE_PANEL, controlTypes.ROLE_PROPERTYPAGE, controlTypes.ROLE_TEXTFRAME, controlTypes.ROLE_GROUPING,controlTypes.ROLE_OPTIONPANE,controlTypes.ROLE_INTERNALFRAME,controlTypes.ROLE_FORM,controlTypes.ROLE_TABLEBODY): 535 return self.presType_layout 536 if role == controlTypes.ROLE_TABLE and not config.conf["documentFormatting"]["reportTables"]: 537 return self.presType_layout 538 if role in (controlTypes.ROLE_TABLEROW,controlTypes.ROLE_TABLECOLUMN,controlTypes.ROLE_TABLECELL) and (not config.conf["documentFormatting"]["reportTables"] or not config.conf["documentFormatting"]["reportTableCellCoords"]): 539 return self.presType_layout 540 if role in (controlTypes.ROLE_TABLEROW,controlTypes.ROLE_TABLECOLUMN): 541 try: 542 table=self.table 543 except NotImplementedError: 544 table=None 545 if table: 546 # This is part of a real table, so the cells will report row/column information. 547 # Therefore, this object is just for layout. 548 return self.presType_layout 549 return self.presType_content
550
551 - def _get_simpleParent(self):
552 obj=self.parent 553 while obj and obj.presentationType!=self.presType_content: 554 obj=obj.parent 555 return obj
556
557 - def _findSimpleNext(self,useChild=False,useParent=True,goPrevious=False):
558 nextPrevAttrib="next" if not goPrevious else "previous" 559 firstLastChildAttrib="firstChild" if not goPrevious else "lastChild" 560 found=None 561 if useChild: 562 child=getattr(self,firstLastChildAttrib) 563 childPresType=child.presentationType if child else None 564 if childPresType==self.presType_content: 565 found=child 566 elif childPresType==self.presType_layout: 567 found=child._findSimpleNext(useChild=True,useParent=False,goPrevious=goPrevious) 568 elif child: 569 found=child._findSimpleNext(useChild=False,useParent=False,goPrevious=goPrevious) 570 if found: 571 return found 572 next=getattr(self,nextPrevAttrib) 573 nextPresType=next.presentationType if next else None 574 if nextPresType==self.presType_content: 575 found=next 576 elif nextPresType==self.presType_layout: 577 found=next._findSimpleNext(useChild=True,useParent=False,goPrevious=goPrevious) 578 elif next: 579 found=next._findSimpleNext(useChild=False,useParent=False,goPrevious=goPrevious) 580 if found: 581 return found 582 parent=self.parent if useParent else None 583 while parent and parent.presentationType!=self.presType_content: 584 next=parent._findSimpleNext(useChild=False,useParent=False,goPrevious=goPrevious) 585 if next: 586 return next 587 parent=parent.parent
588
589 - def _get_simpleNext(self):
590 return self._findSimpleNext()
591
592 - def _get_simplePrevious(self):
593 return self._findSimpleNext(goPrevious=True)
594
595 - def _get_simpleFirstChild(self):
596 child=self.firstChild 597 if not child: 598 return None 599 presType=child.presentationType 600 if presType!=self.presType_content: return child._findSimpleNext(useChild=(presType!=self.presType_unavailable),useParent=False) 601 return child
602
603 - def _get_simpleLastChild(self):
604 child=self.lastChild 605 if not child: 606 return None 607 presType=child.presentationType 608 if presType!=self.presType_content: return child._findSimpleNext(useChild=(presType!=self.presType_unavailable),useParent=False,goPrevious=True) 609 return child
610
611 - def _get_childCount(self):
612 """Retreaves the number of children this object contains. 613 @rtype: int 614 """ 615 return len(self.children)
616
617 - def _get_activeChild(self):
618 """Retreaves the child of this object that currently has, or contains, the focus. 619 @return: the active child if it has one else None 620 @rtype: L{NVDAObject} or None 621 """ 622 return None
623
624 - def setFocus(self):
625 """ 626 Tries to force this object to take the focus. 627 """ 628 pass
629
630 - def scrollIntoView(self):
631 """Scroll this object into view on the screen if possible. 632 """ 633 raise NotImplementedError
634
635 - def _get_labeledBy(self):
636 """Retreaves the object that this object is labeled by (example: the static text label beside an edit field). 637 @return: the label object if it has one else None. 638 @rtype: L{NVDAObject} or None 639 """ 640 return None
641
642 - def _get_positionInfo(self):
643 """Retreaves position information for this object such as its level, its index with in a group, and the number of items in that group. 644 @return: a dictionary containing any of level, groupIndex and similarItemsInGroup. 645 @rtype: dict 646 """ 647 return {}
648
649 - def _get_processID(self):
650 """Retreaves an identifyer of the process this object is a part of. 651 @rtype: int 652 """ 653 raise NotImplementedError
654
655 - def _get_isProtected(self):
656 """ 657 @return: True if this object is protected (hides its input for passwords), or false otherwise 658 @rtype: boolean 659 """ 660 return False
661
662 - def _get_indexInParent(self):
663 """The index of this object in its parent object. 664 @return: The 0 based index, C{None} if there is no parent. 665 @rtype: int 666 @raise NotImplementedError: If not supported by the underlying object. 667 """ 668 raise NotImplementedError
669
670 - def _get_flowsTo(self):
671 """The object to which content flows from this object. 672 @return: The object to which this object flows, C{None} if none. 673 @rtype: L{NVDAObject} 674 @raise NotImplementedError: If not supported by the underlying object. 675 """ 676 raise NotImplementedError
677
678 - def _get_flowsFrom(self):
679 """The object from which content flows to this object. 680 @return: The object from which this object flows, C{None} if none. 681 @rtype: L{NVDAObject} 682 @raise NotImplementedError: If not supported by the underlying object. 683 """ 684 raise NotImplementedError
685
686 - def _get_embeddingTextInfo(self):
687 """Retrieve the parent text range which embeds this object. 688 The returned text range will have its start positioned on the embedded object character associated with this object. 689 That is, calling L{textInfos.TextInfo.getEmbeddedObject}() on the returned text range will return this object. 690 @return: The text range for the embedded object character associated with this object or C{None} if this is not an embedded object. 691 @rtype: L{textInfos.TextInfo} 692 @raise NotImplementedError: If not supported. 693 """ 694 raise NotImplementedError
695
697 """Determine if this object should be presented to the user in the focus ancestry. 698 @return: C{True} if it should be presented in the focus ancestry, C{False} if not. 699 @rtype: bool 700 """ 701 if self.presentationType == self.presType_layout: 702 return False 703 if self.role in (controlTypes.ROLE_TREEVIEWITEM, controlTypes.ROLE_LISTITEM, controlTypes.ROLE_PROGRESSBAR, controlTypes.ROLE_EDITABLETEXT): 704 return False 705 return True
706
707 - def _get_statusBar(self):
708 """Finds the closest status bar in relation to this object. 709 @return: the found status bar else None 710 @rtype: L{NVDAObject} or None 711 """ 712 return None
713
714 - def reportFocus(self):
715 """Announces this object in a way suitable such that it gained focus. 716 """ 717 speech.speakObject(self,reason=speech.REASON_FOCUS)
718
719 - def event_typedCharacter(self,ch):
720 speech.speakTypedCharacters(ch) 721 import winUser 722 if config.conf["keyboard"]["beepForLowercaseWithCapslock"] and ch.islower() and winUser.getKeyState(winUser.VK_CAPITAL)&1: 723 import tones 724 tones.beep(3000,40)
725
726 - def event_mouseMove(self,x,y):
727 if not self._mouseEntered and config.conf['mouse']['reportObjectRoleOnMouseEnter']: 728 speech.cancelSpeech() 729 speech.speakObjectProperties(self,role=True) 730 speechWasCanceled=True 731 else: 732 speechWasCanceled=False 733 self._mouseEntered=True 734 try: 735 info=self.makeTextInfo(textInfos.Point(x,y)) 736 except NotImplementedError: 737 info=NVDAObjectTextInfo(self,textInfos.POSITION_FIRST) 738 except LookupError: 739 return 740 if config.conf["reviewCursor"]["followMouse"]: 741 api.setReviewPosition(info) 742 info.expand(info.unit_mouseChunk) 743 oldInfo=getattr(self,'_lastMouseTextInfoObject',None) 744 self._lastMouseTextInfoObject=info 745 if not oldInfo or info.__class__!=oldInfo.__class__ or info.compareEndPoints(oldInfo,"startToStart")!=0 or info.compareEndPoints(oldInfo,"endToEnd")!=0: 746 text=info.text 747 notBlank=False 748 if text: 749 for ch in text: 750 if not ch.isspace() and ch!=u'\ufffc': 751 notBlank=True 752 if notBlank: 753 if not speechWasCanceled: 754 speech.cancelSpeech() 755 speech.speakText(text)
756
757 - def event_stateChange(self):
758 if self is api.getFocusObject(): 759 speech.speakObjectProperties(self,states=True, reason=speech.REASON_CHANGE) 760 braille.handler.handleUpdate(self)
761
762 - def event_focusEntered(self):
768
769 - def event_gainFocus(self):
770 """ 771 This code is executed if a gain focus event is received by this object. 772 """ 773 self.reportFocus() 774 braille.handler.handleGainFocus(self)
775
776 - def event_foreground(self):
777 """Called when the foreground window changes. 778 This method should only perform tasks specific to the foreground window changing. 779 L{event_focusEntered} or L{event_gainFocus} will be called for this object, so this method should not speak/braille the object, etc. 780 """ 781 speech.cancelSpeech()
782
784 """Called when this object becomes the navigator object. 785 """ 786 braille.handler.handleReviewMove()
787
788 - def event_valueChange(self):
792
793 - def event_nameChange(self):
794 if self is api.getFocusObject(): 795 speech.speakObjectProperties(self, name=True, reason=speech.REASON_CHANGE) 796 braille.handler.handleUpdate(self)
797
798 - def event_descriptionChange(self):
802
803 - def event_caret(self):
804 if self is api.getFocusObject() and not eventHandler.isPendingEvents("gainFocus"): 805 braille.handler.handleCaretMove(self) 806 if config.conf["reviewCursor"]["followCaret"] and api.getNavigatorObject() is self: 807 try: 808 api.setReviewPosition(self.makeTextInfo(textInfos.POSITION_CARET)) 809 except (NotImplementedError, RuntimeError): 810 pass
811
812 - def _get_flatReviewPosition(self):
813 """Locates a TextInfo positioned at this object, in the closest flat review.""" 814 parent=self.simpleParent 815 while parent: 816 ti=parent.treeInterceptor 817 if ti and self in ti and ti.rootNVDAObject==parent: 818 return ti.makeTextInfo(self) 819 if issubclass(parent.TextInfo,DisplayModelTextInfo): 820 try: 821 return parent.makeTextInfo(api.getReviewPosition().pointAtStart) 822 except (NotImplementedError,LookupError): 823 pass 824 try: 825 return parent.makeTextInfo(self) 826 except (NotImplementedError,RuntimeError): 827 pass 828 return parent.makeTextInfo(textInfos.POSITION_FIRST) 829 parent=parent.simpleParent
830
831 - def _get_basicText(self):
832 newTime=time.time() 833 oldTime=getattr(self,'_basicTextTime',0) 834 if newTime-oldTime>0.5: 835 self._basicText=u" ".join([x for x in self.name, self.value, self.description if isinstance(x, basestring) and len(x) > 0 and not x.isspace()]) 836 if len(self._basicText)==0: 837 self._basicText=u"" 838 else: 839 self._basicTextTime=newTime 840 return self._basicText
841
842 - def makeTextInfo(self,position):
843 return self.TextInfo(self,position)
844
845 - def _get_devInfo(self):
846 """Information about this object useful to developers. 847 Subclasses may extend this, calling the superclass property first. 848 @return: A list of text strings providing information about this object useful to developers. 849 @rtype: list of str 850 """ 851 info = [] 852 try: 853 ret = repr(self.name) 854 except Exception as e: 855 ret = "exception: %s" % e 856 info.append("name: %s" % ret) 857 try: 858 ret = self.role 859 for name, const in controlTypes.__dict__.iteritems(): 860 if name.startswith("ROLE_") and ret == const: 861 ret = name 862 break 863 except Exception as e: 864 ret = "exception: %s" % e 865 info.append("role: %s" % ret) 866 try: 867 stateConsts = dict((const, name) for name, const in controlTypes.__dict__.iteritems() if name.startswith("STATE_")) 868 ret = ", ".join( 869 stateConsts.get(state) or str(state) 870 for state in self.states) 871 except Exception as e: 872 ret = "exception: %s" % e 873 info.append("states: %s" % ret) 874 try: 875 ret = repr(self) 876 except Exception as e: 877 ret = "exception: %s" % e 878 info.append("Python object: %s" % ret) 879 try: 880 ret = repr(self.__class__.__mro__) 881 except Exception as e: 882 ret = "exception: %s" % e 883 info.append("Python class mro: %s" % ret) 884 try: 885 ret = repr(self.description) 886 except Exception as e: 887 ret = "exception: %s" % e 888 info.append("description: %s" % ret) 889 try: 890 ret = repr(self.location) 891 except Exception as e: 892 ret = "exception: %s" % e 893 info.append("location: %s" % ret) 894 try: 895 ret = self.value 896 if isinstance(ret, basestring) and len(ret) > 100: 897 ret = "%r (truncated)" % ret[:100] 898 else: 899 ret = repr(ret) 900 except Exception as e: 901 ret = "exception: %s" % e 902 info.append("value: %s" % ret) 903 try: 904 ret = repr(self.appModule) 905 except Exception as e: 906 ret = "exception: %s" % e 907 info.append("appModule: %s" % ret) 908 try: 909 ret = repr(self.TextInfo) 910 except Exception as e: 911 ret = "exception: %s" % e 912 info.append("TextInfo: %s" % ret) 913 return info
914