1 '''
2 Defines default L{AccAdapt.Adapter}s for the L{AEInterfaces.IAccessibleAction}
3 interface on L{pyLinAcc.Accessibility.Accessible} objects.
4
5 @author: Brett Clippingdale
6 @author: Peter Parente
7 @author: Eirikur Hallgrimsson
8 @author: Scott Haeger
9 @organization: IBM Corporation
10 @copyright: Copyright (c) 2005, 2007 IBM Corporation
11 @license: The BSD License
12
13 All rights reserved. This program and the accompanying materials are made
14 available under the terms of the BSD license which accompanies
15 this distribution, and is available at
16 U{http://www.opensource.org/licenses/bsd-license.php}
17 '''
18 from AccAdapt import PORAdapter
19 from AEInterfaces import *
20 from POR import POR
21 import pyLinAcc
22 from pyLinAcc import Interfaces, Constants
23
25 '''
26 Adapts all AT-SPI accessibles to the L{IAccessibleAction} interface. No
27 condition for adaption is given implying that this adapter is used as a
28 default by L{AccAdapt} when no better adapter is available.
29
30 Expects the subject to be a L{pyLinAcc.Accessible}.
31 '''
32 provides = [IAccessibleAction]
33
34 @pyLinAcc.errorToLookupError
36 '''
37 Moves the caret to the location given by the item offset + the char offset.
38 Moves to the beginning of the text if the item offset is None.
39
40 @return: Indicator of whether the caret was moved successfully
41 @rtype: boolean
42 @raise LookupError: When the accessible object is dead
43 @raise NotImplementedError: When the Text interface is not supported
44 '''
45 acc = self.accessible
46 if self.item_offset is None:
47 off = 0
48 else:
49 off = self.item_offset + self.char_offset
50 tex = Interfaces.IText(acc)
51 return tex.setCaretOffset(off)
52
53 @pyLinAcc.errorToLookupError
54 - def setAccText(self, text):
55 '''
56 Replace contents of text area with the given text.
57
58 @param text: Text to set as the content of the text area given by the
59 L{POR}
60 @type text: string
61 @return: Indicator of whether the text was set successfully or not
62 @rtype: boolean
63 @raise LookupError: When the accessible object is dead
64 @raise NotImplementedError: When the EditableText interface is not
65 supported
66 '''
67 tex = Interfaces.EditableText(self.accessible)
68 return tex.setTextContents(text)
69
70 @pyLinAcc.errorToLookupError
71 - def insertAccText(self, text, attrs):
72 '''
73 Inserts text at the location given by the item offset + the char offset.
74 Inserts at the beginning of the text if the item offset is None.
75
76 @param text: Text to insert at the given position
77 @type text: string
78 @param attrs: Dictionary of string name/value pairs of text attributes to
79 set on the inserted text
80 @type attrs: dictionary
81 @return: Indicator of whether the text was inserted successfully or not
82 @rtype: boolean
83 @raise LookupError: When the accessible object is dead
84 @raise NotImplementedError: When the EditableText interface is not
85 supported
86 '''
87 acc = self.accessible
88 if self.item_offset is None:
89 off = 0
90 else:
91 off = self.item_offset + self.char_offset
92 tex = Interfaces.EditableText(acc)
93 if len(attrs) == 0:
94 return tex.insertText(off, text, len(text))
95 else:
96 attrs = '; '.join(['%s:%s' % (name, val) for name, val in attrs.items()])
97 return tex.insertTextWithAttributes(off, text, len(text), attrs)
98
99 @pyLinAcc.errorToLookupError
100 - def setAccTextAttrs(self, por, attrs):
101 '''
102 Sets the accessible text attributes starting at item offset + char offset
103 up to the offset given by the L{POR}. Always replaces the current
104 attributes at present.
105
106 @param por: Point of regard to the end of the text run
107 @type por: L{POR}
108 @param attrs: Dictionary of string name/value pairs of text attributes to
109 set on the text range
110 @type attrs: dictionary
111 @return: Indicator of whether the text attributes were set successfully or
112 not
113 @rtype: boolean
114 @raise LookupError: When the accessible object is dead
115 @raise NotImplementedError: When the EditableText interface is not
116 supported
117 '''
118 acc = self.accessible
119 if self.item_offset is None:
120 start_off = 0
121 else:
122 start_off = self.item_offset + self.char_offset
123 text_area = Interfaces.EditableText(acc)
124 if por.item_offset is None:
125 end_off = text_area.characterCount
126 else:
127 end_off = por.item_offset + por.char_offset
128
129 attrs = '; '.join(['%s:%s' % (name, val) for name, val in attrs.items()])
130 try:
131
132 return text_area.setAttributeRun(attrs, start_off, end_off, True)
133 except (pyLinAcc.NotImplemented, AttributeError):
134 return text_area.setAttributes(attrs, start_off, end_off)
135
136 @pyLinAcc.errorToLookupError
137 - def copyAccText(self, por):
138 '''
139 Copies the text starting at item offset + char offset up to the offset
140 given by the L{POR}. Copies from the beginning of the text if subject item
141 offset is None. Copies to the end of the text if the L{POR} item offset is
142 None.
143
144 @param por: Point of regard to the end terminus of the copy operation
145 @type por: L{POR}
146 @return: Indicator of whether the text was copied successfully or not
147 @rtype: boolean
148 @raise LookupError: When the accessible object is dead
149 @raise NotImplementedError: When the EditableText interface is not
150 supported
151 '''
152 acc = self.accessible
153 if self.item_offset is None:
154 start_off = 0
155 else:
156 start_off = self.item_offset + self.char_offset
157 text_area = Interfaces.EditableText(acc)
158 if por.item_offset is None:
159 end_off = text_area.characterCount
160 else:
161 end_off = por.item_offset + por.char_offset
162 return text_area.copyText(start_off, end_off)
163
164 @pyLinAcc.errorToLookupError
165 - def cutAccText(self, por):
166 '''
167 Cuts the text starting at item offset + char offset up to the offset given
168 by the L{POR}. Cuts from the beginning of the text if subject item offset
169 is None. Cuts to the end of the text if the L{POR} item offset is None.
170
171 @param por: Point of regard to the end terminus of the cut operation
172 @type por: L{POR}
173 @return: Indicator of whether the text was cut successfully or not
174 @rtype: boolean
175 @raise LookupError: When the accessible object is dead
176 @raise NotImplementedError: When the EditableText interface is not supported
177 '''
178 acc = self.accessible
179 if self.item_offset is None:
180 start_off = 0
181 else:
182 start_off = self.item_offset + self.char_offset
183 text_area = Interfaces.EditableText(acc)
184 if por.item_offset is None:
185 end_off = text_area.characterCount
186 else:
187 end_off = por.item_offset + por.char_offset
188 return text_area.cutText(start_off, end_off)
189
190 @pyLinAcc.errorToLookupError
191 - def deleteAccText(self, por):
192 '''
193 Deletes the text starting at item offset + char offset up to the offset
194 given by the L{POR}. Deletes from the beginning of the text if subject item
195 offset is None. Deletes to the end of the text if the L{POR} item_offset is
196 None.
197
198 @param por: Point of regard to the end terminus of the delete operation
199 @type por: L{POR}
200 @return: Indicator of whether the text was deleted successfully or not
201 @rtype: boolean
202 @raise LookupError: When the accessible object is dead
203 @raise NotImplementedError: When the EditableText interface is not
204 supported
205 '''
206 acc = self.accessible
207 if self.item_offset is None:
208 start_off = 0
209 else:
210 start_off = self.item_offset + self.char_offset
211 text_area = Interfaces.EditableText(acc)
212 if por.item_offset is None:
213 end_off = text_area.characterCount
214 else:
215 end_off = por.item_offset + por.char_offset
216 return text_area.deleteText(start_off, end_off)
217
218 @pyLinAcc.errorToLookupError
219 - def pasteAccText(self):
220 '''
221 Pastes the text at item offset + char offset. Pastes from the beginning of
222 the text is item offset is None.
223
224 @return: Indicator of whether the text was pasted successfully or not
225 @rtype: boolean
226 @raise LookupError: When the accessible object is dead
227 @raise NotImplementedError: When the EditableText interface is not
228 supported
229 '''
230 acc = self.accessible
231 if self.item_offset is None:
232 start_off = 0
233 else:
234 start_off = self.item_offset + self.char_offset
235 text_area = Interfaces.EditableText(acc)
236 return text_area.pasteText(start_off)
237
238 @pyLinAcc.errorToLookupError
239 - def selectAccText(self, por, n=None):
240 '''
241 Adds a new selection if n is None or sets the nth selection otherwise.
242 Selects the text starting at item offset + char offset up to the offset
243 given by the L{POR}. Selects to the end of the text if the L{POR}
244 item_offset is None.
245
246 @param por: Point of regard to the end terminus of the select operation
247 @type por: L{POR}
248 @return: Indicator of whether the text was selected successfully or not
249 @rtype: boolean
250 @raise LookupError: When the accessible object is dead
251 @raise NotImplementedError: When the Text interface is not supported
252 '''
253 acc = self.accessible
254 if self.item_offset is None:
255 start_off = 0
256 else:
257 start_off = self.item_offset + self.char_offset
258 text_area = Interfaces.Text(acc)
259 if por.item_offset is None:
260 end_off = text_area.characterCount
261 else:
262 end_off = por.item_offset + por.char_offset
263 if n is None:
264
265 return text_area.addSelection(start_off, end_off)
266 else:
267
268 return text_area.setSelection(n, start_off, end_off)
269
270 - def deselectAccText(self, n=None):
271 '''
272 Removes a all text selections if n is None or removes the nth text
273 selection otherwise. When n is None, returns True if at least one selection
274 was removed.
275
276 @return: Indicator of whether the text was deselected successfully or not
277 @rtype: boolean
278 @raise LookupError: When the accessible object is dead
279 @raise NotImplementedError: When the Text interface is not supported
280 '''
281 text_area = Interfaces.Text(acc)
282 if n is None:
283
284 values = [text_area.removeSelection(i) for i in
285 xrange(text_area.getNSelections())]
286
287 return reduce(lambda x, y: x or y, values)
288 else:
289
290 return text_area.removeSelection(n)
291
292 @pyLinAcc.errorToLookupError
294 '''
295 Performs a mouse event on the center of a given point of regard.
296
297 @param event: Mouse event to perform
298 @type event: integer (EVENT_SYNTHMOUSE*)
299 @return: Indicator of whether the event succeded or not
300 @raise LookupError: When the accessible object is dead
301 '''
302 ai = IAccessibleInfo(self.subject)
303 vpt_x, vpt_y = ai.getAccPosition()
304 width, height = ai.getAccVisualExtents()
305 devcont = pyLinAcc.Registry.getDeviceEventController()
306 devcont.generateMouseEvent(vpt_x + width*.5, vpt_y+ height*.5,
307 event)
308
309
310 return True
311
312 @pyLinAcc.errorToLookupError
314 '''
315 Gives the subject accessible the keyboard focus.
316
317 @return: Did accessible accept (True) or refuse (False) the focus change?
318 @rtype: boolean
319 @raise LookupError: When the accessible object is dead
320 @raise NotImplementedError: When the accessible does not support an
321 interface for setting focus
322 '''
323 c = Interfaces.IComponent(self.accessible)
324 return c.grabFocus()
325
326 @pyLinAcc.errorToLookupError
328 '''
329 Selects the subject accessible if all is False. Selects all children if all
330 is True.
331
332 @param all: Select all children?
333 @type all: boolean
334 @return: Did accessible accept (True) or refuse (False) the selection?
335 @rtype: boolean
336 @raise LookupError: When the accessible object is dead
337 @raise NotImplementedError: When the accessible does not support an
338 interface for setting selection
339 '''
340 acc = self.accessible
341 if all:
342
343 isel = Interfaces.ISelection(acc)
344
345 return isel.selectAll()
346 else:
347
348 i = acc.getIndexInParent()
349 parent = acc.parent
350
351 isel = Interfaces.ISelection(parent)
352 return isel.selectChild(i)
353
354 @pyLinAcc.errorToLookupError
356 '''
357 Deselects the subject accessible if all is False. Deselects all children if
358 all is True.
359
360 @param all: Deselect all children?
361 @type all: boolean
362 @return: Did accessible accept (True) or refuse (False) the deselection?
363 @rtype: boolean
364 @raise LookupError: When the accessible object is dead
365 @raise NotImplementedError: When the accessible does not support an
366 interface for setting selection
367 '''
368 acc = self.accessible
369 if all:
370
371 isel = Interfaces.ISelection(acc)
372
373 return isel.clearSelection()
374 else:
375
376 i = acc.getIndexInParent()
377 parent = acc.parent
378
379 isel = Interfaces.ISelection(parent)
380 return isel.deselectChild(i)
381
382 @pyLinAcc.errorToLookupError
384 '''
385 Executes the accessible action given by the index.
386
387 @param index: Index of the action to execute
388 @type index: integer
389 @return: Did the action execute (True) or not (False)?
390 @rtype: boolean
391 @raise LookupError: When the accessible object is dead
392 @raise NotImplementedError: When the accessible does not support the action
393 interface
394 '''
395 act = Interfaces.IAction(self.accessible)
396 return act.doAction(index)
397