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

Source Code for Module EvolutionScript

  1  # coding=utf-8 
  2  ''' 
  3  A customize script for the Evolution E-Mail client. 
  4   
  5  @author: Ramona Bunk 
  6  @organization: IT Science Center Ruegen gGmbH, Germany 
  7  @copyright: Copyright (c) 2007, 2008 ITSC Ruegen 
  8   
  9  @license: I{The BSD License} 
 10  All rights reserved. This program and the accompanying materials are made  
 11  available under the terms of the BSD which accompanies this distribution, and  
 12  is available at U{http://www.opensource.org/licenses/bsd-license.php} 
 13  ''' 
 14  # import useful modules for Scripts 
 15  from AccessEngine import AEScript, AccessEngineAPI 
 16  from AccessEngine import AEConstants 
 17  from AccessEngine.AEPor import AEPor 
 18  from Tools.i18n import bind, _ 
 19   
 20  import logging 
 21  log = logging.getLogger('EvolutionScript') 
 22   
 23  # metadata describing this Script 
 24  __uie__ = dict(kind='script', tier='evolution', all_tiers=False) 
 25   
26 -class EvolutionScriptState(AEScript.ScriptState):
27 ''' 28 Configuration of SUE for the Evolution application. 29 '''
30 - def init(self):
31 self.newBool('ReadMailHeader', 32 True, _('Read the mail header when the mail is opened?'), 33 _('When checked, SUE will automaticly read the header of the ' 34 'e-mail, when opened in a new window.')) 35 self.newBool('ReadMailBody', 36 True, _('Read the mail text when the mail is opened?'), 37 _('When checked, SUE will automaticly read the text of the ' 38 'e-mail, when opened in a new window.'))
39
40 - def getGroups(self):
41 groupReadMail = self.newGroup() 42 groupReadMail.append('ReadMailHeader') 43 groupReadMail.append('ReadMailBody') 44 return groupReadMail
45
46 -class EvolutionScript(AEScript.EventScript):
47 ''' 48 The customized script for the Evolution E-Mail client. 49 50 @ivar saRootPOR: the first common Ancestor for all sites in the evolution 51 setup assistant (accessible path: 0,0) 52 @type saRootPOR: L{AEPor} 53 @ivar saActiveChild: the active panel in the evolution setup assistant; a 54 direct child of saRootPOR 55 @type saActiveChild: L{AEPor} 56 @ivar htmlPanel: the HTML Container of the open mail 57 @type htmlPanel: L{AEPor} 58 @ivar lastQuotationLevel: the depth of quotation in an e-mail 59 @type lastQuotationLevel: integer 60 ''' 61 STATE = EvolutionScriptState
62 - def init(self):
63 '''Initialization of the EvolutionScript.''' 64 # class variables 65 self.saRootPOR = None 66 self.saActiveChild = None 67 self.htmlPanel = None 68 self.lastTreeTableItem = None 69 self.lastQuotationLevel = 0 70 self.lastPOR = None 71 72 # set an audio device as the default output 73 AccessEngineAPI.setScriptIdealOutput(self, 'audio') 74 75 # some events should be handled a little differently than in the 76 # BasicSpeechScript: 77 self.chainNewEventTaskAround('evolution view change', 78 'read view', 'BasicSpeechScript', 79 'onViewGained', 'onViewLost') 80 self.chainNewEventTaskAround('evolution focus change', 81 'read focus', 'BasicSpeechScript', 82 'onFocusGained') 83 self.chainNewEventTaskAround('evolution selector change', 84 'read selector', 'BasicSpeechScript', 85 'onSelectorActive') 86 self.chainNewEventTaskAround('evolution caret change', 87 'read caret', 'BasicSpeechScript', 88 'onCaretMoved') 89 90 # we want to react to some more events 91 self.registerEventTask('lost view', AEConstants.EVENT_TYPE_VIEW_CHANGE, 92 tier = True) 93 self.registerEventTask('read mail folder tree', 94 AEConstants.EVENT_TYPE_SELECTOR_CHANGE, tier = True) 95 self.registerEventTask('sa read next panel', \ 96 AEConstants.EVENT_TYPE_STATE_CHANGE, tier = True) 97 98 # replace the 'read item text' task for reading e-mails 99 self.registerTask('read email', self.readEMail) 100 self.chainTask('read email', AEConstants.CHAIN_AROUND, 101 'read item text', 'BasicSpeechScript') 102 103 self.registerTask('read label', self.onViewGained) 104 self.registerTask('number of mails', self.getNumberOfMails) 105 106 # get the Keyboard device and register modifiers and commands 107 kbd = AccessEngineAPI.getInputDevice(None, 'keyboard') 108 AccessEngineAPI.addInputModifiers(self, kbd, kbd.AEK_ALT_L, 109 kbd.AEK_SHIFT_L, kbd.AEK_ALT_R, 110 kbd.AEK_SHIFT_R, kbd.AEK_CAPS_LOCK) 111 pairs = [[kbd.AEK_ALT_L, kbd.AEK_SHIFT_L], [kbd.AEK_ALT_R, kbd.AEK_SHIFT_R]] 112 113 # commands for evolution 114 for pair in pairs: 115 self.registerCommand(kbd, 'read label', 116 _('read the label in the Setup Assistant'), 117 False, pair+[kbd.AEK_R])
118 # Todo: RB: tree adapter 119 #self.registerCommand(kbd, 'number of mails', 120 #_('gets the number of mails, that are currently shown'), 121 #False, pair+[kbd.AEK_N]) 122 123 124 ################### 125 ## Event Handler ## 126 ###################
127 - def _readNewTreeTableName(self, **kwargs):
128 ''' 129 Reads the name of the current tree table if it has changed. 130 ''' 131 text = AccessEngineAPI.getAccName(kwargs['por']) 132 if (self.lastPOR is None): 133 AccessEngineAPI.saySection(self, cap='audio', role='output', text=text, 134 **kwargs) 135 elif (not AccessEngineAPI.hasAccRole('tree table', self.lastPOR)): 136 AccessEngineAPI.saySection(self, cap='audio', role='output', text=text, 137 **kwargs) 138 else: 139 textLP = AccessEngineAPI.getAccName(self.lastPOR) 140 if (text != textLP): 141 AccessEngineAPI.saySection(self, cap='audio', role='output', text=text, 142 **kwargs) 143 144 self.lastPOR = kwargs['por'] 145 AccessEngineAPI.inhibitMayStop()
146
147 - def onViewGained(self, **kwargs):
148 ''' 149 Replaces the L{BasicSpeechScript} when Evolution gets a L{ViewChange} Event. 150 151 @return: C{True}; more tasks can execute for this event. 152 @rtype: boolean 153 ''' 154 por = kwargs['por'] 155 rv = True 156 157 # look whether we are in the Evolution Setup Assistant 158 if (self._isSetupAssistant(por)): 159 # make sure the por is set to the root accessible 160 por = AccessEngineAPI.getRootAcc(por) 161 # read the name of the accessible in the por 162 AccessEngineAPI.sayWindow(self, text=AccessEngineAPI.getAccName(por), 163 cap='audio', role='output', **kwargs) 164 165 # get the common Ancestor for all Setup Assistant Sites 166 if self.saRootPOR == None: 167 self.saRootPOR = AccessEngineAPI.getChildAcc(0, por) 168 # find the active panel and read its info labels 169 self._findSAActivePanel() 170 self._readSALabels(**kwargs) 171 172 else: 173 rv = self._doReplacedTask(**kwargs) 174 return rv
175
176 - def onViewLost(self, **kwargs):
177 ''' 178 Reset the evolution states. 179 ''' 180 self.saRootPOR = None 181 self.saActiveChild = None 182 self.htmlPanel = None 183 self.lastTreeTableItem = None 184 self.lastQuotationLevel = 0 185 #self.lastPOR = None 186 return self._doReplacedTask(**kwargs)
187
188 - def onFocusGained(self, **kwargs):
189 ''' 190 Replaces the L{BasicSpeechScript} when Evolution gets a L{FocusChange} Event. 191 192 @return: C{True}; more tasks can execute for this event. 193 @rtype: boolean 194 ''' 195 # return true, so that more tasks can execute for the current event 196 rv = True 197 198 # look whether we are in the Evolution Setup Assistant 199 if self._isSetupAssistant(kwargs['por']): 200 self.lastPOR = None 201 # try to stop older announcements 202 AccessEngineAPI.mayStop(self, cap='audio', role='output', **kwargs) 203 # announce the label when present if it is not the same as the name or the 204 # container 205 206 #workaround for a missing labeled by relation: 207 if not self.__workaroundSALabeledBy(**kwargs): 208 self.doTask('read new label', 'BasicSpeechScript', **kwargs) 209 # only announce role when it has changed 210 self.doTask('read new role', 'BasicSpeechScript', **kwargs) 211 # prevent the next selector or caret from stopping this announcement 212 AccessEngineAPI.inhibitMayStop() 213 214 # when we are in the e-mail list 215 elif (AccessEngineAPI.hasAccRole('table cell', kwargs['por'])): 216 AccessEngineAPI.mayStop(self, cap='audio', role='output', **kwargs) 217 parentPOR = AccessEngineAPI.getParentAcc(kwargs['por']) 218 if (AccessEngineAPI.hasAccRole('tree table', parentPOR)): 219 por = kwargs['por'] 220 kwargs['por'] = parentPOR 221 self._readNewTreeTableName(**kwargs) 222 kwargs['por'] = por 223 self._readTableRowFromMailList(**kwargs) 224 225 # when we have a window for mail reading open 226 elif (self._isMailWindow(**kwargs)): 227 if (AccessEngineAPI.hasAccRole('scroll pane', kwargs['por'])): 228 pass 229 elif (AccessEngineAPI.hasAccRole('unknown', kwargs['por'])): 230 if self.state.ReadMailHeader: 231 self.readMailHeader(**kwargs) 232 if self.state.ReadMailBody: 233 self.readMailBody(**kwargs) 234 235 # for every other case 236 else: 237 if (AccessEngineAPI.hasAccRole('tree table', kwargs['por'])): 238 self._readNewTreeTableName(**kwargs) 239 else: 240 self.lastPOR = None 241 rv = self._doReplacedTask(**kwargs) 242 return rv
243
244 - def onSelectorActive(self, **kwargs):
245 ''' 246 Replaces the L{BasicSpeechScript} when Evolution gets a L{SelectorChange} 247 Event. 248 249 @return: C{True}; more tasks can execute for this event. 250 @rtype: boolean 251 ''' 252 rv = True 253 254 # do Task 'evolution selector change' 255 if kwargs['task_name'] == 'evolution selector change': 256 257 # look whether we are in the e-mail list: 258 if (AccessEngineAPI.hasAccRole('table cell', kwargs['por'])): 259 pass # do nothing 260 261 # when we have a window for mail reading open 262 elif (self._isMailWindow(**kwargs)): 263 if (AccessEngineAPI.hasAccRole('scroll pane', kwargs['por']) or 264 (AccessEngineAPI.hasAccRole('unknown', kwargs['por']))): 265 pass 266 else: 267 rv = self._doReplacedTask(**kwargs) 268 269 # read e-mail content 270 elif (AccessEngineAPI.hasAccRole('text', kwargs['por'])): 271 kwargs['text'] = AccessEngineAPI.getAccText(kwargs['por']) 272 self.readEMail(**kwargs) 273 274 else: 275 # look whether we are in the mail folder tree and whether the current 276 # item is different from the previous one. 277 if (AccessEngineAPI.hasAccRole('tree table', kwargs['por'])): 278 if self.lastTreeTableItem == kwargs['text']: 279 return False 280 self.lastTreeTableItem = kwargs ['text'] 281 rv = self._doReplacedTask(**kwargs) 282 283 # do Task 'evolution tree table' 284 elif kwargs['task_name'] == 'read mail folder tree': 285 286 # look whether we are in the mail folder tree and whether the current 287 # item is different from the previous one. 288 if (AccessEngineAPI.hasAccRole('tree table', kwargs['por'])): 289 if self.lastTreeTableItem == kwargs['text']: 290 return False 291 self.lastTreeTableItem = kwargs ['text'] 292 # TODO: ?? 293 self.unchainTask('evolution selector change', AEConstants.CHAIN_AROUND, 294 'read selector', 'BasicSpeechScript') 295 rv = self.doTask('read selector', 'BasicSpeechScript', **kwargs) 296 self.chainTask('evolution selector change', AEConstants.CHAIN_AROUND, 297 'read selector', 'BasicSpeechScript') 298 299 return rv
300
301 - def onStateChange(self, **kwargs):
302 ''' 303 React to a L{StateChange} event in Evolution. 304 305 We are interested in state changes in the Evolution Setup Assistant, where 306 the state will be set to 'showing'. This should indicate that a new panel in 307 the dialog was activated. 308 309 @return: C{True}; more tasks can execute for this event. 310 @rtype: boolean 311 ''' 312 # we only want panels which get the state 'showing' and are a child of the 313 # evolution setup assistant 314 if (kwargs['name'] == 'showing' and kwargs['value'] == 1 \ 315 and self.saRootPOR == AccessEngineAPI.getParentAcc(kwargs['por'])): 316 317 #AccessEngineAPI.sayInfo(self, text='showing', cap='audio', role='output', **kwargs) 318 319 # look whether the StateChange event is for the active panel 320 # and whether the active panel has changed 321 oldActivePanel = self.saActiveChild 322 self._findSAActivePanel() 323 if (self.saActiveChild == kwargs['por'] and \ 324 self.saActiveChild is not oldActivePanel): 325 self._readSALabels(**kwargs) 326 327 return True
328
329 - def onCaretMoved(self, **kwargs):
330 ''' 331 Don't execute the caret move, when in the list with the e-mails. 332 ''' 333 if (AccessEngineAPI.hasAccRole('table cell', kwargs['por'])): 334 return False 335 else: 336 return self._doReplacedTask(**kwargs)
337 338 ##################### 339 ## Setup Assistant ## 340 #####################
341 - def _isSetupAssistant(self, por):
342 ''' 343 Test whether the given por is an element in the Evolution Setup Assistant 344 345 @param por: The L{AEPor} that should be in the Evolution Setup Assistant 346 @type por: L{AEPor} 347 348 @return: whether the por is in the Evolution Setup Assitant 349 @rtype: boolean 350 ''' 351 if not por: return False 352 353 rootPor = AccessEngineAPI.getRootAcc(por) 354 if self.saRootPOR: 355 return (self.saRootPOR == AccessEngineAPI.getChildAcc(0, rootPor)) 356 else: 357 rootPor = AccessEngineAPI.getChildAcc(0, por) 358 if not rootPor: return False 359 360 # First look at the child count of the first common Ancestor for all sites 361 # in the Evolution Setup Assitant. 362 # The panel should have at least 10 children accessibles 363 childCount = AccessEngineAPI.getAccCount(rootPor) 364 365 if (childCount < 10): return False 366 367 # Next look at the last child of the panel. This should be a filler with 368 # 5 children. Each child should be a push button. 369 else: 370 lastChild = AccessEngineAPI.getChildAcc(childCount-1, rootPor) 371 lastChildCount = AccessEngineAPI.getAccCount(lastChild) 372 if (AccessEngineAPI.hasAccRole('filler', lastChild) and \ 373 lastChildCount == 5): 374 for index in range(lastChildCount): 375 child = AccessEngineAPI.getChildAcc(index, lastChild) 376 if (not AccessEngineAPI.hasAccRole('push button', child)): 377 return False 378 else: 379 return False 380 381 # Try the first child next. 382 # This should be a panel which contains the following children: 383 # an icon at path (0,0,1) 384 # an label at path (0,0,2) 385 # an icon at path (0,0,3) 386 # an label at path (0,0,0,1,0) 387 firstChild = AccessEngineAPI.getChildAcc(0, rootPor) 388 if not (AccessEngineAPI.hasAccRole('icon', \ 389 AccessEngineAPI.getAccFromPath(firstChild, 0,0,1)) \ 390 and \ 391 AccessEngineAPI.hasAccRole('label', 392 AccessEngineAPI.getAccFromPath(firstChild, 0,0,2)) \ 393 and \ 394 AccessEngineAPI.hasAccRole('icon', 395 AccessEngineAPI.getAccFromPath(firstChild, 0,0,3)) \ 396 and \ 397 AccessEngineAPI.hasAccRole('label', 398 AccessEngineAPI.getAccFromPath(firstChild, 0,0,0,1,0))): 399 return False 400 401 return True
402
403 - def _findSAActivePanel(self):
404 ''' 405 Find the active panel in the Evolution Setup Assistant. 406 407 The active panel has the state 'showing' and is a dircet child of the 408 L{saRootPOR} instance variable. Sets the L{saActiveChild} 409 instance variable. 410 ''' 411 found = False 412 index = 0 413 if self.saRootPOR: 414 childCount = AccessEngineAPI.getAccCount(self.saRootPOR) - 1 415 416 while not found and index < childCount: 417 childPor = AccessEngineAPI.getChildAcc(index, self.saRootPOR) 418 if AccessEngineAPI.hasAccState('showing', childPor): 419 self.saActiveChild = childPor 420 found = True 421 else: 422 index = index + 1 423 if index == childCount: self.saActiveChild = None
424
425 - def _getLabel(self, rootPor, *path):
426 ''' 427 Checks whether the L{AEPor} at the given path is a label. 428 429 @return: The AEPor if it is a label; C{False} otherwise. 430 @rtype: L{AEPor} or C{None} 431 ''' 432 labelPor = AccessEngineAPI.getAccFromPath(rootPor, *path) 433 if labelPor: 434 role = AccessEngineAPI.getAccRole(labelPor) 435 if role == 'label': 436 return labelPor 437 else: 438 return None 439 else: 440 return None
441
442 - def _readSALabels(self, **kwargs):
443 ''' 444 Read the header label and the description label of the active panel in the 445 Evolution Setup Assitant. 446 ''' 447 # get the index of the open panel 448 panelIndex = AccessEngineAPI.getAccIndex(self.saActiveChild) 449 450 # look for the headline of the open panel 451 label1Por = self._getLabel(self.saRootPOR, panelIndex,0,0,2) 452 453 # look for a second label that gives information about the purpose of the 454 # open panel 455 label2Por = None 456 label2Por = self._getLabel(self.saRootPOR, panelIndex,0,0,0,1,0) 457 if not label2Por: 458 label2Por = self._getLabel(self.saRootPOR, panelIndex,0,0,0,0,0) 459 if not label2Por: 460 label2Por = self._getLabel(self.saRootPOR, panelIndex,0,0,0,0,0,0,0) 461 462 # read the labels of the current panel to give the user needed informations 463 AccessEngineAPI.inhibitMayStop() 464 if label1Por: 465 AccessEngineAPI.sayInfo(self, text=AccessEngineAPI.getAccName(label1Por), 466 cap='audio', role='output', **kwargs) 467 if label2Por: 468 AccessEngineAPI.sayInfo(self, text=AccessEngineAPI.getAccName(label2Por), 469 cap='audio', role='output', **kwargs)
470 471
472 - def __workaroundSALabeledBy(self, **kwargs):
473 self._findSAActivePanel() 474 panelIndex = AccessEngineAPI.getAccIndex(self.saActiveChild) 475 headerPor = self._getLabel(self.saRootPOR, panelIndex,0,0,2) 476 if headerPor: 477 text = AccessEngineAPI.getAccName(headerPor) 478 # todo: translation 479 if text == _("Aus Sicherungsdatei wiederherstellen"): 480 if AccessEngineAPI.hasAccRole('push button', kwargs['por']): 481 text = AccessEngineAPI.getAccName(kwargs['por']) 482 if (not (text == _("Vor") or 483 text == _("Zurück") or 484 text == _("Abbrechen") or 485 text == _("Anwenden") or 486 text == _("Hilfe") 487 )): 488 text = AccessEngineAPI.getAccName( 489 AccessEngineAPI.getAccFromPath(self.saRootPOR, 490 panelIndex,0,0,0,0,0,2,0)) 491 AccessEngineAPI.sayLabel(self, cap='audio', role='output', 492 text=text, **kwargs) 493 return True 494 return False
495 496 ############### 497 ## Mail-View ## 498 ###############
499 - def getNumberOfMails(self):
500 ''' 501 Finds out, how many mails are shown in the message tree. 502 503 @Todo: RB: must still be implemented 504 ''' 505 pass
506
507 - def _readTableCellFromMailList(self, columnHeader, cellPOR, **kwargs):
508 ''' 509 Read one cell of the table tree that contains the list of E-Mails. 510 511 @param columnHeader: the name of the column that contains the table cell 512 @type columnHeader: string 513 @param cellPOR: the table cell that shall be read 514 @type cellPOR: L{AEPor} 515 @param kwargs: Arbitrary keyword arguments to pass to the task 516 @type kwargs: dictionary 517 ''' 518 # the text that shall be read 519 text = None 520 521 # if the cell is in the "Status" column tell the read or unread status of 522 # the mail 523 # translator: needs the exact name of the "Status" column 524 if (columnHeader == _("Status")): 525 if (AccessEngineAPI.hasAccState('checked', cellPOR)): 526 text = _("read") 527 else: 528 text = _("unread") 529 530 # if the cell has a "toggle" action: read the name of the column, when the 531 # state is checked 532 # translator: needs the exact name of the action 533 elif (AccessEngineAPI.hasAccActionName(_("toggle"), cellPOR)): 534 if (AccessEngineAPI.hasAccState('checked', cellPOR)): 535 text = columnHeader 536 537 # for all other cells read the name of the column and the content of the 538 # cell 539 else: 540 text = columnHeader + " " + AccessEngineAPI.getAccName(cellPOR) 541 542 if text: 543 AccessEngineAPI.sayInfo(self, text=text, cap='audio', role='output', 544 **kwargs)
545
546 - def _readTableRowFromMailList(self, **kwargs):
547 ''' 548 Read the current row of the table tree that contains the list of E-Mails. 549 ''' 550 AccessEngineAPI.mayStop(self, cap='audio', role='output', **kwargs) 551 552 por = kwargs['por'] 553 parentPOR = AccessEngineAPI.getParentAcc(por) 554 childCount = AccessEngineAPI.getAccCount(parentPOR) 555 556 # get the numbers of columns in the tree table 557 numColumns = 0 558 tableColumnHeader = True 559 # and get all table column headers 560 headers = [] 561 while tableColumnHeader: 562 childPOR = AccessEngineAPI.getChildAcc(numColumns, parentPOR) 563 if (AccessEngineAPI.hasAccRole('table column header', childPOR)): 564 headers.append(AccessEngineAPI.getAccName(childPOR)) 565 numColumns = numColumns+1 566 else: 567 tableColumnHeader = False 568 569 # get all table cells from the current row 570 currentCellIndex = AccessEngineAPI.getAccIndex(por) 571 # get the index intervall for the cells in the current row 572 start = (currentCellIndex/numColumns)*numColumns 573 end = start + numColumns - 1 574 cellIndex = start 575 while cellIndex <= end: 576 cell = AccessEngineAPI.getChildAcc(cellIndex, parentPOR) 577 self._readTableCellFromMailList(headers[cellIndex-start], cell, **kwargs) 578 cellIndex = cellIndex+1
579 580 ###################### 581 ## Mail Folder Tree ## 582 ###################### 583 584 ################# 585 ## Read E-Mail ## 586 #################
587 - def _isMailWindow(self, **kwargs):
588 ''' 589 Test whether we are in a window that shows the contents of one mail. 590 ''' 591 rootPor = AccessEngineAPI.getRootAcc(kwargs['por']) 592 scrollPanePor = AccessEngineAPI.getAccFromPath(rootPor, 0,0,2,0) 593 if (AccessEngineAPI.hasAccRole('scroll pane', scrollPanePor)): 594 panelPor = AccessEngineAPI.getAccFromPath(scrollPanePor, 0) 595 if (AccessEngineAPI.getAccName(panelPor) == _('Panel containing HTML')): 596 self.htmlPanel = panelPor 597 return True 598 else: 599 return False 600 else: 601 return False
602
603 - def readMailHeader(self, **kwargs):
604 ''' 605 Reads the header of an e-mail. 606 ''' 607 if self.htmlPanel: 608 AccessEngineAPI.sayInfo(self, cap='audio', role='output', 609 text=_('Mail Header: '), **kwargs) 610 self._readAllText(AccessEngineAPI.getAccFromPath(self.htmlPanel, 0), 611 **kwargs)
612
613 - def readMailBody(self, **kwargs):
614 ''' 615 Reads the text of the whole e-mail. 616 ''' 617 if self.htmlPanel: 618 AccessEngineAPI.sayInfo(self, cap='audio', role='output', 619 text=_('Mail Text: '), **kwargs) 620 for c in range(AccessEngineAPI.getAccCount(self.htmlPanel)): 621 child = AccessEngineAPI.getChildAcc(c, self.htmlPanel) 622 if (AccessEngineAPI.hasAccRole('unknown', child)): 623 self._readAllText(child, **kwargs) 624 break
625
626 - def _readAllText(self, ePor, **kwargs):
627 ''' 628 Reads all text accessibles under the given por. 629 630 This method works recursivly. 631 632 @param ePor: the por which is used to find text accessibles. 633 @type ePor: L{AEPor} 634 ''' 635 childCount = AccessEngineAPI.getAccCount(ePor) 636 if (childCount > 0): 637 for c in range(childCount): 638 self._readAllText(AccessEngineAPI.getChildAcc(c, ePor), **kwargs) 639 elif (AccessEngineAPI.hasAccRole('text', ePor)): 640 #AccessEngineAPI.sayItem(self, cap='audio', role='output', 641 #text=AccessEngineAPI.getAccText(ePor), **kwargs) 642 kwargs['text'] = AccessEngineAPI.getAccText(ePor) 643 #if (kwargs['text'] != ""): 644 # todo: nutzereinstellung, ob leerzeilen als leer angesagt oder nicht 645 AccessEngineAPI.inhibitMayStop() 646 self.readEMail(**kwargs)
647
648 - def _quote(self, text, **kwargs):
649 ''' 650 Reads quotation in an e-mail. 651 ''' 652 # count quotation marks 653 numMarks = 0 654 for s in text.split('>'): 655 s = s.strip() 656 if s == '': 657 numMarks = numMarks + 1 658 else: 659 break 660 if (numMarks == len(text.split('>'))): numMarks = numMarks - 1 661 662 AccessEngineAPI.mayStop(self, cap='audio', role='output', **kwargs) 663 if (self.lastQuotationLevel is not numMarks): 664 level = _('Quotation Level') 665 level = '%s: %d ' % (level, numMarks) 666 self.lastQuotationLevel = numMarks 667 AccessEngineAPI.sayLevel(self, cap='audio', role='output', text=level, **kwargs) 668 AccessEngineAPI.sayLevel(self, cap='audio', role='output', text=text, **kwargs)
669
670 - def readEMail(self, **kwargs):
671 ''' 672 Read a row in a mail. 673 ''' 674 mainPOR = AccessEngineAPI.findAccByName(_('Panel containing HTML'), kwargs['por'], 675 ancestor = True) 676 if mainPOR: 677 try: 678 if (kwargs['text'].startswith('>')): 679 self._quote(**kwargs) 680 else: 681 AccessEngineAPI.sayItem(self, cap='audio', role='output', **kwargs) 682 except KeyError: 683 text = AccessEngineAPI.getItemText(kwargs['por']) 684 label = AccessEngineAPI.getAccLabel(kwargs['por']) 685 if (label != text): 686 if (text.startswith('>')): 687 self._quote(text, **kwargs) 688 else: 689 self.lastQuotationLevel = 0 690 AccessEngineAPI.mayStop(self, cap='audio', role='output', **kwargs) 691 AccessEngineAPI.sayItem(self, text=text, cap='audio', role='output', **kwargs) 692 else: 693 try: 694 if (kwargs['text'].startswith('>')): 695 self._quote(**kwargs) 696 else: 697 AccessEngineAPI.sayItem(self, cap='audio', role='output', **kwargs) 698 except KeyError: 699 self.unchainTask('read email', AEConstants.CHAIN_AROUND, 700 'read item text', 'BasicSpeechScript') 701 self.doTask('read item text', 'BasicSpeechScript', **kwargs) 702 self.chainTask('read email', AEConstants.CHAIN_AROUND, 703 'read item text', 'BasicSpeechScript')
704 705 ################### 706 ## Calendar-View ## 707 ################### 708