2 * sheet-vector.c: Implements sheet vectors.
5 * Miguel de Icaza (miguel@gnu.org)
7 * (C) 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
10 #include <bonobo/bonobo-object.h>
11 #include "idl/Gnumeric.h"
13 #include "sheet-vector.h"
15 #include "sheet-private.h"
21 /* The entry point vectors for the server we provide */
22 static POA_GNOME_Gnumeric_Vector__epv vector_epv
;
23 static POA_GNOME_Gnumeric_Vector__vepv vector_vepv
;
25 #define vector_from_servant(x) SHEET_VECTOR (bonobo_object_from_servant (x))
27 static BonoboObjectClass
*vector_parent_class
;
30 impl_vector_only_numbers (PortableServer_Servant servant
,
31 CORBA_Environment
*ev
)
33 printf ("FIXME: We are always reporting only numbers = TRUE\n");
38 find_block (SheetVector
*vec
, int index
, int *ret_top
, int *ret_idx
)
42 for (i
= total
= 0; i
< vec
->n_blocks
; i
++){
43 int old_total
= total
;
45 total
+= vec
->blocks
[i
].size
;
49 *ret_idx
= old_total
- index
;
54 g_warning ("Should not happen");
59 static GNOME_Gnumeric_DoubleVec
*
60 impl_vector_get_numbers (PortableServer_Servant servant
,
61 CORBA_short low
, CORBA_short high
,
62 CORBA_Environment
*ev
)
64 SheetVector
*vec
= vector_from_servant (servant
);
65 GNOME_Gnumeric_DoubleVec
*res
;
67 int block_top
, block_idx
;
68 int i
, j
, cols
, rows
, idx
;
73 printf ("Values requested are: %d %d\n", low
, high
);
75 if ((low
< 0) || (high
> vec
->len
)){
76 CORBA_exception_set (ev
, CORBA_USER_EXCEPTION
, ex_GNOME_Gnumeric_Sheet_OutOfRange
, NULL
);
80 res
= GNOME_Gnumeric_DoubleVec__alloc ();
84 res
->_length
= (high
- low
);
85 res
->_maximum
= res
->_length
;
86 res
->_buffer
= CORBA_sequence_CORBA_double_allocbuf (res
->_length
);
91 block_idx
= find_block (vec
, low
, &block_top
, &idx
);
92 block
= &vec
->blocks
[block_idx
++];
94 cols
= block
->range
.end
.col
- block
->range
.start
.col
+ 1;
95 rows
= block
->range
.end
.row
- block
->range
.start
.row
+ 1;
97 for (i
= low
; i
< high
; i
++, idx
++){
102 block
= &vec
->blocks
[block_idx
++];
103 block_top
+= block
->size
;
105 cols
= block
->range
.end
.col
- block
->range
.start
.col
;
106 rows
= block
->range
.end
.row
- block
->range
.start
.row
;
109 col
= idx
/ rows
+ block
->range
.start
.col
;
110 row
= idx
% rows
+ block
->range
.start
.row
;
112 cell
= sheet_cell_get (vec
->sheet
, col
, row
);
114 res
->_buffer
[j
++] = value_get_as_float (cell
->value
);
116 res
->_buffer
[j
++] = 0.0;
119 for (j
= 0, i
= low
; i
< high
; i
++, j
++){
120 printf ("Valud %d: %g\n", i
, res
->_buffer
[j
]);
126 static GNOME_Gnumeric_VecValueVec
*
127 impl_vector_get_vec_values (PortableServer_Servant servant
,
128 CORBA_short low
, CORBA_short high
,
129 CORBA_Environment
*ev
)
131 SheetVector
*vec
= vector_from_servant (servant
);
132 GNOME_Gnumeric_VecValueVec
*res
;
134 int block_top
, block_idx
;
135 int i
, j
, cols
, rows
, idx
;
140 if ((low
< 0) || (high
> vec
->len
)){
141 CORBA_exception_set (ev
, CORBA_USER_EXCEPTION
, ex_GNOME_Gnumeric_Sheet_OutOfRange
, NULL
);
145 res
= GNOME_Gnumeric_VecValueVec__alloc ();
149 res
->_length
= (high
- low
);
150 res
->_maximum
= res
->_length
;
151 res
->_buffer
= CORBA_sequence_GNOME_Gnumeric_VecValue_allocbuf (res
->_length
);
156 block_idx
= find_block (vec
, low
, &block_top
, &idx
);
157 block
= &vec
->blocks
[block_idx
];
160 cols
= block
->range
.end
.col
- block
->range
.start
.col
+ 1;
161 rows
= block
->range
.end
.row
- block
->range
.start
.row
+ 1;
163 for (i
= low
; i
< high
; i
++, idx
++){
164 GNOME_Gnumeric_VecValue vecvalue
;
169 block
= &vec
->blocks
[block_idx
++];
170 block_top
+= block
->size
;
172 cols
= block
->range
.end
.col
- block
->range
.start
.col
;
173 rows
= block
->range
.end
.row
- block
->range
.start
.row
;
176 col
= idx
/ rows
+ block
->range
.start
.col
;
177 row
= idx
% rows
+ block
->range
.start
.row
;
179 cell
= sheet_cell_get (vec
->sheet
, col
, row
);
182 Value
*value
= cell
->value
;
184 switch (value
->type
){
187 case VALUE_CELLRANGE
:
189 vecvalue
._d
= GNOME_Gnumeric_VALUE_FLOAT
;
190 vecvalue
._u
.v_float
= 0.0;
194 vecvalue
._d
= GNOME_Gnumeric_VALUE_FLOAT
;
195 vecvalue
._u
.v_float
= value
->v
.v_int
;
199 vecvalue
._d
= GNOME_Gnumeric_VALUE_FLOAT
;
200 vecvalue
._u
.v_float
= value
->v
.v_float
;
204 vecvalue
._d
= GNOME_Gnumeric_VALUE_FLOAT
;
205 vecvalue
._u
.v_float
= value
->v
.v_bool
;
209 vecvalue
._d
= GNOME_Gnumeric_VALUE_STRING
;
210 vecvalue
._u
.str
= CORBA_string_dup (value
->v
.str
->str
);
215 vecvalue
._d
= GNOME_Gnumeric_VALUE_FLOAT
;
216 vecvalue
._u
.v_float
= 0.0;
219 res
->_buffer
[j
] = vecvalue
;
228 impl_vector_count (PortableServer_Servant servant
, CORBA_Environment
*ev
)
230 SheetVector
*vec
= vector_from_servant (servant
);
236 impl_vector_set (PortableServer_Servant servant
, CORBA_short pos
,
237 CORBA_double val
, CORBA_Environment
*ev
)
239 /* SheetVector *vec = vector_from_servant (servant);*/
241 g_error ("Not implemented");
245 impl_vector_set_notify (PortableServer_Servant servant
,
246 GNOME_Gnumeric_VectorNotify vector_notify
,
247 CORBA_Environment
*ev
)
249 SheetVector
*vec
= vector_from_servant (servant
);
251 vec
->notify
= CORBA_Object_duplicate (vector_notify
, ev
);
256 sheet_vector_destroy (GtkObject
*object
)
258 SheetVector
*vec
= SHEET_VECTOR (object
);
259 CORBA_Environment ev
;
261 if (vec
->sheet
!= NULL
)
262 g_error ("SheetVector has not been detached prior to destruction");
264 CORBA_exception_init (&ev
);
265 CORBA_Object_release (vec
->notify
, &ev
);
266 CORBA_exception_free (&ev
);
269 g_free (vec
->blocks
);
271 GTK_OBJECT_CLASS (vector_parent_class
)->destroy (object
);
275 init_vector_corba_class (void)
277 vector_epv
.only_numbers
= impl_vector_only_numbers
;
278 vector_epv
.get_numbers
= impl_vector_get_numbers
;
279 vector_epv
.get_vec_values
= impl_vector_get_vec_values
;
280 vector_epv
.set
= impl_vector_set
;
281 vector_epv
.count
= impl_vector_count
;
282 vector_epv
.set_notify
= impl_vector_set_notify
;
284 vector_vepv
.Bonobo_Unknown_epv
= bonobo_object_get_epv ();
285 vector_vepv
.GNOME_Gnumeric_Vector_epv
= &vector_epv
;
289 sheet_vector_class_init (GtkObjectClass
*object_class
)
291 vector_parent_class
= gtk_type_class (bonobo_object_get_type ());
293 object_class
->destroy
= sheet_vector_destroy
;
295 init_vector_corba_class ();
299 sheet_vector_init (GtkObject
*object
)
301 SheetVector
*vector
= SHEET_VECTOR (object
);
303 vector
->notify
= CORBA_OBJECT_NIL
;
307 sheet_vector_get_type (void)
309 static GtkType type
= 0;
314 sizeof (SheetVector
),
315 sizeof (SheetVectorClass
),
316 (GtkClassInitFunc
) sheet_vector_class_init
,
317 (GtkObjectInitFunc
) sheet_vector_init
,
318 NULL
, /* reserved 1 */
319 NULL
, /* reserved 2 */
320 (GtkClassInitFunc
) NULL
323 type
= gtk_type_unique (bonobo_object_get_type (), &info
);
329 static GNOME_Gnumeric_Vector
330 sheet_vector_corba_object_create (BonoboObject
*object
)
332 POA_GNOME_Gnumeric_Vector
*servant
;
333 CORBA_Environment ev
;
335 servant
= (POA_GNOME_Gnumeric_Vector
*) g_new0 (BonoboObjectServant
, 1);
336 servant
->vepv
= &vector_vepv
;
338 CORBA_exception_init (&ev
);
339 POA_GNOME_Gnumeric_Vector__init ((PortableServer_Servant
) servant
, &ev
);
340 if (ev
._major
!= CORBA_NO_EXCEPTION
){
342 CORBA_exception_free (&ev
);
343 return CORBA_OBJECT_NIL
;
346 CORBA_exception_free (&ev
);
347 return (Bonobo_View
) bonobo_object_activate_servant (object
, servant
);
351 sheet_vector_new (Sheet
*sheet
)
353 SheetVector
*sheet_vector
;
354 GNOME_Gnumeric_Vector corba_vector
;
356 sheet_vector
= gtk_type_new (sheet_vector_get_type ());
358 sheet_vector
->sheet
= sheet
;
360 corba_vector
= sheet_vector_corba_object_create (BONOBO_OBJECT (sheet_vector
));
361 if (corba_vector
== NULL
) {
362 gtk_object_destroy (GTK_OBJECT (sheet_vector
));
366 bonobo_object_construct (BONOBO_OBJECT (sheet_vector
), corba_vector
);
372 sheet_vector_reset (SheetVector
*sheet_vector
)
374 g_return_if_fail (sheet_vector
!= NULL
);
375 g_return_if_fail (IS_SHEET_VECTOR (sheet_vector
));
377 g_free (sheet_vector
->blocks
);
378 sheet_vector
->blocks
= NULL
;
379 sheet_vector
->n_blocks
= 0;
380 sheet_vector
->len
= 0;
384 sheet_vector_append_range (SheetVector
*sheet_vector
, Range
*range
)
386 g_return_if_fail (sheet_vector
!= NULL
);
387 g_return_if_fail (IS_SHEET_VECTOR (sheet_vector
));
389 if (sheet_vector
->blocks
== NULL
){
390 sheet_vector
->blocks
= g_new0 (RangeBlock
, 1);
391 sheet_vector
->n_blocks
= 1;
392 sheet_vector
->blocks
[0].size
= (range
->end
.col
- range
->start
.col
+ 1) *
393 (range
->end
.row
- range
->start
.row
+ 1);
394 sheet_vector
->blocks
[0].range
= *range
;
395 sheet_vector
->len
= sheet_vector
->blocks
[0].size
;
397 g_error ("Not yet implemented");
402 sheet_vector_attach (SheetVector
*sheet_vector
, Sheet
*sheet
)
404 g_return_if_fail (sheet_vector
!= NULL
);
405 g_return_if_fail (IS_SHEET_VECTOR (sheet_vector
));
406 g_return_if_fail (sheet
!= NULL
);
407 g_return_if_fail (IS_SHEET (sheet
));
409 sheet_vector
->sheet
= sheet
;
411 sheet
->private->sheet_vectors
= g_slist_prepend (sheet
->private->sheet_vectors
, sheet_vector
);
415 sheet_vector_detach (SheetVector
*sheet_vector
)
419 g_return_if_fail (sheet_vector
!= NULL
);
420 g_return_if_fail (IS_SHEET_VECTOR (sheet_vector
));
422 sheet
= sheet_vector
->sheet
;
423 sheet_vector
->sheet
= NULL
;
425 g_return_if_fail (sheet
!= NULL
);
426 g_return_if_fail (IS_SHEET (sheet
));
428 sheet
->private->sheet_vectors
= g_slist_remove (sheet
->private->sheet_vectors
, sheet_vector
);
432 sheet_vectors_cell_changed (Cell
*cell
)
435 const int col
= cell
->col
->pos
;
436 const int row
= cell
->col
->pos
;
439 for (l
= cell
->sheet
->private->sheet_vectors
; l
; l
= l
->next
){
440 SheetVector
*vec
= l
->data
;
442 if (vec
->notify
== CORBA_OBJECT_NIL
)
445 for (i
= 0; i
< vec
->n_blocks
; i
++)
446 if (range_contains (&vec
->blocks
[i
].range
, col
, row
)){
447 CORBA_Environment ev
;
450 * FIXME: This is lame. Find out the real index
453 CORBA_exception_init (&ev
);
454 GNOME_Gnumeric_VectorNotify_changed (vec
->notify
, 0, vec
->len
, &ev
);
455 CORBA_exception_free (&ev
);
461 sheet_vectors_shutdown (Sheet
*sheet
)
463 g_return_if_fail (sheet
!= NULL
);
464 g_return_if_fail (IS_SHEET (sheet
));
466 for (;sheet
->private->sheet_vectors
;){
467 SheetVector
*sheet_vector
= sheet
->private->sheet_vectors
->data
;
469 sheet_vector_detach (sheet_vector
);
470 gtk_object_unref (GTK_OBJECT (sheet
->private->sheet_vectors
->data
));
473 g_slist_free (sheet
->private->sheet_vectors
);
474 sheet
->private->sheet_vectors
= NULL
;