1 #Copyright (C) 2008 Codethink Ltd
3 #This library is free software; you can redistribute it and/or
4 #modify it under the terms of the GNU Lesser General Public
5 #License version 2 as published by the Free Software Foundation.
7 #This program is distributed in the hope that it will be useful,
8 #but WITHOUT ANY WARRANTY; without even the implied warranty of
9 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 #GNU General Public License for more details.
11 #You should have received a copy of the GNU Lesser General Public License
12 #along with this program; if not, write to the Free Software
13 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 from factory import create_accessible, add_accessible_class
17 from accessible import BoundingBox
24 #------------------------------------------------------------------------------
28 Wraps the AT-SPI event type string so its components can be accessed
29 individually as klass (can't use the keyword class), major, minor, and detail
30 (klass_major_minor_detail).
32 @note: All attributes of an instance of this class should be considered
33 public readable as it is acting a a struct.
34 @ivar klass: Most general event type identifier (object, window, mouse, etc.)
36 @ivar major: Second level event type description
38 @ivar minor: Third level event type description
40 @ivar detail: Lowest level event type description
42 @ivar name: Full, unparsed event name as received from AT-SPI
44 @cvar format: Names of the event string components
45 @type format: 4-tuple of string
47 format = ('klass', 'major', 'minor', 'detail')
49 def __init__(self, name):
51 Parses the full AT-SPI event name into its components
52 (klass:major:minor:detail). If the provided event name is an integer
53 instead of a string, then the event is really a device event.
55 @param name: Full AT-SPI event name
57 @raise AttributeError: When the given event name is not a valid string
59 # get rid of any leading and trailing '_' separators
60 self.value = name.strip('_')
61 self.name = self.value # Backward compatability
67 # split type according to delimiters
68 split = self.value.split('_', 3)
69 # loop over all the components
70 for i in xrange(len(split)):
71 # store values of attributes in this object
72 setattr(self, self.format[i], split[i])
74 #------------------------------------------------------------------------------
78 Wraps an AT-SPI event with a more Pythonic interface managing exceptions,
79 the differences in any_data across versions, and the reference counting of
80 accessibles provided with the event.
82 @note: All unmarked attributes of this class should be considered public
83 readable and writable as the class is acting as a record object.
85 @ivar type: The type of the AT-SPI event
86 @type type: L{EventType}
87 @ivar detail1: First AT-SPI event parameter
88 @type detail1: integer
89 @ivar detail2: Second AT-SPI event parameter
90 @type detail2: integer
91 @ivar any_data: Extra AT-SPI data payload
92 @type any_data: object
93 @ivar host_application: Application owning the event source
94 @type host_application: Accessibility.Application
95 @ivar source_name: Name of the event source at the time of event dispatch
96 @type source_name: string
97 @ivar source_role: Role of the event source at the time of event dispatch
98 @type source_role: Accessibility.Role
99 @ivar source: Source of the event
100 @type source: Accessibility.Accessible
102 def __init__(self, cache, source_path, source_application, name, event):
104 Extracts information from the provided event. If the event is a "normal"
105 event, pulls the detail1, detail2, any_data, and source values out of the
106 given object and stores it in this object. If the event is a device event,
107 key ID is stored in detail1, scan code is stored in detail2, key name,
108 key modifiers (e.g. ALT, CTRL, etc.), is text flag, and timestamp are
109 stored as a 4-tuple in any_data, and source is None (since key events are
112 @param event: Event from an AT-SPI callback
113 @type event: Accessibility.Event or Accessibility.DeviceEvent
116 self._source_path = source_path
117 self._source_application = source_application
119 self._application = None
121 self._detail = event[0]
122 self.type = EventType(name + '_' + self._detail)
123 self.detail1 = event[1]
124 self.detail2 = event[2]
127 if name == "object_bounds_changed":
128 self.any_data = BoundingBox(*data)
133 def host_application(self):
134 if not self._application:
135 application_root = self._cache[self._source_application]._get_root()
136 return create_accessible(self._cache,
137 self._source_application,
139 interfaces.ATSPI_APPLICATION,
140 connection=self._cache._connection)
141 return self._application
146 self._source = create_accessible(self._cache,
147 self._source_application,
149 interfaces.ATSPI_ACCESSIBLE,
150 connection=self._cache._connection)
154 def source_name(self):
158 def source_role(self):
159 return source.getRole()
163 Builds a human readable representation of the event including event type,
164 parameters, and source info.
166 @return: Event description
169 return '%s(%s, %s, %s)\n\tsource: %s\n\thost_application: %s' % \
170 (self.type, self.detail1, self.detail2, self.any_data,
171 self.source, self.host_application)
173 #END----------------------------------------------------------------------------