Revert, revert, try another thing
[gnumeric.git] / src / sheet-vector.c
blob5d34be494720ac9254e6e73790cf79b288a6819f
1 /*
2 * sheet-vector.c: Implements sheet vectors.
4 * Author:
5 * Miguel de Icaza (miguel@gnu.org)
7 * (C) 1999, 2000 Helix Code, Inc. (http://www.helixcode.com)
8 */
9 #include <config.h>
10 #include <bonobo/bonobo-object.h>
11 #include "idl/Gnumeric.h"
12 #include "gnumeric.h"
13 #include "sheet-vector.h"
14 #include "sheet.h"
15 #include "sheet-private.h"
16 #include "value.h"
17 #include "cell.h"
18 #include "ranges.h"
19 #include <stdio.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;
29 static CORBA_boolean
30 impl_vector_only_numbers (PortableServer_Servant servant,
31 CORBA_Environment *ev)
33 printf ("FIXME: We are always reporting only numbers = TRUE\n");
34 return CORBA_TRUE;
37 static int
38 find_block (SheetVector *vec, int index, int *ret_top, int *ret_idx)
40 int total, i;
42 for (i = total = 0; i < vec->n_blocks; i++){
43 int old_total = total;
45 total += vec->blocks [i].size;
47 if (index <= total){
48 *ret_top = total;
49 *ret_idx = old_total - index;
50 return i;
54 g_warning ("Should not happen");
56 return 0;
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;
66 RangeBlock *block;
67 int block_top, block_idx;
68 int i, j, cols, rows, idx;
70 if (high == -1)
71 high = vec->len;
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);
77 return NULL;
80 res = GNOME_Gnumeric_DoubleVec__alloc ();
81 if (res == NULL)
82 return NULL;
84 res->_length = (high - low);
85 res->_maximum = res->_length;
86 res->_buffer = CORBA_sequence_CORBA_double_allocbuf (res->_length);
89 * Fill in the values
91 block_idx = find_block (vec, low, &block_top, &idx);
92 block = &vec->blocks [block_idx++];
93 j = 0;
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++){
98 Cell *cell;
99 int col, row;
101 if (i == block_top){
102 block = &vec->blocks [block_idx++];
103 block_top += block->size;
104 idx = 0;
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);
113 if (cell)
114 res->_buffer [j++] = value_get_as_float (cell->value);
115 else
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]);
123 return res;
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;
133 RangeBlock *block;
134 int block_top, block_idx;
135 int i, j, cols, rows, idx;
137 if (high == -1)
138 high = vec->len;
140 if ((low < 0) || (high > vec->len)){
141 CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Gnumeric_Sheet_OutOfRange, NULL);
142 return NULL;
145 res = GNOME_Gnumeric_VecValueVec__alloc ();
146 if (res == NULL)
147 return NULL;
149 res->_length = (high - low);
150 res->_maximum = res->_length;
151 res->_buffer = CORBA_sequence_GNOME_Gnumeric_VecValue_allocbuf (res->_length);
154 * Fill in the values
156 block_idx = find_block (vec, low, &block_top, &idx);
157 block = &vec->blocks [block_idx];
158 block_idx++;
159 j = 0;
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;
165 Cell *cell;
166 int col, row;
168 if (i == block_top){
169 block = &vec->blocks [block_idx++];
170 block_top += block->size;
171 idx = 0;
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);
181 if (cell){
182 Value *value = cell->value;
184 switch (value->type){
185 case VALUE_EMPTY:
186 case VALUE_ERROR:
187 case VALUE_CELLRANGE:
188 case VALUE_ARRAY:
189 vecvalue._d= GNOME_Gnumeric_VALUE_FLOAT;
190 vecvalue._u.v_float = 0.0;
191 break;
193 case VALUE_INTEGER:
194 vecvalue._d= GNOME_Gnumeric_VALUE_FLOAT;
195 vecvalue._u.v_float = value->v.v_int;
196 break;
198 case VALUE_FLOAT:
199 vecvalue._d= GNOME_Gnumeric_VALUE_FLOAT;
200 vecvalue._u.v_float = value->v.v_float;
201 break;
203 case VALUE_BOOLEAN:
204 vecvalue._d= GNOME_Gnumeric_VALUE_FLOAT;
205 vecvalue._u.v_float = value->v.v_bool;
206 break;
208 case VALUE_STRING:
209 vecvalue._d= GNOME_Gnumeric_VALUE_STRING;
210 vecvalue._u.str = CORBA_string_dup (value->v.str->str);
211 break;
214 } else {
215 vecvalue._d = GNOME_Gnumeric_VALUE_FLOAT;
216 vecvalue._u.v_float = 0.0;
219 res->_buffer [j] = vecvalue;
220 j++;
223 return res;
227 static CORBA_short
228 impl_vector_count (PortableServer_Servant servant, CORBA_Environment *ev)
230 SheetVector *vec = vector_from_servant (servant);
232 return vec->len;
235 static void
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");
244 static void
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);
255 static void
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);
268 if (vec->blocks)
269 g_free (vec->blocks);
271 GTK_OBJECT_CLASS (vector_parent_class)->destroy (object);
274 static void
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;
288 static void
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 ();
298 static void
299 sheet_vector_init (GtkObject *object)
301 SheetVector *vector = SHEET_VECTOR (object);
303 vector->notify = CORBA_OBJECT_NIL;
306 GtkType
307 sheet_vector_get_type (void)
309 static GtkType type = 0;
311 if (!type){
312 GtkTypeInfo info = {
313 "SheetVector",
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);
326 return type;
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){
341 g_free (servant);
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);
350 SheetVector *
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));
363 return NULL;
366 bonobo_object_construct (BONOBO_OBJECT (sheet_vector), corba_vector);
368 return sheet_vector;
371 void
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;
383 void
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;
396 } else {
397 g_error ("Not yet implemented");
401 void
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);
414 void
415 sheet_vector_detach (SheetVector *sheet_vector)
417 Sheet *sheet;
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);
431 void
432 sheet_vectors_cell_changed (Cell *cell)
434 GSList *l;
435 const int col = cell->col->pos;
436 const int row = cell->col->pos;
437 int i;
439 for (l = cell->sheet->private->sheet_vectors; l; l = l->next){
440 SheetVector *vec = l->data;
442 if (vec->notify == CORBA_OBJECT_NIL)
443 continue;
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
451 * then, notify
453 CORBA_exception_init (&ev);
454 GNOME_Gnumeric_VectorNotify_changed (vec->notify, 0, vec->len, &ev);
455 CORBA_exception_free (&ev);
460 void
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;