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
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
my_atk_selection_init (MyAtkSelection *obj)
40
{
41
}
42

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
171
  return ret;
172
}
173

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

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

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

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

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

            
206
  iface->add_selection = my_atk_selection_add_selection;
207
  iface->clear_selection = my_atk_selection_clear_selection;
208
  iface->ref_selection = my_atk_selection_ref_selection;
209
  iface->get_selection_count = my_atk_selection_get_selection_count;
210
  iface->is_child_selected = my_atk_selection_is_child_selected;
211
  iface->remove_selection = my_atk_selection_remove_selection;
212
  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
my_atk_selection_class_init (MyAtkSelectionClass *my_class)
227
{
228
  AtkObjectClass *atk_class = ATK_OBJECT_CLASS (my_class);
229
  GObjectClass *gobject_class = G_OBJECT_CLASS (my_class);
230

            
231
  gobject_class->finalize = my_atk_selection_finalize;
232

            
233
  atk_class->initialize = my_atk_selection_initialize;
234
}