1
/*
2
 * AT-SPI - Assistive Technology Service Provider Interface
3
 * (Gnome Accessibility Project; https://wiki.gnome.org/Accessibility)
4
 *
5
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the
19
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
 * Boston, MA 02110-1301, USA.
21
 */
22

            
23
#include <atk/atk.h>
24
#include <stdio.h>
25
#include <string.h>
26

            
27
#include "my-atk-object.h"
28
#include "my-atk-selection.h"
29

            
30
static void atk_selection_interface_init (AtkSelectionIface *iface);
31

            
32
9
G_DEFINE_TYPE_WITH_CODE (MyAtkSelection,
33
                         my_atk_selection,
34
                         MY_TYPE_ATK_OBJECT,
35
                         G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION,
36
                                                atk_selection_interface_init));
37

            
38
static void
39
9
my_atk_selection_init (MyAtkSelection *obj)
40
{
41
9
}
42

            
43
static gboolean
44
6
my_atk_selection_add_selection (AtkSelection *selection, gint i)
45
{
46
6
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
47
6
  if (!self)
48
    return FALSE;
49

            
50
6
  AtkObject *child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
51
6
  AtkStateSet *ss = atk_object_ref_state_set (child);
52
6
  atk_state_set_add_state (ss, ATK_STATE_SELECTED);
53
6
  return atk_state_set_contains_state (ss, ATK_STATE_SELECTED);
54
}
55

            
56
static gboolean
57
1
my_atk_selection_clear_selection (AtkSelection *selection)
58
{
59
1
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
60
1
  if (!self)
61
    return FALSE;
62
1
  AtkObject *child = NULL;
63
1
  AtkStateSet *states = NULL;
64
  int i;
65
1
  int childs = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
66

            
67
6
  for (i = 0; i < childs; i++)
68
    {
69
5
      child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
70
5
      states = atk_object_ref_state_set (child);
71
5
      atk_state_set_remove_state (states, ATK_STATE_SELECTED);
72
    }
73
1
  return TRUE;
74
}
75

            
76
static AtkObject *
77
6
my_atk_selection_ref_selection (AtkSelection *selection, gint no)
78
{
79
6
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
80
6
  if (!self)
81
    return FALSE;
82
6
  AtkObject *child = NULL;
83
6
  AtkStateSet *states = NULL;
84
6
  GArray *array = g_array_new (FALSE, FALSE, sizeof (AtkObject *));
85
  int i;
86
6
  int childs = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
87

            
88
36
  for (i = 0; i < childs; i++)
89
    {
90
30
      child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
91
30
      states = atk_object_ref_state_set (child);
92
30
      if (atk_state_set_contains_state (states, ATK_STATE_SELECTED))
93
24
        g_array_append_val (array, child);
94
    }
95

            
96
6
  return g_array_index (array, AtkObject *, no);
97
}
98

            
99
static gint
100
15
my_atk_selection_get_selection_count (AtkSelection *selection)
101
{
102
15
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
103
15
  if (!self)
104
    return FALSE;
105
15
  AtkObject *child = NULL;
106
15
  AtkStateSet *states = NULL;
107
15
  int i, ret = 0;
108
15
  int childs = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
109

            
110
90
  for (i = 0; i < childs; i++)
111
    {
112
75
      child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
113
75
      states = atk_object_ref_state_set (child);
114
75
      if (atk_state_set_contains_state (states, ATK_STATE_SELECTED))
115
54
        ret++;
116
    }
117
15
  return ret;
118
}
119

            
120
static gboolean
121
5
my_atk_selection_is_child_selected (AtkSelection *selection, gint i)
122
{
123
5
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
124
5
  if (!self)
125
    return FALSE;
126
5
  AtkObject *child = NULL;
127
5
  AtkStateSet *states = NULL;
128
5
  child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
129
5
  states = atk_object_ref_state_set (child);
130
5
  if (atk_state_set_contains_state (states, ATK_STATE_SELECTED))
131
3
    return TRUE;
132
2
  return FALSE;
133
}
134

            
135
static gboolean
136
2
my_atk_selection_remove_selection (AtkSelection *selection, gint no)
137
{
138
2
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
139
2
  AtkObject *child = NULL;
140
2
  AtkStateSet *states = NULL;
141
2
  GArray *array = NULL;
142
2
  AtkObject *o = NULL;
143
  int i;
144
  int childs;
145
2
  gboolean ret = FALSE;
146

            
147
2
  if (!self)
148
    return FALSE;
149
2
  array = g_array_new (FALSE, FALSE, sizeof (AtkObject *));
150
2
  childs = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
151

            
152
12
  for (i = 0; i < childs; i++)
153
    {
154
10
      child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
155
10
      states = atk_object_ref_state_set (child);
156
10
      if (atk_state_set_contains_state (states, ATK_STATE_SELECTED))
157
10
        g_array_append_val (array, child);
158
    }
159
2
  g_object_unref (states);
160

            
161
2
  o = g_array_index (array, AtkObject *, no);
162
2
  states = atk_object_ref_state_set (o);
163
2
  atk_state_set_remove_state (states, ATK_STATE_SELECTED);
164

            
165
2
  ret = !atk_state_set_contains_state (states, ATK_STATE_SELECTED);
166
2
  g_object_unref (states);
167
2
  g_object_unref (o);
168
2
  g_object_unref (self);
169
2
  g_array_free (array, TRUE);
170

            
171
2
  return ret;
172
}
173

            
174
static gboolean
175
1
my_atk_selection_select_all_selection (AtkSelection *selection)
176
{
177
1
  MyAtkSelection *self = MY_ATK_SELECTION (selection);
178
1
  AtkObject *child = NULL;
179
1
  AtkStateSet *states = NULL;
180
  int i;
181
  int childs;
182

            
183
1
  if (!self)
184
    return FALSE;
185
1
  childs = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
186

            
187
6
  for (i = 0; i < childs; i++)
188
    {
189
5
      child = atk_object_ref_accessible_child (ATK_OBJECT (selection), i);
190
5
      states = atk_object_ref_state_set (child);
191
5
      atk_state_set_add_state (states, ATK_STATE_SELECTED);
192
5
      g_object_unref (states);
193
5
      g_object_unref (child);
194
    }
195

            
196
1
  g_object_unref (self);
197
1
  return TRUE;
198
}
199

            
200
static void
201
9
atk_selection_interface_init (AtkSelectionIface *iface)
202
{
203
9
  if (!iface)
204
    return;
205

            
206
9
  iface->add_selection = my_atk_selection_add_selection;
207
9
  iface->clear_selection = my_atk_selection_clear_selection;
208
9
  iface->ref_selection = my_atk_selection_ref_selection;
209
9
  iface->get_selection_count = my_atk_selection_get_selection_count;
210
9
  iface->is_child_selected = my_atk_selection_is_child_selected;
211
9
  iface->remove_selection = my_atk_selection_remove_selection;
212
9
  iface->select_all_selection = my_atk_selection_select_all_selection;
213
}
214

            
215
static void
216
my_atk_selection_initialize (AtkObject *obj, gpointer data)
217
{
218
}
219

            
220
static void
221
my_atk_selection_finalize (GObject *obj)
222
{
223
}
224

            
225
static void
226
9
my_atk_selection_class_init (MyAtkSelectionClass *my_class)
227
{
228
9
  AtkObjectClass *atk_class = ATK_OBJECT_CLASS (my_class);
229
9
  GObjectClass *gobject_class = G_OBJECT_CLASS (my_class);
230

            
231
9
  gobject_class->finalize = my_atk_selection_finalize;
232

            
233
9
  atk_class->initialize = my_atk_selection_initialize;
234
9
}