| Trees | Indices | Help |
|
|---|
|
|
1 '''
2 Defines a special L{AEScript <AEScript.AEScript>} for the GNOME Terminal.
3 Corrects caret problems.
4
5 @author: Peter Parente
6 @author: Brett Clippingdale
7 @author: Eitan Isaacson
8 @author: Scott Haeger
9 @author: Luiz Rocha
10 @organization: IBM Corporation
11 @copyright: Copyright (c) 2005, 2007 IBM Corporation
12
13 @license: I{The BSD License}
14 All rights reserved. This program and the accompanying materials are made
15 available under the terms of the BSD license which accompanies
16 this distribution, and is available at
17 U{http://www.opensource.org/licenses/bsd-license.php}
18 '''
19 from AccessEngine import AEScript, AccessEngineAPI
20 from AccessEngine import AEConstants
21 from AccessEngine.AEPor import AEPor
22 from Tools.i18n import bind, _
23
24 __uie__ = dict(kind='script', tier='gnome-terminal', all_tiers=False)
25
27 '''
28 A special L{AEScript <AEScript.AEScript>} for handling gnome terminal.
29 Corrects caret problems in in gnome-terminal.
30
31 @ivar actions: Maps all possible 'added' values to strings
32 @type actions: dictionary
33 @ivar move_keys: Stores all keys that allow movement
34 @type move_keys: tuple
35 @ivar delete_keys: Stores keys to delete something
36 @type delete_keys: tuple
37 @ivar space_key: Store the space key
38 @type space_key: string
39 @ivar ret_key: Store the return key
40 @type ret_key: string
41 @ivar last_caret: Stores the previous caret
42 @type last_caret: L{AEPor}
43 @ivar last_key: Stores the last key pressed for future comparision
44 @type last_key: tuple
45 '''
47 '''
48 Registers a L{event task <AEScript.event_tasks>} to handle
49 L{caret events <AEEvent.CaretChange>} and chain it around the default
50 L{BasicSpeechScript.onCaretChange
51 <BasicSpeechScript.BasicSpeechScript.onCaretChange>}-method.
52 Initialize script variables.
53 '''
54 # initialize script variables
55 self.actions = {None: 'move', False: 'delete', True: 'insert'}
56 self.move_keys = ('Left', 'Right', 'Home', 'End')
57 self.delete_keys = ('Delete', 'BackSpace')
58 self.space_key = 'space'
59 self.ret_key = 'Return'
60 self.last_caret = AEPor(item_offset=0)
61 self.last_key = None
62
63 # set an audio device as the default output
64 AccessEngineAPI.setScriptIdealOutput(self, 'audio')
65
66 # register tasks
67 #self.registerTask('terminal caret', self.handleTerminalCaret)
68
69 # chain to other tasks
70 #self.chainTask('terminal caret', AEConstants.CHAIN_AROUND,
71 #'read caret', 'BasicSpeechScript')
72
74 '''
75 Provides the localized name of this L{AEScript <AEScript.AEScript>}.
76
77 @return: Human readable translated name of this script.
78 @rtype: string
79 '''
80 return _('GNOME Terminal')
81
83 '''
84 Describe which L{AETier} this script applies to by default.
85
86 @return: Human readable translated description of this script.
87 @rtype: string
88 '''
89 return _('Improve general accessibility of the GNOME Terminal.')
90
92 '''
93 This task handles messy L{AEEvent.CaretChange} events sent from
94 gnome-terminal. This one is chained around the
95 L{BasicSpeechScript.onCaretChange
96 <BasicSpeechScript.BasicSpeechScript.onCaretChange>} event. The method
97 identifies the event, fix, propagate or ignore it althogether.
98
99 @param por: Point of regard where the caret event occurred
100 @type por: L{AEPor}
101 @param text: The text inserted, deleted or the line of the caret
102 @type text: string
103 @param text_offset: The offset of the inserted/deleted text or the line
104 offset when movement only
105 @type text_offset: integer
106 @param added: C{True} when text added, C{False} when text deleted, and
107 C{None} (the default) when event is for caret movement only.
108 @type added: boolean
109 @keyword layer: Layer on which the event occurred
110 @type layer: integer
111 @keyword task_name: Name of the task this function executes.
112 @type task_name: string
113 @param kwargs: Arbitrary keyword arguments to pass to the task
114 @type kwargs: dictionary
115 @return: True to allow other tasks to process this event.
116 @rtype: boolean
117 '''
118 # TODO: write a nice description for execute.
119 # TODO: would it be a good idea to refactor this and move the conditional
120 # blocks for each 'added' to separate methods inside this task?
121 # TODO: check long cmdlines (call a random prog with a long line of args)
122 # TODO: check reverse/incremental search (Ctrl+R) output
123 # TODO: say the whole word (instead of just the ending) on tab-completion?
124 # TODO: say the character (ie. 'vertical bar' for '|') or common name ('pipe')?
125 # TODO: selection is bogus, fix
126 # TODO: gnome-terminal breaks long commnand lines (ex. du --apparent-size
127 # --human-readable --summarize
128 # ~/downloads/mozilla/firefox/granparadiso), find a way around.
129
130 # handling only terminal events
131 if not AccessEngineAPI.hasAccRole('terminal', por):
132 return True
133
134 # last key pressed in gterm is our current key
135 current_key = self.getLastKey()
136
137 # TODO: remove the 'else' from the action conditional loop and use this as
138 # default condition setting?
139 # propagate to chained tasks by default
140 # propagate = True
141
142 # --- Insert Events ----------------------------------------------------- #
143 if self.actions[added] == 'insert':
144 # insert events are fired by gnome-terminal when an insertion or a
145 # deletion happens. Cases to implement:
146 #
147 # 1. Terminal responding to user input should not be interrupted
148 # 2. Ignore insert event fired by delete keys
149 # 3. Route all other events to basic speech script
150
151 # 1. if the current key is a Return, the terminal is probably responding
152 # to some user input. the avalanche of events gterm sends might break the
153 # speech output. inhibit the next stop to prevent this.
154 if current_key[1] == self.ret_key:
155 AccessEngineAPI.inhibitMayStop()
156 propagate = True
157 # 2. insert event bundled in a valid deletes, ignore those
158 elif current_key[1] in self.delete_keys:
159 propagate = False
160 # 3. let basic speech handle anything else
161 else:
162 propagate = True
163
164 # --- Move Events ------------------------------------------------------- #
165 elif self.actions[added] == 'move':
166 # everything you do on gnome-terminal fires a move event, but we want to
167 # react only to a few cases:
168 #
169 # 1. Events fired by actual move keys (Up/Down/Home/End),
170 # 2. Events fired by space key, since gterm considers space to be just
171 # a move key, thus produce no announce,
172 # 3. Move events that happens before an insert, to set the actual caret
173 # position,
174 # 4. Ignore anything else.
175
176 # 1. react if this move event was fired by an actual move key
177 if current_key[1] in self.move_keys:
178 # TODO: because of the basic speech self.changed var, first move never
179 # gets announced. get around that.
180 self.last_caret = por
181 propagate = True
182 # 2. gnome-terminal only move the caret when space is pressed. do a fake
183 # space announcement then.
184 elif current_key[1] == self.space_key:
185 self.sayChar(text=' ')
186 self.last_caret = por
187 propagate = False
188 # 3. if this event is bundled with an insert event, store the caret
189 # position for future use
190 elif not current_key[1] in self.delete_keys:
191 self.last_caret = por
192 propagate = False
193 # 4. Ignore anything else
194 else:
195 propagate = False
196
197 # --- Delete Events ----------------------------------------------------- #
198 elif self.actions[added] == 'delete':
199 # delete events are fired in both inserts and deletes, but reaction to it
200 # should happen only when delete keys are pressed. Cases:
201 #
202 # 1. Handle event fired by delete key press,
203 # 2. Ignore event bundled on insert events.
204
205 # 1. delete event fired by a delete key, let's handle it
206 if current_key[1] in self.delete_keys:
207 # the text param on delete events contains the whole text after the
208 # deleted character. trim the text to announce only the deleted char
209 #
210 # TODO: selection delete is correctly announced?
211 text = text[:1]
212 # pass to BasicSpeechScript last_caret the last valid caret position
213 AccessEngineAPI.setScriptVar(self.tier, 'BasicSpeechScript', 'last_caret',
214 self.last_caret)
215 # update last_caret position
216 self.last_caret = por
217 # let basic speech do the rest
218 propagate = True
219 # not a valid delete event, ignore it
220 else:
221 propagate = False
222 else:
223 # propagate and let BasicSpeechScript handle anything we missed here
224 propagate = True
225
226 # if propagate is True, call BasicSpeechScript named task 'read caret'.
227 if propagate:
228 self.doTask('read caret', 'BasicSpeechScript', chain=False, por=por, text=text,
229 text_offset=text_offset, added=added, **kwargs)
230
231 # store keyboard input and last caret position for future comparisons
232 self.last_key = current_key
233
234 return propagate
235
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Mon Jun 30 13:06:11 2008 | http://epydoc.sourceforge.net |