2008-08-20 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/upstream/at-spi2-core.git] / pyatspi / state.py
1 #Copyright (C) 2008 Codethink Ltd
2 #copyright: Copyright (c) 2005, 2007 IBM Corporation
3
4 #This library is free software; you can redistribute it and/or
5 #modify it under the terms of the GNU Lesser General Public
6 #License version 2 as published by the Free Software Foundation.
7
8 #This program is distributed in the hope that it will be useful,
9 #but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #GNU General Public License for more details.
12 #You should have received a copy of the GNU Lesser General Public License
13 #along with this program; if not, write to the Free Software
14 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15
16 #Portions of this code originally licensed and copyright (c) 2005, 2007
17 #IBM Corporation under the BSD license, available at
18 #U{http://www.opensource.org/licenses/bsd-license.php}
19
20 #authors: Peter Parente, Mark Doffman
21
22 from base import Enum as _Enum
23
24 #------------------------------------------------------------------------------
25
26 class StateType(_Enum):
27     _enum_lookup = {
28         0:'STATE_INVALID',
29         1:'STATE_ACTIVE',
30         2:'STATE_ARMED',
31         3:'STATE_BUSY',
32         4:'STATE_CHECKED',
33         5:'STATE_COLLAPSED',
34         6:'STATE_DEFUNCT',
35         7:'STATE_EDITABLE',
36         8:'STATE_ENABLED',
37         9:'STATE_EXPANDABLE',
38         10:'STATE_EXPANDED',
39         11:'STATE_FOCUSABLE',
40         12:'STATE_FOCUSED',
41         13:'STATE_HAS_TOOLTIP',
42         14:'STATE_HORIZONTAL',
43         15:'STATE_ICONIFIED',
44         16:'STATE_MODAL',
45         17:'STATE_MULTI_LINE',
46         18:'STATE_MULTISELECTABLE',
47         19:'STATE_OPAQUE',
48         20:'STATE_PRESSED',
49         21:'STATE_RESIZABLE',
50         22:'STATE_SELECTABLE',
51         23:'STATE_SELECTED',
52         24:'STATE_SENSITIVE',
53         25:'STATE_SHOWING',
54         26:'STATE_SINGLE_LINE',
55         27:'STATE_STALE',
56         28:'STATE_TRANSIENT',
57         29:'STATE_VERTICAL',
58         30:'STATE_VISIBLE',
59         31:'STATE_MANAGES_DESCENDANTS',
60         32:'STATE_INDETERMINATE',
61         33:'STATE_REQUIRED',
62         34:'STATE_TRUNCATED',
63         35:'STATE_ANIMATED',
64         36:'STATE_INVALID_ENTRY',
65         37:'STATE_SUPPORTS_AUTOCOMPLETION',
66         38:'STATE_SELECTABLE_TEXT',
67         39:'STATE_IS_DEFAULT',
68         40:'STATE_VISITED',
69         41:'STATE_LAST_DEFINED',
70     }
71
72 #------------------------------------------------------------------------------
73
74 STATE_ACTIVE = StateType(1)
75 STATE_ANIMATED = StateType(35)
76 STATE_ARMED = StateType(2)
77 STATE_BUSY = StateType(3)
78 STATE_CHECKED = StateType(4)
79 STATE_COLLAPSED = StateType(5)
80 STATE_DEFUNCT = StateType(6)
81 STATE_EDITABLE = StateType(7)
82 STATE_ENABLED = StateType(8)
83 STATE_EXPANDABLE = StateType(9)
84 STATE_EXPANDED = StateType(10)
85 STATE_FOCUSABLE = StateType(11)
86 STATE_FOCUSED = StateType(12)
87 STATE_HAS_TOOLTIP = StateType(13)
88 STATE_HORIZONTAL = StateType(14)
89 STATE_ICONIFIED = StateType(15)
90 STATE_INDETERMINATE = StateType(32)
91 STATE_INVALID = StateType(0)
92 STATE_INVALID_ENTRY = StateType(36)
93 STATE_IS_DEFAULT = StateType(39)
94 STATE_LAST_DEFINED = StateType(41)
95 STATE_MANAGES_DESCENDANTS = StateType(31)
96 STATE_MODAL = StateType(16)
97 STATE_MULTISELECTABLE = StateType(18)
98 STATE_MULTI_LINE = StateType(17)
99 STATE_OPAQUE = StateType(19)
100 STATE_PRESSED = StateType(20)
101 STATE_REQUIRED = StateType(33)
102 STATE_RESIZABLE = StateType(21)
103 STATE_SELECTABLE = StateType(22)
104 STATE_SELECTABLE_TEXT = StateType(38)
105 STATE_SELECTED = StateType(23)
106 STATE_SENSITIVE = StateType(24)
107 STATE_SHOWING = StateType(25)
108 STATE_SINGLE_LINE = StateType(26)
109 STATE_STALE = StateType(27)
110 STATE_SUPPORTS_AUTOCOMPLETION = StateType(37)
111 STATE_TRANSIENT = StateType(28)
112 STATE_TRUNCATED = StateType(34)
113 STATE_VERTICAL = StateType(29)
114 STATE_VISIBLE = StateType(30)
115 STATE_VISITED = StateType(40)
116
117 #------------------------------------------------------------------------------
118
119 # Build a dictionary mapping state values to names based on the prefix of the enum constants.
120
121 STATE_VALUE_TO_NAME = dict(((value, name[6:].lower().replace('_', ' ')) 
122                             for name, value 
123                             in globals().items()
124                             if name.startswith('STATE_')))
125
126 #------------------------------------------------------------------------------
127
128 def _marshal_state_set(bitfield):
129         """
130         The D-Bus protocol has a stateset object passed
131         as a 64bit bitfield. The Bits are passed as two 32bit
132         integers.
133
134         This function marshals the D-Bus message into a 
135         StateSet object that corresponds to these states.
136         """
137         (lower, upper) = bitfield
138
139         states = []
140
141         pos = 0
142         while (lower):
143                 if (1L)&lower:
144                         #TODO Return the state objects rather than integers.
145                         states.append(pos)
146                 pos+=1
147         while (upper):
148                 if (1L)&upper:
149                         #TODO return the state objects rather than integers.
150                         states.append(pos)
151
152         return StateSet(*states)
153
154 #------------------------------------------------------------------------------
155
156 class StateSet(object):
157         """
158         The StateSet object implements a wrapper around a
159         bitmap of Accessible states.
160
161         The StateSet object is the instantaneous state of
162         the Accessible object and is not updated with its
163         container Accessible. This behaviour is different
164         to the CORBA version of AT-SPI
165         """
166         def __init__(self, *states):
167                 """
168                 Initializes the state set with the given states.
169
170                 @param states: States to add immediately
171                 @type states: list
172                 """
173                 map(self.add, states)
174                 self.states = set()
175                 
176         def contains(self, state):
177                 """
178                 Checks if this StateSet contains the given state.
179                 
180                 @param state: State to check
181                 @type state: Accessibility.StateType
182                 @return: True if the set contains the given state
183                 @rtype: boolean
184                 """
185                 return state in self.states
186         
187         def add(self, *states):
188                 """
189                 Adds states to this set.
190                 
191                 @param states: State(s) to add
192                 @type states: Accessibility.StateType
193                 """
194                 self.states.add(state)
195                 
196         def remove(self, state):
197                 """
198                 Removes states from this set.
199                 
200                 @param states: State(s) to remove
201                 @type states: Accessibility.StateType
202                 """
203                 self.states.remove(state)
204         
205         def equals(self, state_set):
206                 """
207                 Checks if this StateSet contains exactly the same members as the given
208                 StateSet.
209                 
210                 @param state_set: Another set
211                 @type state_set: Accessibility.StateSet
212                 @return: Are the sets equivalent in terms of their contents?
213                 @rtype: boolean
214                 """
215                 return set(state_set.getStates()) == self.states
216         
217         def compare(self, state_set):
218                 """
219                 Finds the symmetric difference between this state set andthe one provided,
220                 and returns it as a new StateSet.
221
222                 @note: This does not use L{_StateSetImpl.compare} which cannot be
223                 implemented at this time
224                 @param state_set: Set to compare against
225                 @type state_set: Accessibility.StateSet
226                 @return: Proxy for the new set
227                 @rtype: L{StateSet}
228                 """
229                 a = set(self.getStates())
230                 b = set(state_set.getStates())
231                 diff = a.symmetric_difference(b)
232                 return StateSet(*diff)
233         
234         def isEmpty(self):
235                 """
236                 Checks if this StateSet is empty.
237                 
238                 @return: Is it empty?
239                 @rtype: boolean
240                 """
241                 return len(self.states) == 0
242
243         def getStates(self):
244                 """
245                 Gets the sequence of all states in this set.
246                 
247                 @return: List of states
248                 @rtype: list
249                 """
250                 return list(self.states)
251
252 #END----------------------------------------------------------------------------