| Trees | Indices | Help |
|
|---|
|
|
1 '''
2 Defines a user interface for pidgin.
3
4 Keys registered
5
6 CapsLock-W: Reports status of all open conversations
7 CapsLock-S: Cycle focus between message history and compose area
8
9 Event announcements
10
11 (X) means optional announcement X based on type of widget
12 [X] means X always announced
13 <X> indicates continue announcements in X
14
15 on activate: ["chat with" username]
16 on focus: ["compose" or "history"] <active descendant change>
17 on message received: [text of message]
18
19 @var CONTAINER_PATH: path from frame to container with accessible elements
20 @type CONTAINER_PATH: integer
21 @var NUM_CHILDREN_IN_CHAT_WINDOW: to identify a chat window: assume that only
22 this acc will have 2 kids, and further assume that accessibles with similar
23 hierarchical placement will not.
24 @type NUM_CHILDREN_IN_CHAT_WINDOW: integer
25 @var MENU_BAR_PATH: path: from container to menu bar
26 @type MENU_BAR_PATH: integer
27 @var TAB_PATH: path from container to page tab list (contains conversations)
28 @type TAB_PATH: integer
29 @var HISTORY_PATH: path from a conversation tab to its history text panel
30 @type HISTORY_PATH: integer
31 @var COMPOSE_PATH: path from a conversation tab to its compose text panel
32 @type COMPOSE_PATH: integer
33 @var UNREAD_STATUS: Constant representing a conversation has an unread
34 message
35 @type UNREAD_STATUS: integer
36 @var TYPING_STATUS: Constant representing a chat partner is currently typing
37 in a conversation
38 @type TYPING_STATUS: integer
39 @var PAUSED_STATUS: Constant representing a chat partner is stoped typing
40 in a conversation
41 @type PAUSED_STATUS: integer
42 @var IDLE_STATUS: Constant representing a chat partner is idle in a
43 conversation
44 @type IDLE_STATUS: integer
45 @var OFFLINE_STATUS: Constant representing a chat partner is offline in a
46 conversation
47 @type OFFLINE_STATUS: integer
48 @var RED: Gtk color description of color red, as string
49 @type RED: string
50 @var GREEN: Gtk color description of color green, as string
51 @type GREEN: string
52 @var YELLOW: Gtk color description of color yellow, as string
53 @type YELLOW: string
54 @var LOGOUT_GREY: Gtk color description of grey, as string, used in logoff
55 @type LOGOUT_GREY: string
56 @var STATUS_MSG: List of strings describing the unread, typing, etc. status
57 of conversations sorted by their likely importance to the user
58 @type STATUS_MSG: list of string
59
60 @author: Brett Clippingdale
61 @author: Peter Parente
62 @organization: IBM Corporation
63 @copyright: Copyright (c) 2005, 2007 IBM Corporation
64 @license: The BSD License
65
66 All rights reserved. This program and the accompanying materials are made
67 available under the terms of the BSD license which accompanies
68 this distribution, and is available at
69 U{http://www.opensource.org/licenses/bsd-license.php}
70 '''
71 from AccessEngine import AEConstants
72 from AccessEngine import AEState, AEScript, AccessEngineAPI
73 from AccessEngine.AEPor import AEPor
74 from Tools.i18n import _
75
76 __uie__ = dict(kind='script', tier='pidgin')
77
78 # actual paths, derived using at-poke, assumed to be static. YMMV.
79 # path: from frame to container with accessible elements
80 CONTAINER_PATH = 0
81 # to identify a chat window: assume that only this acc will have 2 kids, and
82 # further assume that accessibles with similar hierarchical placement will
83 # not. Again, YMMV, so analyze carefully with AT-Poke and then verify.
84 NUM_CHILDREN_IN_CHAT_WINDOW = 2
85 # path: from container to page tab list (contains all conversations)
86 TAB_PATH = 1
87
88 # actual paths in Pidgin 1.5, derived using at-poke, assumed to be static
89 # if Pidgin 2, these will get different values in setPidginEnviron()
90 HISTORY_PATH = (0,0,0,0,0) # path: tab (a conversation) to history text panel
91 COMPOSE_PATH = (0,0,1,1,0,0,0) # path: tab to chat compose text panel
92
93 # pidgin colors, (eg. convo tab text color depends on typing/login status)
94 RED = "57311,16962,7710" # unread msg
95 GREEN = "18247,41120,17990" # active typing
96 YELLOW = "53713,38036,3084" # paused typing
97 GREY = "34438,33410,29298" # off-line
98 LOGOUT_GREY = "32639, 32639, 32639" # used in buddy list on logoff
99 # constants for status of conversations
100 UNREAD_STATUS = 0
101 TYPING_STATUS = 1
102 PAUSED_STATUS = 2
103 IDLE_STATUS = 3
104 OFFLINE_STATUS = 4
105 LOGIN_STATUS = 5
106 LOGOUT_STATUS = 6
107 STATUS_MSG = [_('unseen'), _('typing'), _('paused'), _('idle'), _('offline'),
108 _('logged in'), _('logged out')]
109
111 '''
112 Settings for Pidgin.
113
114 ReadBackground (bool): Read incoming messages when pidgin is in the background?
115 '''
117 self.newBool('ReadBackground', False, _('Read background messages?'),
118 _('When checked, incoming messages will be read even when '
119 'Pidgin is in the background.'))
120 self.newBool('BrailleBackground', False, _('Braille background messages?'),
121 _('When checked, incoming messages will be output to Braille '
122 'device even when Pidgin is in the background.'))
123
129
131 '''
132 Provides hotkeys for switching between the message history and message
133 compose areas. Announces incoming messages and allows for review by entire
134 message.
135
136 Has initial support for announcing when buddies sign in and out and when the
137 status of a conversation changes. Written to work with both pidgin 1.5 and 2.0.
138
139 @ivar chat_compose_por: Reference to chat msg compose panel
140 @type chat_compose_por: L{AEPor}
141 @ivar chat_history_por: Reference to chat history panel
142 @type chat_history_por: L{AEPor}
143 @ivar last_convo: Reference to the last selected conversation tab
144 @type last_convo: L{AEPor}
145 @ivar initialized: have pidgin environment variables been initialized?
146 @type initialized: boolean
147 @ivar is_pidgin2: is user client Pidgin2 ?
148 @type is_pidgin2: boolean
149 @ivar is_history_focused: does chat history panel currently have focus?
150 @type is_history_focused: boolean
151 @ivar last_history_caret: track caret in history panel, read when on new line
152 @type last_history_caret: L{AEPor}
153 '''
154 STATE = PidginScriptState
155
157 '''
158 Registers keyboard bindings that give status of conversation tabs (unread
159 message, active typing, paused typing) and drive focus back and forth
160 between chat composition text area and history text area.
161 '''
162
163 # set an audio device as the default output
164 AccessEngineAPI.setScriptIdealOutput('audio')
165
166 ## register event handlers
167 ## events here are app-level, other Scripts will handle gnome-level events,
168 ## so only register events of interest here.
169 #AccessEngineAPI.registerTask(ActivatePidginWindow('pidgin read window'))
170 #AccessEngineAPI.registerTask(HandleFocusChange('pidgin read focus'))
171 #AccessEngineAPI.registerTask(HandleSelectorChange('pidgin read selector'))
172 #AccessEngineAPI.registerTask(HandleCaretChange('pidgin read caret'))
173 #AccessEngineAPI.registerTask(ReadIncoming('pidgin read incoming', all=True))
174 ## not working for background events ???
175 ##self.registerEventTask(HandlePropertyChange(focus=True, tier=True,
176 ## background=True))
177 ## @note: not handling TableChange until certain Pidgin bugs fixed
178 ## if re-enabled, may want to uncomment debug code: last_por_inserted (global
179 ## variable) and code in handleCaretChange
180 ##self.registerEventTask(BuddySignOnOff(focus=True, tier=True,
181 ##background=True))
182
183 ## register named tasks. Specify the task class name (see below) and a
184 ## description. These descriptions are dictionary keys and therefore
185 ## must be unique. Here, Pidgin is a prefix to help ensure uniqueness.
186 #AccessEngineAPI.registerTask(ToggleChatPanel('pidgin chat panel toggle'))
187 #AccessEngineAPI.registerTask(ConversationStatus('pidgin conversation status'))
188
189 ## get the Keyboard device and register modifiers.
190 #kbd = AccessEngineAPI.getInputDevice(None, 'keyboard')
191 #AccessEngineAPI.addInputModifiers(self, kbd, kbd.AEK_CAPS_LOCK)
192
193 ## register the keys and their associated commands, binding them using the
194 ## unique dictionary key we registered above.
195 ## Pass 3 element tuple. Need to capture keys as pressed though we only
196 ## handle them if all both modifiers pressed before the non-modifier.
197 #AccessEngineAPI.registerCommand(kbd, 'pidgin chat panel toggle', False,
198 #[kbd.AEK_CAPS_LOCK, kbd.AEK_S])
199 #AccessEngineAPI.registerCommand(kbd, 'pidgin conversation status', False,
200 #[kbd.AEK_CAPS_LOCK, kbd.AEK_W])
201
202 ## POR reference to chat composition text area
203 #self.chat_compose_por = AEPor()
204 ## POR reference to chat history text area
205 #self.chat_history_por = AEPor()
206 #self.last_convo = AEPor()
207
208 ## have pidgin environment variables been initialized? This must happen first
209 ## time that pidgin chat window is activated
210 #self.initialized = False
211 ## is user client Pidgin 2.0 instead of 1.5?
212 #self.is_pidgin2 = False
213
214 ## does chat history panel currently have focus
215 #self.is_history_focused = False
216 #self.last_history_caret = AEPor()
217
218 ## is there selection in the composition area? used to avoid announcing
219 ## deleted text when sending
220 #self.selection = False
221
222 ## may be used in case where, on sign-off, multiple inserts fire
223 ##debug, see handleRowInserted, handleCaretChange
224 ##last_row_inserted_por = None
225
226 #def getActivePageTabListPOR(self):
227 #'''
228 #Gets a Point of Regard to the page tab list in an active chat window.
229
230 #@return: Point of Regard to the page tab list in an active chat window,
231 #or None otherwise
232 #@rtype: L{AEPor}
233 #'''
234 #frame_por = AccessEngineAPI.getRootAcc()
235 #container_por = AccessEngineAPI.getAccFromPath(frame_por, CONTAINER_PATH)
236 ## is chat window active?
237 #if (AccessEngineAPI.hasAccState('active', frame_por) and
238 #AccessEngineAPI.getAccCount(container_por) == NUM_CHILDREN_IN_CHAT_WINDOW):
239 ## get 'page tab list'
240 #tab_list_por = AccessEngineAPI.getAccFromPath(container_por, TAB_PATH)
241 #if AccessEngineAPI.hasAccRole("page tab list", tab_list_por):
242 #return tab_list_por
243 ## in all other cases, return None
244 #return None
245
246 #def getTypingStatus(self, por):
247 #'''
248 #Gets current typing status on a given conversation L{AEPor}.
249
250 #@return: One of L{UNREAD_STATUS}, L{TYPING_STATUS}, L{PAUSED_STATUS},
251 #L{IDLE_STATUS} that can be mapped to a message in L{STATUS_MSG}
252 #@rtype: integer
253 #'''
254 #value = self.getAccTextAttr("fg-color", por)
255 ## red: message typed, unread
256 #if value == RED:
257 #return UNREAD_STATUS
258 ## green: typing
259 #elif value == GREEN:
260 #return TYPING_STATUS
261 ## yellow: paused
262 #elif value == YELLOW:
263 #return PAUSED_STATUS
264 ## grey: offline
265 #elif value == GREY:
266 #return OFFLINE_STATUS
267 ## black: (no typing), and no fg-color value
268 #else:
269 #return IDLE_STATUS
270
271 #def setPidginVersion(self):
272 #'''
273 #Applies a heuristic to determine which Pidgin version is running locally.
274 #This is important because the the representation of the UI varies by local
275 #client, and in the case of a local Pidgin 2 it also varies by remote client.
276 #'''
277 #tab_list_por = self.getActivePageTabListPOR()
278 ## get selected conversation tab
279 #selected_tab_por = AccessEngineAPI.getFirstSelected(tab_list_por)
280 #self.chat_history_por = \
281 #AccessEngineAPI.getAccFromPath(selected_tab_por, *HISTORY_PATH)
282 ## if this is a "filler" rather than a text area, must be Pidgin2
283 #if AccessEngineAPI.getAccRoleName(self.chat_history_por) == "filler":
284 #self.is_pidgin2 = True
285 #print "chat client is Pidgin beta 2 or higher"
286 #else:
287 #print "chat client is Pidgin 1.5 or lower"
288
290 '''
291 @return: Human readable name of this L{AEScript <AEScript.AEScript>}.
292 @rtype: string
293 '''
294 return _('Pidgin')
295
296 ##
297 ## Tasks executed by keys
298 ##
299
300 #class ToggleChatPanel(Task.InputTask):
301 #'''
302 #Toggles focus between chat composition and chat history panels.
303 #'''
304 ## each task class must implement an execute method which is called when
305 ## the associated key bindings (registered in init method, above) are pressed
306 #def execute(self, **kwargs):
307 ## determine which chat panel currently has focus. Specify which
308 ## ATSPI-defined property of interest (here, 'focused') and the POR to check
309 ## for that property
310 #tab_list_por = self.script.getActivePageTabListPOR()
311 #if tab_list_por is not None:
312 #if not self.script.is_history_focused:
313 ##change focus to chat history panel
314 #self.setAccFocus(self.script.chat_history_por)
315 #else:
316 ##change focus to chat compose panel
317 #self.setAccFocus(self.script.chat_compose_por)
318 #return True # allow triggering keystrokes to propagate (default)
319
320 #class ConversationStatus(Task.InputTask):
321 #'''
322 #Announces the status of the current conversations. Status for conversations
323 #is grouped by status type except for the foreground conversation which is
324 #always reported first.
325 #'''
326 #def execute(self, **kwargs):
327 #brailleout=[]
328 #tab_list_por = self.script.getActivePageTabListPOR()
329 ## is chat window active? otherwise, don't switch
330 #if tab_list_por is None:
331 #return True
332
333 ## stop prior speech
334 #self.stopNow()
335
336 ## get selected conversation tab
337 #selected_tab_por = self.getFirstSelected(tab_list_por)
338
339 #por = self.getFirstPeerAcc(selected_tab_por)
340 #l = []
341 #while por is not None:
342 ## get the tab name and status value
343 #name = self.getAccName(por)
344 ## if acc not an artifact, process
345 #if name != '':
346 #value = self.script.getTypingStatus(por)
347 #print selected_tab_por
348 #if selected_tab_por == por:
349 #self.sayState(text=(name, STATUS_MSG[value]), template='%s %s,')
350 #brailleout.append('%s: %s, ' % (name, STATUS_MSG[value]))
351 #else:
352 #l.append((value, name))
353 #por = self.getNextPeerAcc(por)
354
355 ## sort the list of status values and names by priority, highest first)
356 #l.sort()
357
358 #last = -1
359 #for value, name in l:
360 #if last != value:
361 #last = value
362 #self.sayState(text=STATUS_MSG[value], template='%s,')
363 #brailleout.append('%s: ' % (STATUS_MSG[value]))
364 #self.sayState(text=name, template='%s,')
365 #brailleout.append('%s, ' % (name))
366 ## output to Braille device
367 #self.doTask('braille text', text=''.join(brailleout))
368
369 ##
370 ## Tasks executed by events
371 ##
372
373 #class ActivatePidginWindow(Task.ViewTask):
374 #'''
375 #Task that handles a L{AEEvent.ViewChange}.
376 #'''
377 #def executeGained(self, por, title, **kwargs):
378 #'''
379 #Prevents the window title from being announced if it is the chat window,
380 #since better information is given for the chat window on the subsequent
381 #focus change event. Accomplished by stopping propagation of the event.
382
383 #@param por: Point of regard to the root of the new view
384 #@type por: L{AEPor}
385 #@param title: Title of the newly activated window
386 #@type title: string
387 #'''
388 #self.script.last_convo = AEPor()
389 #tab_list_por = self.script.getActivePageTabListPOR()
390 #print 'GAIM:', tab_list_por
391 ## test to see if not a chat window
392 #if tab_list_por is None:
393 #return True # allow other Scripts to handle the view change
394 ## must be a chat window
395 #else:
396 #if not self.script.initialized:
397 #self.script.setPidginVersion()
398 #self.script.initialized = True
399 ## don't allow the view change event to propagate
400 #return False
401
402 #class HandleFocusChange(Task.FocusTask):
403 #'''
404 #Task that handles a L{AEEvent.FocusChange}.
405 #'''
406 #GAIM2_HISTORY_PATH = (0,0,0,0,0,0,0) #history text panel
407 #GAIM2_COMPOSE_PATH = (0,0,1,0,0,0,0,2,0) # compose text panel - pidgin2 remote
408 #GAIM2_ALT_COMPOSE_PATH = (0,0,1,0,1,0,0,2,0) # compose text panel - pidgin1.5
409
410 #def executeGained(self, por, **kwargs):
411 ## get 'page tab list'
412 #tab_list_por = self.script.getActivePageTabListPOR()
413 #if tab_list_por is None:
414 ## let the event propagate
415 #return True
416
417 ## possibly stop prior speech
418 #self.mayStop()
419 ## and prevent this speech from being interrupted
420 #self.inhibitMayStop()
421
422 ## get selected conversation tab
423 #selected_tab_por = self.getFirstSelected(tab_list_por)
424
425 ## check if we should announce the state of the current convo or not
426 #if selected_tab_por != self.script.last_convo:
427 #name = self.getAccName(selected_tab_por)
428 #self.saySection(text=name, template=_('chat with %s'))
429 #value = self.script.getTypingStatus(selected_tab_por)
430 #self.sayState(text=STATUS_MSG[value])
431 #self.script.last_convo = selected_tab_por
432
433 ## locate message history/compose text box PORs
434 ## pidgin 2 local client
435 #if self.script.is_pidgin2:
436 #self.script.chat_history_por = \
437 #self.getAccFromPath(selected_tab_por, *self.GAIM2_HISTORY_PATH)
438 #self.script.chat_compose_por = \
439 #self.getAccFromPath(selected_tab_por, *self.GAIM2_COMPOSE_PATH)
440 #if (self.script.chat_compose_por is None or
441 #not self.hasAccRole('text', self.script.chat_compose_por)):
442 #self.script.chat_compose_por = \
443 #self.getAccFromPath(selected_tab_por, *self.GAIM2_ALT_COMPOSE_PATH)
444 #print 'alt', self.script.chat_compose_por
445 ## pidgin 1.5 local client
446 #else:
447 #self.script.chat_history_por = \
448 #self.getAccFromPath(selected_tab_por, *HISTORY_PATH)
449 #self.script.chat_compose_por = \
450 #self.getAccFromPath(selected_tab_por, *COMPOSE_PATH)
451
452 ## tell user which text area is focused
453 #self.script.is_history_focused = \
454 #self.hasAccState('focused', self.script.chat_history_por)
455 #if self.script.is_history_focused:
456 ##if self.hasAccState('focused', self.script.chat_history_por):
457 #self.saySection(text=_('history,')) # this odd syntax supports i18n
458 #self.script.last_history_caret = AEPor() # reset
459 #return False
460 #elif self.hasAccState('focused', self.script.chat_compose_por):
461 ##elif self.hasAccState('focused', self.script.chat_compose_por):
462 #self.saySection(text=_('compose,')) # this odd syntax supports i18n
463 #return False
464 ##else:
465 ## return True # propagate handling of the event (default)
466
467 #class HandleSelectorChange(Task.SelectorTask):
468 #'''
469 #Task that tracks text selection changes. Used to updated the selection flag
470 #so the L{HandleCaretChange.executeDeleted} method can decide whether or not
471 #to allow reporting of deleted text.
472 #'''
473 #def executeText(self, por, text, **kwargs):
474 #'''
475 #Sets the selection flag to True if some text is selected else sets it to
476 #False.
477
478 #@param por: Point of regard to the text caret
479 #@type por: L{AEPor}
480 #@param text: Currently selected text
481 #@type text: string
482 #'''
483 #if text:
484 #self.script.selection = True
485 #else:
486 #self.script.selection = False
487 #return True
488
489 #class ReadIncoming(Task.CaretTask):
490 #'''
491 #Reads incoming messages.
492 #'''
493 #def executeInserted(self, por, text, text_offset, layer, **kwargs):
494 #'''
495 #Speaks text that starts with a new line character. This indicates a new
496 #line of text has been inserted into the message history.
497
498 #@param por: Point of regard where the caret event occurred
499 #@type por: L{AEPor}
500 #@param text: The text passed during the move
501 #@type text: string
502 #@param text_offset: The offset of the new caret position
503 #@type text_offset: integer
504 #@param layer: Layer of the event, focus, tier, or background
505 #@type layer: integer
506 #'''
507 ## convoluted logic is necessary in order to minimize expensive
508 ## compareAncestorRoles calls.
509 #if (not self.script_state.ReadBackground and
510 #not self.script_state.BrailleBackground and
511 #layer == AEConstants.LAYER_BACKGROUND):
512 ## don't output background messages if the user has it disabled.
513 #return
514
515 #rv = self.compareAncestorRoles(por, 'scroll pane', 'filler', 'panel',
516 #'filler', 'split pane', 'filler',
517 #'page tab')
518
519 #if rv and (layer != AEConstants.LAYER_BACKGROUND or
520 #(layer == AEConstants.LAYER_BACKGROUND and
521 #self.script_state.ReadBackground)):
522 ## queue up text to speak
523 #self.sayItem(text=text)
524
525 #if rv and (layer != AEConstants.LAYER_BACKGROUND or
526 #(layer == AEConstants.LAYER_BACKGROUND and
527 #self.script_state.BrailleBackground)):
528 ## output to braille device
529 #self.doTask('braille text', text=text)
530
531
532 #class HandleCaretChange(Task.CaretTask):
533 #'''
534 #Task that handles a L{AEEvent.CaretChange}. Used to read an entire message in
535 #chat history, rather than simply the current line. The L{executeMoved} method
536 #finds the beginning and end of the current message, truncates the timestamp
537 #and user name when redundant, then reads the message.
538 #'''
539 #def executeMoved(self, por, text, text_offset, **kwargs):
540 #'''
541 #Announces an entire message from a remote user by looking for hard line
542 #breaks (\\n) when the caret moves to a position just after or just before
543 #the break character. If the caret is anywhere else, lets other L{AEScript <AEScript.AEScript>}s do
544 #their default caret processing.
545
546 #@param por: Point of regard where the caret event occurred
547 #@type por: L{AEPor}
548 #@param text: The text passed during the move
549 #@type text: string
550 #@param text_offset: The offset of the new caret position
551 #@type text_offset: integer
552 #'''
553 ## debugging code for handleTableChange, since we may or may not get
554 ## multiple events when a remote buddy logs off, announce when caret changes
555 ## just as a test, not for final code.
556 ##if self.script.last_row_inserted_por is not None:
557 ## print "last_row_inserted_por" , self.script.last_row_inserted_por
558 ## self.script.last_row_inserted_por = None
559 ## could eliminate by setting is_history_focused = False when appropriate
560 #tab_list_por = self.script.getActivePageTabListPOR()
561 ## if chat window and chat history have focus
562 #if tab_list_por is not None and self.script.is_history_focused:
563 ## say line when item_offset changes
564 #if (not por.isSameItem(self.script.last_history_caret)):
565 ## get the start of the line (character after a \n)
566 #start = self.getStartOfHardLine(por)
567 ## get the end of the line (next encountered \n)
568 #end = self.getEndOfHardLine(por)
569
570 ## store the current POR
571 #self.script.last_history_caret = por
572 ## if we're not at the start or end of a true message line, let
573 ## other Scripts handle the caret event unless at start/end of msg
574 #if por != end and por != start:
575 #return True
576
577 ## get all the text between the start and end PORs
578 #msg = self.getAccTextBetween(start, end)
579
580 #self.mayStop()
581 #self.sayItem(text=msg)
582 ##self.inhibitMayStop()
583 #return False
584
585 ## respond to caret movement on same line
586 ## just let other Scripts handle this case
587 #else:
588 #self.script.last_history_caret = por
589 #return True
590
591 ## not in chat history
592 #else:
593 #return True
594
595 #def executeInserted(self, **kwargs):
596 #'''Resets the selection flag.'''
597 #self.script.selection = False
598 #return True
599
600 #def executeDeleted(self, text, **kwargs):
601 #'''
602 #Consumes the deletion event if the selection flag is False and more than
603 #one character of text was deleted (i.e. a message was sent). Avoids
604 #announcing the sent text as "Backspace <text>" as well as the text that
605 #appears in the message history. If the selection flag is True, resets it.
606
607 #@param text: The text deleted
608 #@type text: string
609 #'''
610 #if not self.script.selection and len(text) > 1:
611 #return False
612 #self.script.selection = False
613 #return True
614
615 #class HandlePropertyChange(Task.PropertyTask):
616 #'''
617 #Task that handles a L{AEEvent.PropertyChange}.
618 #'''
619 #def execute(self, por, name, value, **kwargs):
620 #'''
621 #If in a chat window, check to see if the text color properties of a
622 #conversation tab have changed. Announce change if to anything other than
623 #'idle' (ie. active typing, paused typing, away, away idle, logged out).
624 #'''
625 #is_chat_window = self.script.getActivePageTabListPOR()
626 ## test to see if a chat window and if a conversation page tab
627 #if is_chat_window is not None and self.hasAccRoleName('page tab', por):
628 #user = self.getAccName(por)
629 #status = self.script.getTypingStatus(por)
630 ##print "%s: %s: %s" %(name, STATUS_MSG[status], por)
631 ## don't report idle status, we already report paused and new message
632 #if status != IDLE_STATUS:
633 ##print "PidginScript::Property change:", por, name, value
634 ##print "%s: %s: %s" %(user, STATUS_MSG[status], por)
635 #self.sayState(text=(user, STATUS_MSG[status]), template='%s %s,')
636 #return True
637
638
639 #class BuddySignOnOff(Task.TableTask):
640 #'''
641 #Task that handles a L{AEEvent.TableChange}.
642
643 #These events will be used to know when a remote buddy logs in/out, however
644 #current information makes the "in/out" determination unreliable. Bugs are
645 #being filed against Pidgin. Therefore, this script does not currently register
646 #to handle TableChange events.
647 #'''
648
649 #def executeTableRowInserted(self, por, first_child_por, last_child_por,
650 #layer, **kwargs):
651 #'''
652 #Executes this task in response to a row-inserted table change event.
653 #Called by L{Task.TableTask.execute}.
654
655 #@param por: The L{AEPor} for the related accessible
656 #@type por: L{AEPor}
657 #@param first_child_por: The L{AEPor} of first inserted row
658 #@type first_child_por: L{AEPor}
659 #@param last_child_por: The L{AEPor} of last inserted row
660 #@type last_child_por: L{AEPor}
661 #@param layer: Layer on which the event occurred
662 #@type layer: integer
663 #'''
664 ##print "PidginScript::executeTableRowInserted()", por, first_child_por, \
665 ## last_child_por, layer
666 #frame_name = self.getWindowTitle(por)
667 ## only handle table change events from buddy list (don't announce when
668 ## conversation tab order changes, assume only a sighted user would do that).
669 #if frame_name == "Buddy List":
670 ##print "1" , self.getItemText(first_child_por)
671 ##print "2" , self.getItemText(last_child_por)
672 ## may be used in case where, on sign-off, multiple inserts fire
673 ## self.script.last_row_inserted_por = first_child_por
674 ## name = self.getItemText(self.script.last_row_inserted_por)
675 ##print "%s logged in" %name
676 #status = STATUS_MSG[LOGIN_STATUS]
677 #self.sayState(text=(name, status), template='%s: %s,')
678 #return True
679
680 #def executeTableRowDeleted(self, por, first_child_por, last_child_por,
681 #layer, **kwargs):
682 #'''
683 #Executes this task in response to a row-deleted table change event.
684 #Called by L{execute}.
685
686 #@param por: The L{AEPor} for the related accessible
687 #@type por: L{AEPor}
688 #@param first_child_por: The L{AEPor} of first deleted row
689 #@type first_child_por: L{AEPor}
690 #@param last_child_por: The L{AEPor} of last deleted row
691 #@type last_child_por: L{AEPor}
692 #@param layer: Layer on which the event occurred
693 #@type layer: integer
694 #'''
695 ##print "PidginScript::executeTableRowDeleted()" , por, first_child_por, \
696 ## last_child_por, layer
697 #frame_name = self.getWindowTitle(por)
698 #if frame_name == "Buddy List":
699 ##print "1" , self.getItemText(first_child_por)
700 ##print "2" , self.getItemText(last_child_por)
701 #name = self.getItemText(first_child_por)
702 ##print "%s logged out" %name
703 #status = (name, STATUS_MSG[LOGOUT_STATUS])
704 #self.sayState(text=status, template='%s: %s,')
705 #return True
706
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Mon Jun 30 13:06:16 2008 | http://epydoc.sourceforge.net |