2008-07-28 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / pyatspi / stateset.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 class _StateSetImpl(Accessibility__POA.StateSet):
23         """
24         Implementation of the StateSet interface. Clients should not use this class
25         directly, but rather the L{StateSet} proxy class.
26         
27         @param states: Set of states
28         @type states: set
29         """
30         def __init__(self):
31                 """Initializes the state set."""
32                 self.states = set()
33                 
34         def contains(self, state):
35                 """
36                 Checks if this StateSet contains the given state.
37                 
38                 @param state: State to check
39                 @type state: Accessibility.StateType
40                 @return: True if the set contains the given state
41                 @rtype: boolean
42                 """
43                 return state in self.states
44         
45         def add(self, state):
46                 """
47                 Adds a state to this set.
48                 
49                 @param state: State to add
50                 @type state: Accessibility.StateType
51                 """
52                 self.states.add(state)
53         
54         def remove(self, state):
55                 """
56                 Removes a state from this set.
57                 
58                 @param state: State to remove
59                 @type state: Accessibility.StateType
60                 """
61                 self.states.remove(state)
62         
63         def equals(self, state_set):
64                 """
65                 Checks if this StateSet contains exactly the same members as the given
66                 StateSet.
67                 
68                 @param state_set: Another set
69                 @type state_set: Accessibility.StateSet
70                 @return: Are the sets equivalent in terms of their contents?
71                 @rtype: boolean
72                 """
73                 # don't check private members, object might be from another process
74                 # or implementation
75                 return set(state_set.getStates()) == self.states
76         
77         def compare(self, state_set):
78                 """
79                 Computes the symmetric differences of this L{StateSet} and the given
80                 L{StateSet}.
81
82                 @note: This method is not currently implemented because of difficulties
83                 with reference counting. This method needs to return a new
84                 Accessibility.StateSet object, but the Python implementation for that
85                 object needs to be kept alive. The problem is who will keep that
86                 server implementation alive? As soon as it goes out of scope, it's
87                 GC'ed. This object cannot keep it alive either as it may go out of
88                 scope before the new object is ready to be finalized. With a global
89                 cache of objects, we don't know when to invalidate.
90                 
91                 @param state_set: Another set
92                 @type state_set: Accessibility.StateSet
93                 @return: Elements in only one of the two sets
94                 @rtype: Accessibility.StateSet
95                 """
96                 raise ORBit.CORBA.NO_IMPLEMENT
97                 
98                 # don't check private members, object might be from another process
99                 # or implementation
100                 #states = set(state_set.getStates())
101                 #diff = self.states.symmetric_difference(states)
102                 #new_ss = _StateSetImpl()
103                 #map(new_ss._this().add, diff)
104                 #return new_ss._this()
105         
106         def isEmpty(self):
107                 """
108                 Checks if this L{StateSet} is empty.
109                 
110                 @return: Is it empty?
111                 @rtype: boolean
112                 """
113                 return len(self.states) == 0
114
115         def getStates(self):
116                 """
117                 Gets the sequence of all states in this set.
118                 
119                 @return: List of states
120                 @rtype: list
121                 """
122                 return list(self.states)
123
124 class StateSet(object):
125         """
126         Python proxy for the L{_StateSetImpl} class. Use this to safely instantiate
127         new StateSet objects in Python.
128
129         @param impl: State set implementation
130         @type impl: L{_StateSetImpl}
131         """
132         def __init__(self, *states):
133                 """
134                 Initializes the state set with the given states.
135
136                 @param states: States to add immediately
137                 @type states: list
138                 """
139                 self.impl = _StateSetImpl()
140                 map(self.impl._this().add, states)
141                 
142         def contains(self, state):
143                 """
144                 Checks if this StateSet contains the given state.
145                 
146                 @param state: State to check
147                 @type state: Accessibility.StateType
148                 @return: True if the set contains the given state
149                 @rtype: boolean
150                 """
151                 return self.impl._this().contains(state)
152         
153         def add(self, *states):
154                 """
155                 Adds states to this set.
156                 
157                 @param states: State(s) to add
158                 @type states: Accessibility.StateType
159                 """
160                 map(self.impl._this().add, states)
161                 
162         def remove(self, state):
163                 """
164                 Removes states from this set.
165                 
166                 @param states: State(s) to remove
167                 @type states: Accessibility.StateType
168                 """
169                 map(self.impl._this().remove, state)
170         
171         def equals(self, state_set):
172                 """
173                 Checks if this StateSet contains exactly the same members as the given
174                 StateSet.
175                 
176                 @param state_set: Another set
177                 @type state_set: Accessibility.StateSet
178                 @return: Are the sets equivalent in terms of their contents?
179                 @rtype: boolean
180                 """
181                 if isinstance(state_set, self.__class__):
182                         # convenience if we're given a proxy
183                         state_set = state_set.raw()
184                 return self.impl._this().equals(state_set)
185         
186         def compare(self, state_set):
187                 """
188                 Finds the symmetric difference between this state set andthe one provided,
189                 and returns it as a new StateSet.
190
191                 @note: This does not use L{_StateSetImpl.compare} which cannot be
192                 implemented at this time
193                 @param state_set: Set to compare against
194                 @type state_set: Accessibility.StateSet
195                 @return: Proxy for the new set
196                 @rtype: L{StateSet}
197                 """
198                 if isinstance(state_set, self.__class__):
199                         # shortcut if it's another one of our proxies
200                         state_set = state_set.raw()
201                 a = set(self.impl._this().getStates())
202                 b = set(state_set.getStates())
203                 diff = a.symmetric_difference(b)
204                 return StateSet(*diff)
205         
206         def isEmpty(self):
207                 """
208                 Checks if this StateSet is empty.
209                 
210                 @return: Is it empty?
211                 @rtype: boolean
212                 """
213                 return self.impl._this().isEmpty()
214
215         def getStates(self):
216                 """
217                 Gets the sequence of all states in this set.
218                 
219                 @return: List of states
220                 @rtype: list
221                 """
222                 return self.impl._this().getStates()
223
224         def raw(self):
225                 """
226                 Gets the Accessibility.StateSet object proxied for use in a remote
227                 call.
228
229                 @return: State set
230                 @rtype: Accessibility.StateSet
231                 """
232                 return self.impl._this()