Initial pass at adding i18n and proper object disposal
[platform/upstream/at-spi2-core.git] / atspi / atspi-stateset.c
1 #include "atspi-private.h"
2
3 static void atspi_state_set_class_init (AtspiStateSetClass *klass);
4
5 G_DEFINE_TYPE (AtspiStateSet, atspi_state_set, G_TYPE_OBJECT)
6
7 static const char *state_names [] =
8 {
9   "invalid",
10   "active",
11   "armed",
12   "busy",
13   "checked",
14   "collapsed",
15   "defunct",
16   "editable",
17   "enabled",
18   "expandable",
19   "expanded",
20   "focusable",
21   "focused",
22   "has-tool-tip",
23   "horizontal",
24   "iconified",
25   "modal",
26   "multi-line",
27   "multiselectable",
28   "opaque",
29   "pressed",
30   "resizable",
31   "selectable",
32   "selected",
33   "sensitive",
34   "showing",
35   "singleLine",
36   "stale",
37   "transient",
38   "vertical",
39   "visible",
40   "manages-descendants",
41   "indeterminate",
42   "required",
43   "truncated",
44   "animated",
45   "invalid-entry",
46   "supports-autocompletion",
47   "selectable-text",
48   "is-default",
49   "visited",
50   NULL
51 };
52
53 static void
54 atspi_state_set_init (AtspiStateSet *set)
55 {
56   set->states = 0;
57 }
58
59 static void
60 atspi_state_set_class_init (AtspiStateSetClass* klass)
61 {
62 }
63
64 /*
65  * atspi_state_set_new:
66  *
67  * @states: (element-type AtspiStateType): An array of states with which to initialize
68  * the state set.
69  *
70  * Returns: A new #AtspiStateSet with the given states.
71  **/
72 AtspiStateSet *
73 atspi_state_set_new (GArray *states)
74 {
75   AtspiStateSet *set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
76   gint i;
77
78   if (!set || !states)
79     return set;
80
81   for (i = 0; i < states->len; i++)
82     atspi_state_set_add (set, g_array_index (states, AtspiStateType, i));
83   return set;
84 }
85
86 AtspiStateSet *
87 _atspi_state_set_new_internal (AtspiAccessible *accessible, gint64 states)
88 {
89   AtspiStateSet *set;
90   
91   set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
92   g_return_val_if_fail (set != NULL, NULL);
93
94   set->accessible = accessible;
95   set->states = states;
96   return set;
97 }
98
99 void
100 atspi_state_set_set_by_name (AtspiStateSet *set, const gchar *name, gboolean enabled)
101 {
102   gint i = 0;
103
104   if (set->accessible &&
105       !(set->accessible->cached_properties & ATSPI_CACHE_STATES))
106     return;
107
108   /* TODO: This could perhaps be optimized */
109   for (i = 0; state_names [i]; i++)
110   {
111     if (!strcmp (state_names [i], name))
112     {
113       if (enabled)
114         set->states |= (1 << i);
115       else
116         set->states &= ~(1 << i);
117       return;
118     }
119   }
120   g_warning ("at-spi: Attempt to set unknown state '%s'", name);
121 }
122
123 static void
124 refresh_states (AtspiStateSet *set)
125 {
126   GArray *state_array;
127   dbus_uint32_t *states;
128
129   if (!set->accessible ||
130       (set->accessible->cached_properties & ATSPI_CACHE_STATES))
131     return;
132
133   if (!_atspi_dbus_call (set->accessible, atspi_interface_accessible, "GetState", NULL, "=>au", &state_array))
134     return;
135
136   states = (dbus_uint32_t *) state_array->data;
137
138   set->states = ((gint64)states [1]) << 32;
139   set->states += states [0];
140   g_array_free (state_array, TRUE);
141 }
142
143 /**
144  * atspi_state_set_add:
145  *
146  * @set: a pointer to the #AtspiStateSet object on which to operate.
147  * @state: an #AtspiStateType to be added to the specified #AtspiStateSet.
148  *
149  * Add a particular #AtspiState to an #AtspiStateSet (i.e. set the
150  *       given state to #TRUE in the stateset.
151  *
152  **/
153 void
154 atspi_state_set_add (AtspiStateSet *set, AtspiStateType state)
155 {
156   g_return_if_fail (set != NULL);
157   set->states |= (((gint64)1) << state);
158 }
159
160 /**
161  * atspi_state_set_compare:
162  * @set: a pointer to the first #AtspiStateSet object on which to operate.
163  * @set: a pointer to the second #AtspiStateSet setect on which to operate.
164  *
165  * Determine the differences between two instances of #AtspiStateSet.
166  *.
167  * @see AtspiStateSet_equals().
168  *
169  * Returns: (transfer full): an #AtspiStateSet object containing all states
170  *          contained on one of the two sets but not the other.
171  *
172  **/
173 AtspiStateSet *
174 atspi_state_set_compare (AtspiStateSet *set,
175                          AtspiStateSet *set2)
176 {
177   g_return_val_if_fail (set != NULL, NULL);
178   g_return_val_if_fail (set2 != NULL, NULL);
179
180   return _atspi_state_set_new_internal (NULL, set->states ^ set2->states);
181 }
182
183 /**
184  * atspi_state_set_contains:
185  * @set: a pointer to the #AtspiStateSet object on which to operate.
186  * @state: an #AtspiStateType for which the specified #AtspiStateSet
187  *       will be queried.
188  *
189  * Determine whether a given #AtspiStateSet includes a given state; that is,
190  *       whether @state is true for the stateset in question.
191  *
192  * Returns: #TRUE if @state is true/included in the given #AtspiStateSet,
193  *          otherwise #FALSE.
194  *
195  **/
196 gboolean
197 atspi_state_set_contains (AtspiStateSet *set,
198                              AtspiStateType state)
199 {
200   if (!set)
201     return FALSE;
202   refresh_states (set);
203   return (set->states & (1 << state)) ? TRUE : FALSE;
204 }
205
206 /**
207  * atspi_state_set_equals:
208  * @set: a pointer to the first #AtspiStateSet object on which to operate.
209  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
210  *
211  * Determine whether two instances of #AtspiStateSet are equivalent (i.e.
212  *         consist of the same #AtspiStates).  Useful for checking multiple
213  *         state variables at once; construct the target state then compare against it.
214  *
215  * @see AtspiStateSet_compare().
216  *
217  * Returns: #TRUE if the two #AtspiStateSets are equivalent,
218  *          otherwise #FALSE.
219  *
220  **/
221 gboolean
222 atspi_state_set_equals (AtspiStateSet *set,
223                            AtspiStateSet *set2)
224 {
225   if (set == set2)
226     return TRUE;
227   if (set == NULL || set2 == NULL)
228     return FALSE;
229   return (set->states == set2->states);
230 }
231
232 /**
233  * atspi_state_set_get_states:
234  *
235  * @set: The #AtspiStateSet to be queried.
236  *
237  * Return the states in an #AtspiStateSet as an array.
238  *
239  * Returns: (element-type AtspiStateType) (transfer full): A #GArray of state
240  *          types representing the current state.
241  **/
242 GArray *
243 atspi_state_set_get_states (AtspiStateSet *set)
244 {
245   gint i = 0;
246   guint64 val = 1;
247   GArray *ret;
248
249   g_return_val_if_fail (set != NULL, NULL);
250   refresh_states (set);
251   ret = g_array_new (TRUE, TRUE, sizeof (AtspiStateType));
252   if (!ret)
253     return NULL;
254   for (i = 0; i < 64; i++)
255   {
256     if (set->states & val)
257     {
258       GArray *new_array = g_array_append_val (ret, i);
259       if (new_array)
260         ret = new_array;
261     }
262     val <<= 1;
263   }
264   return ret;
265 }
266
267 /**
268  * atspi_state_set_is_empty:
269  *
270  * @set: The #AtspiStateSet to query.
271  *
272  * Returns: #TRUE if the state set contains no states; #FALSE otherwise.
273  **/
274 gboolean
275 atspi_state_set_is_empty (AtspiStateSet *set)
276 {
277   return (set->states == 0);
278 }
279
280 /**
281  * atspi_state_set_remove:
282  *
283  * @set: a pointer to the #AtspiStateSet object on which to operate.
284  * @state: an #AtspiStateType to remove from the specifiedn state set.
285  *
286  * Remove a particular #AtspiState to an #AtspiStateSet (i.e. set the
287  *       given state to #FALSE in the stateset.)
288  *
289  **/
290 void
291 atspi_state_set_remove (AtspiStateSet *set, AtspiStateType state)
292 {
293   g_return_if_fail (set != NULL);
294   set->states &= ~(1 << state);
295 }
296