2007-09-08 Li Yuan <li.yuan@sun.com>
[platform/core/uifw/at-spi2-atk.git] / libspi / table.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001, 2002 Sun Microsystems Inc.,
6  * Copyright 2001, 2002 Ximian, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /* table.c : implements the Table interface */
25
26 #include <config.h>
27 #include <stdio.h>
28 #include <bonobo/bonobo-exception.h>
29 #include <atk/atktable.h>
30 #include <libspi/accessible.h>
31 #include <libspi/table.h>
32
33
34 SpiTable *
35 spi_table_interface_new (AtkObject *obj)
36 {
37   SpiTable *new_table = g_object_new (SPI_TABLE_TYPE, NULL);
38
39   spi_base_construct (SPI_BASE (new_table), G_OBJECT(obj));
40
41   return new_table;
42 }
43
44
45 static AtkTable *
46 get_table_from_servant (PortableServer_Servant servant)
47 {
48   SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
49
50   g_return_val_if_fail (object, NULL);
51   g_return_val_if_fail (ATK_IS_OBJECT(object->gobj), NULL);
52   return ATK_TABLE (object->gobj);
53 }
54
55
56 static Accessibility_Accessible
57 impl__get_caption (PortableServer_Servant servant,
58                    CORBA_Environment     *ev)
59 {
60   AtkObject *atk_object;
61   AtkTable  *table = get_table_from_servant (servant);
62
63   g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
64
65   atk_object = atk_table_get_caption (table);
66
67   return spi_accessible_new_return (atk_object, FALSE, ev);
68 }
69
70
71 static Accessibility_Accessible
72 impl__get_summary (PortableServer_Servant servant,
73                    CORBA_Environment     *ev)
74 {
75   AtkObject *atk_object;
76   AtkTable  *table = get_table_from_servant (servant);
77
78   g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
79
80   atk_object = atk_table_get_summary (table);
81
82   return spi_accessible_new_return (atk_object, FALSE, ev);
83 }
84
85
86 static CORBA_long
87 impl__get_nRows (PortableServer_Servant servant,
88                  CORBA_Environment     *ev)
89 {
90   AtkTable *table = get_table_from_servant (servant);
91
92   g_return_val_if_fail (table != NULL, 0);
93
94   return atk_table_get_n_rows (table);
95 }
96
97
98 static CORBA_long
99 impl__get_nColumns (PortableServer_Servant servant,
100                     CORBA_Environment     *ev)
101 {
102   AtkTable *table = get_table_from_servant (servant);
103
104   g_return_val_if_fail (table != NULL, 0);
105
106   return atk_table_get_n_columns (table);
107 }
108
109
110 static Accessibility_Accessible
111 impl_getAccessibleAt (PortableServer_Servant servant,
112                       const CORBA_long       row,
113                       const CORBA_long       column,
114                       CORBA_Environment     *ev)
115 {
116   AtkObject *atk_object;
117   AtkTable  *table = get_table_from_servant (servant);
118
119   g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
120
121   atk_object = atk_table_ref_at (table, row, column);
122
123   return spi_accessible_new_return (atk_object, TRUE, ev);
124 }
125
126
127 static CORBA_long
128 impl_getIndexAt (PortableServer_Servant servant,
129                  const CORBA_long       row,
130                  const CORBA_long       column,
131                  CORBA_Environment     *ev)
132 {
133   AtkTable *table = get_table_from_servant (servant);
134
135   g_return_val_if_fail (table != NULL, 0);
136
137   return atk_table_get_index_at (table, row, column);
138 }
139
140
141 static CORBA_long
142 impl_getRowAtIndex (PortableServer_Servant servant,
143                     const CORBA_long       index,
144                     CORBA_Environment     *ev)
145 {
146   AtkTable *table = get_table_from_servant (servant);
147
148   g_return_val_if_fail (table != NULL, 0);
149
150   return atk_table_get_row_at_index (table, index);
151 }
152
153
154 static CORBA_long
155 impl_getColumnAtIndex (PortableServer_Servant servant,
156                        const CORBA_long       index,
157                        CORBA_Environment     *ev)
158 {
159   AtkTable *table = get_table_from_servant (servant);
160
161   g_return_val_if_fail (table != NULL, 0);
162
163   return atk_table_get_column_at_index (table, index);
164 }
165
166
167 static CORBA_string
168 impl_getRowDescription (PortableServer_Servant servant,
169                         const CORBA_long       row,
170                         CORBA_Environment     *ev)
171 {
172   const char *rv;
173   AtkTable   *table = get_table_from_servant (servant);
174
175   g_return_val_if_fail (table != NULL, NULL);
176   
177   rv = atk_table_get_row_description (table, row);
178
179   if (rv)
180     {
181       return CORBA_string_dup (rv);
182     }
183   else
184     {
185       return CORBA_string_dup ("");
186     }
187 }
188
189
190 static CORBA_string
191 impl_getColumnDescription (PortableServer_Servant servant,
192                            const CORBA_long       column,
193                            CORBA_Environment     *ev)
194 {
195   const char *rv;
196   AtkTable   *table = get_table_from_servant (servant);
197
198   g_return_val_if_fail (table != NULL, CORBA_string_dup (""));
199   
200   rv = atk_table_get_column_description (table, column);
201
202   if (rv)
203     {
204       return CORBA_string_dup (rv);
205     }
206   else
207     {
208       return CORBA_string_dup ("");
209     }
210 }
211
212
213 static CORBA_long
214 impl_getRowExtentAt (PortableServer_Servant servant,
215                      const CORBA_long       row,
216                      const CORBA_long       column,
217                      CORBA_Environment     *ev)
218 {
219   AtkTable *table = get_table_from_servant (servant);
220
221   g_return_val_if_fail (table != NULL, -1);
222
223   return atk_table_get_row_extent_at (table, row, column);
224 }
225
226
227 static CORBA_long
228 impl_getColumnExtentAt (PortableServer_Servant servant,
229                         const CORBA_long       row,
230                         const CORBA_long       column,
231                         CORBA_Environment     *ev)
232 {
233   AtkTable *table = get_table_from_servant (servant);
234
235   g_return_val_if_fail (table != NULL, -1);
236
237   return atk_table_get_column_extent_at (table, row, column);
238 }
239
240
241 static Accessibility_Table
242 impl_getRowHeader (PortableServer_Servant servant,
243                    const CORBA_long       row,
244                    CORBA_Environment     *ev)
245 {
246   AtkObject *header;
247   AtkTable  *table = get_table_from_servant (servant);
248
249   g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
250
251   header = atk_table_get_row_header (table, row);
252
253   return spi_accessible_new_return (header, FALSE, ev);
254 }
255
256
257 static Accessibility_Table
258 impl_getColumnHeader (PortableServer_Servant servant,
259                       const CORBA_long       column,
260                       CORBA_Environment     *ev)
261 {
262   AtkObject *header;
263   AtkTable  *table = get_table_from_servant (servant);
264
265   g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
266
267   header = atk_table_get_column_header (table, column);
268
269   return spi_accessible_new_return (header, FALSE, ev);
270 }
271
272 static CORBA_long
273 impl__get_nSelectedRows (PortableServer_Servant servant,
274                          CORBA_Environment     *ev)
275 {
276   gint *selectedRows = NULL;
277   gint retval = 0;
278   AtkTable *table = get_table_from_servant (servant);
279
280   bonobo_return_val_if_fail (table != NULL, 0, ev);
281
282   retval = atk_table_get_selected_rows (table, &selectedRows);
283   if (selectedRows) g_free (selectedRows);
284   return retval;
285 }
286
287
288 static CORBA_long
289 impl__get_nSelectedColumns (PortableServer_Servant servant,
290                             CORBA_Environment     *ev)
291 {
292   gint *selectedColumns = NULL;
293   gint retval = 0;
294   AtkTable *table = get_table_from_servant (servant);
295
296   bonobo_return_val_if_fail (table != NULL, 0, ev);
297
298   retval = atk_table_get_selected_columns (table, &selectedColumns);
299   if (selectedColumns) g_free (selectedColumns);
300   return retval;
301 }
302
303 static Accessibility_LongSeq *
304 impl_getSelectedRows (PortableServer_Servant servant,
305                       CORBA_Environment     *ev)
306 {
307   gint *selectedRows = NULL;
308   gint length;
309   Accessibility_LongSeq *retval;
310   AtkTable *table = get_table_from_servant (servant);
311
312   bonobo_return_val_if_fail (table != NULL, NULL, ev);
313
314   length = atk_table_get_selected_rows (table, &selectedRows);
315
316   bonobo_return_val_if_fail (length >= 0, NULL, ev);
317
318   retval = Accessibility_LongSeq__alloc ();
319   retval->_maximum = retval->_length = length;
320   retval->_buffer = Accessibility_LongSeq_allocbuf (length);
321
322   while (--length >= 0)
323     {
324       retval->_buffer[length] = selectedRows[length];
325     }
326
327   if (selectedRows) g_free (selectedRows);
328
329   return retval;
330 }
331
332
333 static Accessibility_LongSeq *
334 impl_getSelectedColumns (PortableServer_Servant servant,
335                          CORBA_Environment     *ev)
336 {
337   gint *selectedColumns = NULL;
338   gint length;
339   Accessibility_LongSeq *retval;
340   AtkTable *table = get_table_from_servant (servant);
341
342   bonobo_return_val_if_fail (table != NULL, NULL, ev);
343
344   length = atk_table_get_selected_columns (table, &selectedColumns);
345
346   bonobo_return_val_if_fail (length >= 0, NULL, ev);
347
348   retval = Accessibility_LongSeq__alloc ();
349   retval->_maximum = retval->_length = length;
350   retval->_buffer = Accessibility_LongSeq_allocbuf (length);
351
352   while (--length >= 0)
353     {
354       retval->_buffer[length] = (CORBA_long) selectedColumns[length];
355     }
356
357   if (selectedColumns) g_free (selectedColumns);
358
359   return retval;
360 }
361
362
363 static CORBA_boolean
364 impl_isRowSelected (PortableServer_Servant servant,
365                     const CORBA_long       row,
366                     CORBA_Environment     *ev)
367 {
368   AtkTable *table = get_table_from_servant (servant);
369
370   g_return_val_if_fail (table != NULL, FALSE);
371
372   return atk_table_is_row_selected (table, row);
373 }
374
375
376 static CORBA_boolean
377 impl_isColumnSelected (PortableServer_Servant servant,
378                        const CORBA_long       column,
379                        CORBA_Environment     *ev)
380 {
381   AtkTable *table = get_table_from_servant (servant);
382
383   g_return_val_if_fail (table != NULL, FALSE);
384
385   return atk_table_is_column_selected (table, column);
386 }
387
388 static CORBA_boolean
389 impl_addRowSelection (PortableServer_Servant servant,
390                       const CORBA_long       row,
391                       CORBA_Environment     *ev)
392 {
393   AtkTable *table = get_table_from_servant (servant);
394
395   g_return_val_if_fail (table != NULL, FALSE);
396
397   return atk_table_add_row_selection (table, row);
398 }
399
400
401 static CORBA_boolean
402 impl_addColumnSelection (PortableServer_Servant servant,
403                          const CORBA_long       column,
404                          CORBA_Environment     *ev)
405 {
406   AtkTable *table = get_table_from_servant (servant);
407
408   g_return_val_if_fail (table != NULL, FALSE);
409
410   return atk_table_add_column_selection (table, column);
411 }
412
413
414 static CORBA_boolean
415 impl_removeRowSelection (PortableServer_Servant servant,
416                          const CORBA_long       row,
417                          CORBA_Environment     *ev)
418 {
419   AtkTable *table = get_table_from_servant (servant);
420
421   g_return_val_if_fail (table != NULL, FALSE);
422
423   return atk_table_remove_row_selection (table, row);
424 }
425
426
427 static CORBA_boolean
428 impl_removeColumnSelection (PortableServer_Servant servant,
429                             const CORBA_long       column,
430                             CORBA_Environment     *ev)
431 {
432   AtkTable *table = get_table_from_servant (servant);
433
434   g_return_val_if_fail (table != NULL, FALSE);
435
436   return atk_table_remove_column_selection (table, column);
437 }
438
439
440 static CORBA_boolean
441 impl_getRowColumnExtentsAtIndex (PortableServer_Servant servant,
442                                  const CORBA_long index,
443                                  CORBA_long *row,
444                                  CORBA_long *column,
445                                  CORBA_long *row_extents,
446                                  CORBA_long *col_extents,
447                                  CORBA_boolean *is_selected,
448                                  CORBA_Environment *ev)
449 {
450
451   AtkObject *cell;
452   AtkRole role;
453   AtkTable *table = get_table_from_servant (servant);
454   gint intColumn, intRow, intRow_extents, intCol_extents;
455   gboolean boolIs_selected;
456
457   g_return_val_if_fail (table != NULL, FALSE);
458
459   intColumn = atk_table_get_column_at_index (table, index);
460   intRow = atk_table_get_row_at_index (table, index);
461   intRow_extents = atk_table_get_row_extent_at (table, intRow, intColumn);
462   intCol_extents = atk_table_get_column_extent_at (table, intRow, intColumn);
463   boolIs_selected = atk_table_is_selected (table, intRow, intColumn);
464
465   *column = intColumn;
466   *row = intRow;
467   *row_extents = intRow_extents;
468   *col_extents = intCol_extents;
469   *is_selected = boolIs_selected;
470
471   cell = atk_table_ref_at (table, intRow, intColumn);
472   role = atk_object_get_role (cell);
473
474   if (role == ATK_ROLE_TABLE_CELL)
475     return TRUE;
476   
477   return FALSE;
478
479 }
480
481 static CORBA_boolean
482 impl_isSelected (PortableServer_Servant servant,
483                  const CORBA_long       row,
484                  const CORBA_long       column,
485                  CORBA_Environment     *ev)
486 {
487   AtkTable *table = get_table_from_servant (servant);
488
489   g_return_val_if_fail (table != NULL, FALSE);
490
491   return atk_table_is_selected (table,
492                                 row, column);
493 }
494
495
496 static void
497 spi_table_class_init (SpiTableClass *klass)
498 {
499   POA_Accessibility_Table__epv *epv = &klass->epv;
500
501   /* Initialize epv table */
502
503   epv->_get_caption = impl__get_caption;
504   epv->_get_summary = impl__get_summary;
505   epv->_get_nRows = impl__get_nRows;
506   epv->_get_nColumns = impl__get_nColumns;
507   epv->_get_nSelectedRows = impl__get_nSelectedRows;
508   epv->_get_nSelectedColumns = impl__get_nSelectedColumns;
509   epv->getAccessibleAt = impl_getAccessibleAt;
510   epv->getIndexAt = impl_getIndexAt;
511   epv->getRowAtIndex = impl_getRowAtIndex;
512   epv->getColumnAtIndex = impl_getColumnAtIndex;
513   epv->getRowDescription = impl_getRowDescription;
514   epv->getColumnDescription = impl_getColumnDescription;
515   epv->getRowExtentAt = impl_getRowExtentAt;
516   epv->getColumnExtentAt = impl_getColumnExtentAt;
517   epv->getRowHeader = impl_getRowHeader;
518   epv->getColumnHeader = impl_getColumnHeader;
519   epv->getSelectedRows = impl_getSelectedRows;
520   epv->getSelectedColumns = impl_getSelectedColumns;
521   epv->isRowSelected = impl_isRowSelected;
522   epv->isColumnSelected = impl_isColumnSelected;
523   epv->addRowSelection = impl_addRowSelection;
524   epv->addColumnSelection = impl_addColumnSelection;
525   epv->removeRowSelection = impl_removeRowSelection;
526   epv->removeColumnSelection = impl_removeColumnSelection;
527   epv->isSelected = impl_isSelected;
528   epv->getRowColumnExtentsAtIndex = impl_getRowColumnExtentsAtIndex;
529 }
530
531 static void
532 spi_table_init (SpiTable *table)
533 {
534 }
535
536 BONOBO_TYPE_FUNC_FULL (SpiTable,
537                        Accessibility_Table,
538                        SPI_TYPE_BASE,
539                        spi_table)