Changeset 73
- Timestamp:
- 11/23/07 19:52:07
- Files:
-
- action_groups/trunk/ActionBrowser.py (modified) (16 diffs)
- action_groups/trunk/KeyGenerator.py (added)
- action_groups/trunk/action_tree.py (modified) (6 diffs)
- action_groups/trunk/atspi.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
action_groups/trunk/ActionBrowser.py
r72 r73 21 21 def getApp(name): 22 22 desktop = pyatspi.Registry.getDesktop(0) 23 if name is None: 24 return desktop 23 25 for app in desktop: 24 26 if app and app.name == name: 25 27 return app 26 return desktop28 return None 27 29 28 30 class ActionBrowser(klass): … … 31 33 else: 32 34 __gsignals__ = {'switch-down' : 33 (gobject.SIGNAL_RUN_FIRST,34 gobject.TYPE_NONE,35 (gobject.TYPE_INT,gobject.TYPE_INT,)),36 'switch-up' :37 (gobject.SIGNAL_RUN_FIRST,38 gobject.TYPE_NONE,39 (gobject.TYPE_INT,gobject.TYPE_INT,))}35 (gobject.SIGNAL_RUN_FIRST, 36 gobject.TYPE_NONE, 37 (gobject.TYPE_INT,gobject.TYPE_INT,)), 38 'switch-up' : 39 (gobject.SIGNAL_RUN_FIRST, 40 gobject.TYPE_NONE, 41 (gobject.TYPE_INT,gobject.TYPE_INT,))} 40 42 41 43 def __init__(self, *args, **kwargs): 42 klass.__init__(self,gtk.WINDOW_TOPLEVEL)43 self.acc = getApp(kwargs['app'])44 self.init()45 self._onGenerate(None)44 klass.__init__(self,gtk.WINDOW_TOPLEVEL) 45 self.acc = getApp(kwargs['app']) 46 self.init() 47 self._onGenerate(None) 46 48 47 49 def init(self): … … 65 67 vbox.pack_start(bottom_hbox, False) 66 68 self.groups_tree = ProgressiveTree() 67 69 68 70 self.groups_tree.connect('row-activated', self._onRowActivated) 69 71 … … 99 101 self.groups_tree.set_top_acc(self.acc) 100 102 self.groups_tree.next() 101 103 102 104 def _onExamine(self, button): 103 105 acc = self.groups_tree.get_selected_acc() 104 106 if acc is not None: 105 107 self.node.update(acc) 106 108 107 109 def _onScan(self, button): 108 110 if not self.is_scanning: … … 111 113 label = ('Stop _Scan' if self.is_scanning else 'Start _Scan') 112 114 button.set_label(label) 113 115 114 116 def _onScanStep(self): 115 117 if self.is_scanning: … … 124 126 #acc = self.groups_tree.get_acc_from_path(path) 125 127 #self.node.update(acc) 126 128 127 129 def _onSelectionChanged(self, selection): 128 130 acc = self.groups_tree.get_selected_acc(selection) … … 133 135 return 134 136 extents = ci.getExtents(pyatspi.DESKTOP_COORDS) 135 print extents136 137 Blinker(extents) 137 138 … … 159 160 self.append_column(tvc) 160 161 162 pyatspi.Registry.registerEventListener(self._onAccEventState, 'object', 'window', 'focus') 161 163 pyatspi.Registry.registerEventListener(self._onAccEventState, 'object:state-changed') 162 164 #self.set_property('fixed-height-mode', True) # speed display … … 174 176 model.popLevel(iter) 175 177 self.next_children = True; 176 178 177 179 def _getSelection(self, selection=None): 178 180 selection = selection or self.get_selection() … … 183 185 acc = None 184 186 return (model, iter, acc) 185 187 186 188 def get_selected_acc(self, selection=None): 187 189 model, iter, acc = self._getSelection(selection) 188 190 return acc 189 191 190 192 def get_acc_from_path(self, path): 191 193 try: … … 194 196 return None 195 197 return acc 196 198 197 199 def set_top_acc(self, acc): 198 200 model = ProgressiveTreeModel(acc) … … 202 204 def __del__(self): 203 205 self.deRegisterEventListener(self._onAccEventState, 'object:state-changed') 204 206 205 207 def select(self, iter): 206 208 selection = self.get_selection() … … 223 225 self.next_children = True; 224 226 self.select(nextiter) 225 227 226 228 def _onAccEventState(self, event): 227 229 ''' 228 230 Callback for accessible state changes. Repopulates the states model. 229 231 230 232 @param event: Event that triggered this callback. 231 233 @type event: Accessibility.Event … … 238 240 if acc is None: 239 241 return 240 print event.type, event.detail1, event.detail2, event.source, acc, repr(event.source.getRole())242 printEvent(event) 241 243 if event.source.getRole() == pyatspi.ROLE_WINDOW \ 242 and event.type in ('object:state-changed:showing'):244 and event.type in ('object:state-changed:showing'): 243 245 showing = bool(event.detail1) 244 246 path = model.get_path(iter) 245 if showing \ 246 and not model.iter_has_child(iter): 247 248 if showing:# \ 249 # and not model.iter_has_child(iter): 247 250 model.makeExpandable(iter) 251 #model.addSubTree(event.source, None) 248 252 model.popLevel(iter) 249 253 self.expand_row(path, False) 254 acc.is_group = True 255 250 256 elif not showing: 251 257 menu_iter = model.iter_parent_with_role(iter, pyatspi.ROLE_MENU) 252 258 if menu_iter: 253 259 menu_path = model.get_path(menu_iter) 254 if self.row_expanded(menu_path):260 if self.row_expanded(menu_path): 255 261 self.collapse_row(menu_path) 256 262 model.dePopLevel(menu_iter, all=True) 257 263 acc.is_group = False 264 self.get_selection().select_iter(menu_iter) 265 258 266 def do_action(self): 259 267 model, iter, acc = self._getSelection() 260 268 if acc is None: return 261 269 path = model.get_path(iter) 262 is_interactive = acc.isInteractive() 263 if is_interactive: 270 acc.grabFocus() 271 272 if acc.isActionable(): 273 if not (acc.getRole() == pyatspi.ROLE_MENU and self.row_expanded(path)): 274 try: 275 action_if = acc.queryAction() 276 action_if.doAction(0) 277 except: 278 pass 279 280 elif acc.isEditable(): 264 281 try: 265 action_if = acc.queryAction() 266 action_if.doAction(0) 282 MessageBox(None, 'You are now editing the text:\r\n%s' % acc.getText()) 267 283 except: 268 pass284 raise 269 285 270 else: 286 elif acc.isSelectable(): 287 acc.toggleSectable() 288 289 if acc.is_group: 271 290 if self.row_expanded(path): 272 self.collapse_row(path) 291 if acc.getRole() == pyatspi.ROLE_MENU: 292 from KeyGenerator import sendKeyCombination 293 sendKeyCombination('Escape', '') 294 else: 295 self.collapse_row(path) 273 296 elif model.iter_has_child(iter): 274 297 self.expand_row(path, False) 298 self.next() 299 300 class MessageBox(): 301 def __init__(self, parent, message): 302 mb = gtk.MessageDialog(parent, 303 gtk.DIALOG_MODAL, 304 gtk.MESSAGE_INFO, 305 buttons=gtk.BUTTONS_OK, 306 message_format=message 307 ) 308 mb.run() 309 mb.destroy() 310 275 311 276 312 class Blinker(object): … … 288 324 self.inv = gtk.Invisible() 289 325 self.inv.set_screen(screen) 290 326 291 327 self.blinks = 0 292 328 gobject.timeout_add(30, self._drawRectangle) … … 311 347 return False 312 348 return True 349 350 def printEvent(event): 351 from os import times 352 t = int(os.times()[-1] % 10000) 353 print t, event.type, event.detail1, event.detail2, \ 354 (str(event.any_data) if event.any_data else ''), \ 355 '\n\t', event.host_application, event.source, repr(event.source_role) 356 if isinstance(event.any_data, pyatspi.Accessibility.BoundingBox): 357 ad = event.any_data 358 print '\t', ad.x, ad.y, ad.width, ad.height 359 action_groups/trunk/action_tree.py
r72 r73 88 88 return False 89 89 #print self, self.getStates() 90 return self.isSelectable() or self.hasInterfaceIn('Action','EditableText') 90 return self.isSelectable() or self.hasInterfaceIn('Action','EditableText', 'Hypertext') 91 92 def isEditable(self): 93 return self.hasInterface('EditableText') 91 94 92 95 def isActionable(self): … … 109 112 if rv is not None: break 110 113 return bool(rv) 111 114 115 def grabFocus(self): 116 try: 117 ic = self.queryComponent() 118 ic.grabFocus() 119 except NotImplementedError: 120 pass 121 122 def toggleSectable(self): 123 selection = self._acc.parent 124 try: 125 si = selection.querySelection() 126 except NotImplementedError: 127 return 128 129 index = self.getIndexInParent() 130 if si.isChildSelected(index): 131 si.deselectChild(index) 132 else: 133 si.selectChild(index) 134 135 def getText(self): 136 try: 137 eti = self.queryEditableText() 138 except NotImplementedError: 139 return 140 return eti.getText(0,-1) 141 112 142 class ActionGroup(object): 113 143 def __init__(self, root_acc): … … 122 152 if child_acc is None: continue 123 153 child = AccDecorator(child_acc) 124 child.is_group = self.isActionGroup(child) 125 if child.isInteractive() or child.is_group: 154 child.is_group = self._isActionGroup(child) 155 child.is_interactive = child.isInteractive() 156 if child.is_interactive or child.is_group: 126 157 self.items.append(child) 158 print '%s %s%s ' % (child._acc, ('i' if child.is_interactive else ''), 159 ('g' if child.is_group else '')) 127 160 else: 128 161 self._populateChildren(child_acc) … … 143 176 ', '.join((str_item(item) for item in self.items))) 144 177 145 def isActionGroup(self, acc): 178 def _isActionGroup(self, acc): 179 role = acc.getRole() 146 180 if not acc.hasStates(pyatspi.STATE_SHOWING) \ 147 or acc.getRole()== pyatspi.ROLE_MENU:181 or role == pyatspi.ROLE_MENU: 148 182 return False 149 if acc.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:183 if role in (pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_FRAME): 150 184 return True 151 if acc.getRole()== pyatspi.ROLE_FRAME:152 app = acc.getApplication()153 if app.childCount == 1:185 #if role == pyatspi.ROLE_FRAME: 186 #app = acc.getApplication() 187 #if app.childCount == 1: 154 188 # Top level frames of single framed apps can't be groups 155 return False189 #return False 156 190 if acc.childCount == 1: 157 191 # A container with one interactive child can't be a group 158 return False192 return role == pyatspi.ROLE_PAGE_TAB 159 193 # needs interactive (grand)children 160 194 for child in acc: … … 177 211 self.root = root_acc 178 212 213 def addSubTree(self, acc, parent=None): 214 root = None 215 iter = self.append(root, 216 [acc.name, acc.getRoleName(), acc, False, False]) 217 print self.get_path(iter) 218 self.popLevel(iter) 219 179 220 def popLevel(self, iter): 180 221 t = time() … … 203 244 [acc.name, acc.getRoleName(), acc, False, False]) 204 245 205 if not acc.isInteractive(): 246 #print self.get_path(iter) 247 if acc.is_group: 206 248 self.makeExpandable(iter) 207 249
