1'''
2AT-SPI API browser plugin.
3
4@author: Eitan Isaacson
5@organization: IBM Corporation
6@copyright: Copyright (c) 2007 IBM Corporation
7@license: BSD
8
9All rights reserved. This program and the accompanying materials are made
10available under the terms of the BSD which accompanies this distribution, and
11is available at U{http://www.opensource.org/licenses/bsd-license.php}
12'''
13from gi.repository import Gtk as gtk
14from accerciser.plugin import ViewportPlugin
15from accerciser.i18n import _, N_
16import pyatspi
17
18class APIBrowser(ViewportPlugin):
19  '''
20  Plugin class for API Browser.
21
22  @ivar iface_combo: Combobox that shows available interfaces.
23  @type iface_combo: gtk.ComboBox
24  @ivar method_tree: Tree view with available methods from chosen interface.
25  @type method_tree: gtk.TreeView
26  @ivar property_tree: Tree view with available properties from chosen
27  interface.
28  @type property_tree: gtk.TreeView
29  @ivar private_toggle: Toggles visibility of private attributes.
30  @type private_toggle: gtk.CheckButton
31  '''
32  plugin_name = N_('API Browser')
33  plugin_name_localized = _(plugin_name)
34  plugin_description = \
35      N_('Browse the various methods of the current accessible')
36  def init(self):
37    '''
38    Initialize the API browser plugin.
39    '''
40    self._buildUI()
41    self._initTreeViews()
42    self.iface_combo.connect('changed', self._refreshAttribs)
43    self.private_toggle.connect('toggled', self._refreshAttribs)
44    self.curr_iface = None
45
46  def _buildUI(self):
47    '''
48    Manually build the plugin's UI.
49    '''
50    vbox = gtk.VBox()
51    self.plugin_area.add(vbox)
52    top_hbox = gtk.HBox()
53    bottom_hbox = gtk.HBox()
54    vbox.pack_start(top_hbox, False, True, 0)
55    vbox.pack_start(bottom_hbox, True, True, 0)
56    self.method_tree = gtk.TreeView()
57    scrolled_window = gtk.ScrolledWindow()
58    scrolled_window.add(self.method_tree)
59    bottom_hbox.pack_start(scrolled_window, True, True, 0)
60    self.property_tree = gtk.TreeView()
61    scrolled_window = gtk.ScrolledWindow()
62    scrolled_window.add(self.property_tree)
63    bottom_hbox.pack_start(scrolled_window, True, True, 0)
64    self.iface_combo = gtk.ComboBoxText.new()
65    top_hbox.pack_start(self.iface_combo, False, True, 0)
66    self.private_toggle = gtk.CheckButton.new_with_label(_('Hide private attributes'))
67    self.private_toggle.set_active(True)
68    top_hbox.pack_end(self.private_toggle, False, True, 0)
69    self.show_all()
70
71  def _initTreeViews(self):
72    '''
73    Initialize the properties and methods tree views and models.
74    '''
75    # method view
76    model = gtk.ListStore(str, str)
77    self.method_tree.set_model(model)
78    crt = gtk.CellRendererText()
79    tvc = gtk.TreeViewColumn(_('Method'))
80    tvc.pack_start(crt, True)
81    tvc.add_attribute(crt, 'text', 0)
82    self.method_tree.append_column(tvc)
83
84    # property view
85    model = gtk.ListStore(str, str)
86    self.property_tree.set_model(model)
87    crt = gtk.CellRendererText()
88    tvc = gtk.TreeViewColumn(_('Property'))
89    tvc.pack_start(crt, True)
90    tvc.add_attribute(crt, 'text', 0)
91    self.property_tree.append_column(tvc)
92    crt = gtk.CellRendererText()
93    tvc = gtk.TreeViewColumn(_('Value'))
94    tvc.pack_start(crt, True)
95    tvc.add_attribute(crt, 'text', 1)
96    self.property_tree.append_column(tvc)
97
98  def onAccChanged(self, acc):
99    '''
100    Update the UI when the selected accessible changes.
101
102    @param acc: The applications-wide selected accessible.
103    @type acc: Accessibility.Accessible
104    '''
105    self.acc = acc
106    ints = pyatspi.listInterfaces(acc)
107    model = self.iface_combo.get_model()
108    model.clear()
109    for iface in ints:
110      self.iface_combo.append_text(iface)
111    self.iface_combo.set_active(0)
112
113  def _refreshAttribs(self, widget):
114    '''
115    Refresh the attributes in the tree views. Could be used as a callback.
116
117    @param widget: The widget that may have triggered this callback.
118    @type widget: gtk.Widget
119    '''
120    iface = self.iface_combo.get_active_text()
121
122    try:
123      query_func = getattr(self.acc, 'query%s' % iface)
124    except AttributeError:
125      pass
126    else:
127      self.curr_iface = query_func()
128      self._popAttribViews()
129
130  def _popAttribViews(self):
131    '''
132    Populate the attribute views with information from currently selected
133    accessible and interface.
134    '''
135    prop_model = self.property_tree.get_model()
136    method_model = self.method_tree.get_model()
137    prop_model.clear()
138    method_model.clear()
139    for attr in dir(self.curr_iface):
140      if self.private_toggle.get_active() and attr[0] == '_':
141        continue
142      try:
143        obj = getattr(self.curr_iface, attr)
144      except AttributeError:
145        # Slots seem to raise AttributeError if they were not assigned.
146        continue
147      if callable(obj):
148        method_model.append([attr, obj.__doc__])
149      else:
150        prop_model.append([attr, str(obj)])
151